修改流程
This commit is contained in:
@@ -21,32 +21,33 @@
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<view :change:prop="mapRenderjs.searchPlace" :prop="querySearch" class="bg-#f5f5f5">
|
||||
<view class="bg-#f5f5f5">
|
||||
<view class="px-22rpx py-20rpx">
|
||||
<template v-if="placesLength === 0">
|
||||
<view class="center py-100rpx">
|
||||
<image class="w-250rpx h-250rpx" src="@img/chef/100.png"></image>
|
||||
<view v-if="logicStore.searchLoading" class="center py-100rpx text-28rpx text-#9B9CA0">
|
||||
Loading...
|
||||
</view>
|
||||
|
||||
<template v-else-if="placesLength > 0">
|
||||
<view class="rounded-36rpx bg-white">
|
||||
<view
|
||||
v-for="(item, index) in logicStore.placesList"
|
||||
:key="(item as any).id || index"
|
||||
:class="[index === logicStore.placesList.length - 1 ? '' : 'border-bottom']"
|
||||
class="px-22rpx pb-30rpx pt-34rpx"
|
||||
@click="handleClickLocation(item as AddressPlaceItem)"
|
||||
>
|
||||
<view class="text-#000 text-26rpx font-bold">{{ (item as any).displayName }}</view>
|
||||
<view class="text-#9B9CA0 text-24rpx flex-center-sb">
|
||||
<view>{{ (item as any).formattedAddress }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<view class="rounded-36rpx bg-white">
|
||||
<template v-for="(item,index) in logicStore.placesList" :key="index">
|
||||
<view :class="[index === logicStore.placesList.length - 1 ? '' : 'border-bottom']"
|
||||
class="px-22rpx pb-30rpx pt-34rpx"
|
||||
@click="handleClickLocation(item)">
|
||||
<!-- <view >{{ item }}</view> -->
|
||||
<view class="text-#000 text-26rpx font-bold">{{ item.displayName }}</view>
|
||||
<view class="text-#9B9CA0 text-24rpx flex-center-sb">
|
||||
<view>{{ item.formattedAddress }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
<view v-else-if="hasSearched" class="center py-100rpx">
|
||||
<image class="w-250rpx h-250rpx" src="@img/chef/100.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view id="map" :change:prop="mapRenderjs.initMap" :prop="mapDataComputed" :user-location="userLocation"
|
||||
class="absolute left-0 bottom-0 w-0 h-0"></view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</template>
|
||||
@@ -54,84 +55,245 @@
|
||||
import Config from "@/config";
|
||||
import {useLogicStore} from "@/pages-user/store/logic";
|
||||
import {useUserStore} from "@/store";
|
||||
import { getCurrentInstance } from "vue";
|
||||
import {debounce} from "throttle-debounce";
|
||||
|
||||
const {t, locale} = useI18n();
|
||||
const userStore = useUserStore()
|
||||
const logicStore = useLogicStore()
|
||||
|
||||
export interface AddressPlaceItem {
|
||||
id: string
|
||||
displayName: string
|
||||
formattedAddress: string
|
||||
location: { lat: number; lng: number } | null
|
||||
}
|
||||
|
||||
let openerEventChannel: any = null
|
||||
onLoad(() => {
|
||||
// 统一通过 getOpenerEventChannel 获取导航传入的 eventChannel
|
||||
const pages = getCurrentPages() as any[]
|
||||
const page = pages[pages.length - 1]
|
||||
openerEventChannel = page?.getOpenerEventChannel?.() || null
|
||||
})
|
||||
|
||||
// 生命周期:清空地址列表
|
||||
onMounted(() => {
|
||||
logicStore.clearPlacesList()
|
||||
})
|
||||
|
||||
const placesLength = computed(() => {
|
||||
return logicStore.placesList.length;
|
||||
});
|
||||
|
||||
const userLocation = computed(() => ({
|
||||
longitude: userStore.location.longitude,
|
||||
latitude: userStore.location.latitude
|
||||
}));
|
||||
const placesLength = computed(() => logicStore.placesList.length)
|
||||
const mapSearchKeyword = ref<string>('')
|
||||
const hasSearched = ref(false)
|
||||
|
||||
watch(
|
||||
() => logicStore.searchLoading,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
uni.showLoading({
|
||||
title: 'Loading...',
|
||||
mask: true,
|
||||
});
|
||||
} else {
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
() => logicStore.searchLoading,
|
||||
(loading) => {
|
||||
if (loading) {
|
||||
uni.showLoading({ title: 'Loading...', mask: true })
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
// 地图搜索关键词
|
||||
const mapSearchKeyword = ref<string>('');
|
||||
const querySearch = computed(() => {
|
||||
return {
|
||||
keyword: mapSearchKeyword.value,
|
||||
function resolveLanguageCode() {
|
||||
if (locale.value === 'zh-Hans') return 'zh-CN'
|
||||
if (locale.value === 'en') return 'en'
|
||||
return String(locale.value || 'en')
|
||||
}
|
||||
|
||||
function resolveRegionCode() {
|
||||
return locale.value === 'zh-Hans' ? 'CN' : 'US'
|
||||
}
|
||||
|
||||
function resolveBiasCenter() {
|
||||
const lat = Number(userStore.location.latitude)
|
||||
const lng = Number(userStore.location.longitude)
|
||||
if (Number.isFinite(lat) && Number.isFinite(lng) && (lat !== 0 || lng !== 0)) {
|
||||
return { latitude: lat, longitude: lng }
|
||||
}
|
||||
if (locale.value === 'zh-Hans') {
|
||||
return { latitude: 39.9042, longitude: 116.4074 }
|
||||
}
|
||||
return { latitude: 38.8977, longitude: -77.0365 }
|
||||
}
|
||||
|
||||
function parsePlacesApiPlace(place: any): AddressPlaceItem | null {
|
||||
if (!place) return null
|
||||
|
||||
const lat = place.location?.latitude
|
||||
const lng = place.location?.longitude
|
||||
const formattedAddress = String(place.formattedAddress || '').trim()
|
||||
const displayName = String(
|
||||
typeof place.displayName === 'string'
|
||||
? place.displayName
|
||||
: place.displayName?.text || formattedAddress,
|
||||
).trim()
|
||||
|
||||
if (!displayName && !formattedAddress) return null
|
||||
|
||||
return {
|
||||
id: String(place.id || ''),
|
||||
displayName: displayName || formattedAddress,
|
||||
formattedAddress,
|
||||
location:
|
||||
Number.isFinite(Number(lat)) && Number.isFinite(Number(lng))
|
||||
? { lat: Number(lat), lng: Number(lng) }
|
||||
: null,
|
||||
}
|
||||
}
|
||||
|
||||
function parseGeocodeResult(result: any): AddressPlaceItem | null {
|
||||
if (!result) return null
|
||||
|
||||
const formattedAddress = String(result.formatted_address || '').trim()
|
||||
const lat = result.geometry?.location?.lat
|
||||
const lng = result.geometry?.location?.lng
|
||||
const displayName =
|
||||
formattedAddress.split(',')[0]?.trim() || formattedAddress
|
||||
|
||||
if (!formattedAddress) return null
|
||||
|
||||
return {
|
||||
id: String(result.place_id || ''),
|
||||
displayName,
|
||||
formattedAddress,
|
||||
location:
|
||||
Number.isFinite(Number(lat)) && Number.isFinite(Number(lng))
|
||||
? { lat: Number(lat), lng: Number(lng) }
|
||||
: null,
|
||||
}
|
||||
}
|
||||
|
||||
function requestJson<T = any>(options: UniApp.RequestOptions) {
|
||||
return new Promise<{ statusCode: number; data: T }>((resolve, reject) => {
|
||||
uni.request({
|
||||
timeout: 10000,
|
||||
...options,
|
||||
success: (res) => resolve(res as any),
|
||||
fail: reject,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function searchByPlacesTextSearch(keyword: string) {
|
||||
const languageCode = resolveLanguageCode()
|
||||
const regionCode = resolveRegionCode()
|
||||
const center = resolveBiasCenter()
|
||||
|
||||
const res = await requestJson<{ places?: any[]; error?: any }>({
|
||||
url: 'https://places.googleapis.com/v1/places:searchText',
|
||||
method: 'POST',
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Goog-Api-Key': Config.googleMapKey,
|
||||
'X-Goog-FieldMask': 'places.id,places.displayName,places.formattedAddress,places.location',
|
||||
},
|
||||
data: {
|
||||
textQuery: keyword,
|
||||
languageCode,
|
||||
regionCode,
|
||||
pageSize: 20,
|
||||
locationBias: {
|
||||
circle: {
|
||||
center,
|
||||
radius: 50000,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (res.statusCode !== 200) {
|
||||
const message = (res.data as any)?.error?.message || `HTTP ${res.statusCode}`
|
||||
throw new Error(message)
|
||||
}
|
||||
|
||||
const places = Array.isArray(res.data?.places) ? res.data.places : []
|
||||
return places.map(parsePlacesApiPlace).filter(Boolean) as AddressPlaceItem[]
|
||||
}
|
||||
|
||||
async function searchByGeocodeFallback(keyword: string) {
|
||||
const languageCode = resolveLanguageCode()
|
||||
const regionCode = resolveRegionCode()
|
||||
const query = encodeURIComponent(keyword)
|
||||
const url =
|
||||
`https://maps.googleapis.com/maps/api/geocode/json?address=${query}` +
|
||||
`&key=${Config.googleMapKey}&language=${languageCode}®ion=${regionCode}`
|
||||
|
||||
const res = await requestJson<{ results?: any[]; status?: string }>({
|
||||
url,
|
||||
method: 'GET',
|
||||
})
|
||||
|
||||
if (res.statusCode !== 200 || res.data?.status !== 'OK') {
|
||||
return []
|
||||
}
|
||||
|
||||
const results = Array.isArray(res.data.results) ? res.data.results : []
|
||||
return results.map(parseGeocodeResult).filter(Boolean) as AddressPlaceItem[]
|
||||
}
|
||||
|
||||
async function searchPlaces(keyword: string) {
|
||||
logicStore.searchLoading = true
|
||||
hasSearched.value = true
|
||||
|
||||
try {
|
||||
let list = await searchByPlacesTextSearch(keyword)
|
||||
|
||||
if (list.length === 0) {
|
||||
list = await searchByGeocodeFallback(keyword)
|
||||
}
|
||||
|
||||
logicStore.setPlacesList(list)
|
||||
} catch (error) {
|
||||
console.error('地址搜索失败', error)
|
||||
try {
|
||||
const fallback = await searchByGeocodeFallback(keyword)
|
||||
logicStore.setPlacesList(fallback)
|
||||
} catch (fallbackError) {
|
||||
console.error('Geocode 回退失败', fallbackError)
|
||||
logicStore.setPlacesList([])
|
||||
}
|
||||
} finally {
|
||||
logicStore.searchLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
const debouncedSearch = debounce(300, (keyword: string) => {
|
||||
void searchPlaces(keyword)
|
||||
})
|
||||
|
||||
function handleClickLocation(item: any) {
|
||||
console.log('item', item)
|
||||
watch(mapSearchKeyword, (keyword) => {
|
||||
const text = String(keyword || '').trim()
|
||||
if (!text) {
|
||||
hasSearched.value = false
|
||||
logicStore.clearPlacesList()
|
||||
return
|
||||
}
|
||||
debouncedSearch(text)
|
||||
})
|
||||
|
||||
function handleClickLocation(item: AddressPlaceItem) {
|
||||
openerEventChannel?.emit?.('chooseAddress', item)
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
// 使用当前位置
|
||||
function handleUseLocation() {
|
||||
// 检查是否获取到了当前定位
|
||||
if (!userStore.location.longitude || !userStore.location.latitude) {
|
||||
// 尝试再次获取定位
|
||||
uni.getLocation({
|
||||
isHighAccuracy: true,
|
||||
type: 'gcj02',
|
||||
geocode: true,
|
||||
success: async (res) => {
|
||||
success: (res) => {
|
||||
getCityName(res.latitude, res.longitude)
|
||||
},
|
||||
fail: (err) => {
|
||||
fail: () => {
|
||||
const settings = uni.getAppAuthorizeSetting()
|
||||
console.log(settings)
|
||||
if (settings.locationAuthorized === 'denied') {
|
||||
uni.showToast({
|
||||
title: t('common.prompt.please-authorize-location-information'),
|
||||
icon: 'none'
|
||||
icon: 'none',
|
||||
})
|
||||
setTimeout(()=> {
|
||||
setTimeout(() => {
|
||||
uni.openAppAuthorizeSetting()
|
||||
})
|
||||
}
|
||||
@@ -143,311 +305,75 @@ function handleUseLocation() {
|
||||
formattedAddress: userStore.location.formattedAddress || '',
|
||||
location: {
|
||||
lng: userStore.location.longitude,
|
||||
lat: userStore.location.latitude
|
||||
}
|
||||
lat: userStore.location.latitude,
|
||||
},
|
||||
})
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
|
||||
function getCityName(latitude: number, longitude: number) {
|
||||
const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${Config.googleMapKey}&language=${locale.value === 'zh-Hans' ? 'zh-CN' : locale.value}`;
|
||||
const languageCode = resolveLanguageCode()
|
||||
const url =
|
||||
`https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}` +
|
||||
`&key=${Config.googleMapKey}&language=${languageCode}`
|
||||
|
||||
uni.request({
|
||||
url,
|
||||
method: 'GET',
|
||||
timeout: 10000,
|
||||
success: (res: any) => {
|
||||
const results = res.data?.results || [];
|
||||
console.log('geocode results:', results);
|
||||
const results = res.data?.results || []
|
||||
|
||||
if (!results.length) {
|
||||
return handleFail();
|
||||
return handleFail()
|
||||
}
|
||||
|
||||
const addr = results[0]; // 最高匹配度
|
||||
const components = addr.address_components || [];
|
||||
const addr = results[0]
|
||||
const components = addr.address_components || []
|
||||
|
||||
// 提取城市名的工具函数
|
||||
const pickAddress = (types: string[]) => {
|
||||
return components.find((item) => item.types.some((t) => types.includes(t)));
|
||||
};
|
||||
return components.find((item: any) => item.types.some((type: string) => types.includes(type)))
|
||||
}
|
||||
|
||||
// 寻找城市名(多层兜底)
|
||||
let cityObj =
|
||||
pickAddress(["locality"]) ||
|
||||
pickAddress(["administrative_area_level_2"]) ||
|
||||
pickAddress(["administrative_area_level_1"]) ||
|
||||
pickAddress(["political"]);
|
||||
const cityObj =
|
||||
pickAddress(['locality']) ||
|
||||
pickAddress(['administrative_area_level_2']) ||
|
||||
pickAddress(['administrative_area_level_1']) ||
|
||||
pickAddress(['political'])
|
||||
|
||||
const cityName = cityObj?.long_name || null;
|
||||
|
||||
// 从 Google 获取完整地址
|
||||
const formattedAddress = addr.formatted_address || cityName || "";
|
||||
|
||||
console.log("city:", cityObj);
|
||||
console.log("formattedAddress:", formattedAddress);
|
||||
const cityName = cityObj?.long_name || null
|
||||
const formattedAddress = addr.formatted_address || cityName || ''
|
||||
|
||||
if (!cityName) {
|
||||
return handleFail();
|
||||
return handleFail()
|
||||
}
|
||||
|
||||
// 存入 store
|
||||
userStore.location = {
|
||||
location: cityName,
|
||||
formattedAddress,
|
||||
longitude,
|
||||
latitude
|
||||
};
|
||||
latitude,
|
||||
}
|
||||
|
||||
// 回传上一页(eventChannel)
|
||||
openerEventChannel?.emit?.('chooseAddress', {
|
||||
displayName: cityName,
|
||||
formattedAddress,
|
||||
location: { lng: longitude, lat: latitude }
|
||||
});
|
||||
location: { lng: longitude, lat: latitude },
|
||||
})
|
||||
|
||||
uni.navigateBack();
|
||||
uni.navigateBack()
|
||||
},
|
||||
|
||||
fail: () => handleFail()
|
||||
});
|
||||
fail: () => handleFail(),
|
||||
})
|
||||
|
||||
function handleFail() {
|
||||
uni.showToast({
|
||||
title: t('common.prompt.getLocationFailed'),
|
||||
icon: 'none'
|
||||
});
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const mapDataComputed = computed(() => {
|
||||
return {
|
||||
language: locale.value,
|
||||
lng: userStore.location.longitude || 174.7633,
|
||||
lat: userStore.location.latitude || -36.8485,
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
import { useLogicStore } from "@/pages-user/store/logic";
|
||||
|
||||
export default defineComponent({
|
||||
methods: {
|
||||
onMapSearchResult(places: any) {
|
||||
const logicStore = useLogicStore()
|
||||
console.log(places, '接收到的搜索结果')
|
||||
|
||||
if (places && places.length > 0) {
|
||||
// 保持与原先一致的解析逻辑
|
||||
const parsedPlaces = places
|
||||
.map((placeArray: any) => {
|
||||
const placeData = placeArray[0]?.[0]
|
||||
if (!placeData) return null
|
||||
|
||||
const placeId = placeData[1]
|
||||
const formattedAddress = placeData[8] || ''
|
||||
const locationArray = placeData[11]
|
||||
const displayNameArray = placeData[27]
|
||||
|
||||
return {
|
||||
id: placeId,
|
||||
displayName: displayNameArray?.[0] || formattedAddress,
|
||||
formattedAddress: formattedAddress,
|
||||
location: locationArray
|
||||
? {
|
||||
lat: locationArray[0],
|
||||
lng: locationArray[1],
|
||||
}
|
||||
: null,
|
||||
}
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
console.log('解析后的地址列表', parsedPlaces)
|
||||
logicStore.setPlacesList(parsedPlaces)
|
||||
} else {
|
||||
logicStore.setPlacesList([])
|
||||
}
|
||||
},
|
||||
onMapNotLoaded() {
|
||||
uni.showToast({
|
||||
title: 'Map is not loaded yet, please wait',
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
onMapSearchTimeout() {
|
||||
uni.showToast({
|
||||
title: 'Search timeout, please try again',
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
onMapSearchLoading(_isLoading: boolean) {
|
||||
// 如需联动 loading,可在此处驱动 store
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<script lang="renderjs" module="mapRenderjs">
|
||||
import {Loader} from "@googlemaps/js-api-loader"
|
||||
import * as R from 'ramda'
|
||||
import Config from '@/config'
|
||||
import {debounce} from "throttle-debounce";
|
||||
|
||||
let map = null
|
||||
let mapLoaded = false; // 地图加载完成标志
|
||||
// @ts-ignore
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
region: "US",
|
||||
lan: 'en',
|
||||
google: null,
|
||||
canvas: null,
|
||||
center: null,
|
||||
dotLottie: null,
|
||||
marker: null,
|
||||
markerViewList: [],
|
||||
AdvancedMarkerElement: null,
|
||||
lng: -77.0365,
|
||||
lat: 38.8977,
|
||||
userLocation: {
|
||||
longitude: 0,
|
||||
latitude: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
userLocation: Object
|
||||
},
|
||||
mounted() {
|
||||
console.log('mounted mapRenderjs')
|
||||
mapLoaded = false; // 重置地图加载完成标志
|
||||
// !map&&this.initMap()
|
||||
this.searchPlace = debounce(200, this.searchPlace)
|
||||
},
|
||||
methods: {
|
||||
initMap({lng, lat, language}) {
|
||||
console.log('initMap', lng, lat)
|
||||
console.log('当前系统语言', language)
|
||||
|
||||
this.lan = language === 'zh-Hans' ? 'zh-CN' : 'en'
|
||||
this.region = language === 'zh-Hans' ? 'CN' : 'US'
|
||||
this.lng = language === 'zh-Hans' ? 116.4074 : -77.0365
|
||||
this.lat = language === 'zh-Hans' ? 39.9042 : 38.8977
|
||||
console.log('当前系统语言', this.lan)
|
||||
console.log('当前系统区域', this.region)
|
||||
|
||||
this.$nextTick(() => {
|
||||
const loader = new Loader({
|
||||
apiKey: Config.googleMapKey,
|
||||
version: "weekly",
|
||||
region: this.region, // 设置为美国
|
||||
language: this.lan,
|
||||
});
|
||||
|
||||
|
||||
loader.load().then(async (google) => {
|
||||
const {Map} = await google.maps.importLibrary("maps")
|
||||
this.google = google
|
||||
console.log('google', google.maps)
|
||||
// 地图相关配置
|
||||
// 指定自定义地图样式的 ID。
|
||||
// center: 地图初始中心点的经纬度(lat, lng)。
|
||||
// zoom: 地图初始缩放级别。
|
||||
// fullscreenControl: 是否显示全屏按钮(false 表示不显示)。
|
||||
// cameraControl: 是否显示相机控制(false 表示不显示)。
|
||||
// disableDefaultUI: 是否禁用所有默认 UI 控件(true 表示全部禁用)。
|
||||
// gestureHandling: 设置手势操作方式("greedy" 表示允许所有手势操作)
|
||||
const mapOptions = {
|
||||
mapId: 'ff2268c265ce7a40',
|
||||
center: {
|
||||
lat: this.lat,
|
||||
lng: this.lng,
|
||||
},
|
||||
zoom: 12,
|
||||
fullscreenControl: false,
|
||||
cameraControl: false,
|
||||
disableDefaultUI: true,
|
||||
gestureHandling: "greedy",
|
||||
};
|
||||
|
||||
map = new Map(document.getElementById("map"), mapOptions);
|
||||
mapLoaded = true; // 地图加载完成
|
||||
});
|
||||
})
|
||||
},
|
||||
async searchPlace({keyword}) {
|
||||
console.log('搜索关键词', keyword);
|
||||
if (!keyword) {
|
||||
this.$ownerInstance.callMethod('onMapSearchResult', [])
|
||||
return;
|
||||
}
|
||||
if (!mapLoaded) {
|
||||
console.log('地图未加载完成,无法搜索');
|
||||
this.$ownerInstance.callMethod('onMapNotLoaded');
|
||||
return;
|
||||
}
|
||||
if (!map || !this.google) {
|
||||
return
|
||||
}
|
||||
this.$ownerInstance.callMethod('onMapSearchLoading', true);
|
||||
let timeoutId;
|
||||
try {
|
||||
// 设置搜索超时
|
||||
const timeoutPromise = new Promise((_, reject) => {
|
||||
timeoutId = setTimeout(() => {
|
||||
this.$ownerInstance.callMethod('onMapSearchLoading', false);
|
||||
reject(new Error('Search timeout'));
|
||||
}, 10000); // 10 秒超时
|
||||
});
|
||||
|
||||
const {Place, SearchByTextRankPreference} = await this.google.maps.importLibrary("places");
|
||||
const request = {
|
||||
textQuery: keyword,
|
||||
fields: ['id', 'displayName', 'location', 'formattedAddress', 'addressComponents'],
|
||||
locationBias: {lat: this.lat, lng: this.lng},
|
||||
language: this.lan,
|
||||
maxResultCount: 20,
|
||||
region: this.region,
|
||||
rankPreference: SearchByTextRankPreference.RELEVANCE
|
||||
};
|
||||
|
||||
const searchPromise = Place.searchByText(request);
|
||||
const {places} = await Promise.race([searchPromise, timeoutPromise]);
|
||||
console.log('地图搜索结果原始数据', places);
|
||||
|
||||
// 将 Google Places API 返回的对象转换为可序列化的数组格式
|
||||
const serializedPlaces = places.map(place => {
|
||||
// 提取需要的字段并转换为普通对象
|
||||
return [[{
|
||||
1: place.id,
|
||||
8: place.formattedAddress || '',
|
||||
9: place.addressComponents || [],
|
||||
11: place.location ? [place.location.lat(), place.location.lng()] : null,
|
||||
27: place.displayName ? [
|
||||
typeof place.displayName === 'string' ? place.displayName : place.displayName.text,
|
||||
place.displayName.languageCode || this.lan
|
||||
] : null
|
||||
}]];
|
||||
});
|
||||
|
||||
console.log('序列化后的搜索结果', serializedPlaces);
|
||||
this.$ownerInstance.callMethod('onMapSearchResult', serializedPlaces);
|
||||
} catch (e) {
|
||||
console.log('搜索错误原因', e);
|
||||
if (e.message === 'Search timeout') {
|
||||
this.$ownerInstance.callMethod('onMapSearchTimeout');
|
||||
}
|
||||
this.$ownerInstance.callMethod('onMapSearchResult', []);
|
||||
} finally {
|
||||
clearTimeout(timeoutId);
|
||||
this.$ownerInstance.callMethod('onMapSearchLoading', false);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
page {
|
||||
@@ -456,4 +382,4 @@ page {
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user