feat(robotaxi): 优化订单详情地图显示与首页城市选择逻辑
- 在订单详情页添加 `useDidHide` 钩子以在页面隐藏时重置地图状态
- 新增 `getPointsCenter` 函数计算路径中心点并自动调整地图视野
- 在首页重构城市选择逻辑,提取 `ensureSelectedCityReady` 函数复用代码
- 修改 `updateMapData` 函数以接受可选 `cityCode` 参数,避免重复获取城市信息
- 修复轨迹点坐标类型转换问题,确保地图路径正确渲染
| | |
| | | code: '', |
| | | }); // 选中的城市 |
| | | |
| | | const ensureSelectedCityReady = async (lng: number, lat: number, skipCityEffect = false) => { |
| | | const cachedCity = Taro.getStorageSync('selectedCity'); |
| | | if (cachedCity?.code) { |
| | | return cachedCity; |
| | | } |
| | | try { |
| | | const data = await getAddressByLocation(lng, lat); |
| | | if (data?.regeocodeData?.addressComponent) { |
| | | const { city, province, adcode } = data.regeocodeData.addressComponent; |
| | | const cityName = (city && typeof city === 'string' && city.length > 0) ? city : province; |
| | | const cityCode = convertAdcodeToCityCode(adcode, cityName, province); |
| | | const cityInfo = await getCityInfoWithId(cityCode, cityName); |
| | | if (cityInfo?.code) { |
| | | if (skipCityEffect) { |
| | | skipCityChangeEffectRef.current = true; |
| | | } |
| | | setSelectedCity(cityInfo); |
| | | Taro.setStorageSync('selectedCity', cityInfo); |
| | | return cityInfo; |
| | | } |
| | | } |
| | | } catch (error) { |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | const ORDER_STATUS = { |
| | | 4: '车辆正在赶来', |
| | | 5: '车辆已到达上车点,请尽快前往', |
| | |
| | | setCurrentSite(startSite); |
| | | setIsAdsorbed(true); |
| | | shouldIgnoreRegionChange.current = true; |
| | | |
| | | // 初始化时也调用接口检查运营区状态和更新站点 |
| | | updateMapData(startSite.latitude, startSite.longitude); |
| | | if (!selectedCity || !selectedCity.code) { |
| | | getAddressByLocation(startSite.longitude, startSite.latitude) |
| | | .then((data) => { |
| | | if (data?.regeocodeData?.addressComponent) { |
| | | const { city, province, adcode } = data.regeocodeData.addressComponent; |
| | | const cityName = (city && typeof city === 'string' && city.length > 0) ? city : province; |
| | | const cityCode = convertAdcodeToCityCode(adcode, cityName, province); |
| | | getCityInfoWithId(cityCode, cityName).then(cityInfo => { |
| | | skipCityChangeEffectRef.current = true; |
| | | setSelectedCity(cityInfo); |
| | | Taro.setStorageSync('selectedCity', cityInfo); |
| | | }); |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | }); |
| | | const cachedCity = Taro.getStorageSync('selectedCity'); |
| | | if (cachedCity?.code) { |
| | | updateMapData(startSite.latitude, startSite.longitude, cachedCity.code); |
| | | } else { |
| | | ensureSelectedCityReady(startSite.longitude, startSite.latitude, true).then((cityInfo) => { |
| | | if (cityInfo?.code) { |
| | | updateMapData(startSite.latitude, startSite.longitude, cityInfo.code); |
| | | } |
| | | }); |
| | | } |
| | | } else { |
| | | if (isCitySwitchingRef.current) { |
| | |
| | | } |
| | | |
| | | // 更新地图数据 |
| | | const updateMapData = async (lat: number, lng: number) => { |
| | | const selectedCity = Taro.getStorageSync('selectedCity'); |
| | | const { isInside, electronicAreaId, newMarkers, sites } = await fetchMapData(lat, lng, selectedCity?.code); |
| | | const updateMapData = async (lat: number, lng: number, cityCode?: string) => { |
| | | const code = cityCode || Taro.getStorageSync('selectedCity')?.code; |
| | | if (!code) { |
| | | return { isInside: false, electronicAreaId: '', newMarkers: [], sites: [] }; |
| | | } |
| | | const { isInside, electronicAreaId, newMarkers, sites } = await fetchMapData(lat, lng, code); |
| | | |
| | | setIsOperatingArea(isInside); |
| | | setElectronicAreaId(electronicAreaId); |
| | |
| | | } |
| | | |
| | | try { |
| | | // 更新地图数据 |
| | | const { newMarkers, sites } = await updateMapData(res.latitude, res.longitude); |
| | | |
| | | const { targetMarker, minDistance } = findNearestMarker(res.latitude, res.longitude, sites.length > 0 ? sites : newMarkers); |
| | | |
| | | if (minDistance < adsorptionDistance && targetMarker) { |
| | | setIsAdsorbed(true); |
| | | setCurrentSite(targetMarker); |
| | | setShowToolTip(true); |
| | | return; |
| | | const cityInfo = await ensureSelectedCityReady(res.longitude, res.latitude); |
| | | if (cityInfo?.code) { |
| | | const { newMarkers, sites } = await updateMapData(res.latitude, res.longitude, cityInfo.code); |
| | | const { targetMarker, minDistance } = findNearestMarker(res.latitude, res.longitude, sites.length > 0 ? sites : newMarkers); |
| | | if (minDistance < adsorptionDistance && targetMarker) { |
| | | setIsAdsorbed(true); |
| | | setCurrentSite(targetMarker); |
| | | setShowToolTip(true); |
| | | return; |
| | | } |
| | | } |
| | | } catch (error) { |
| | | |
| | | } |
| | | |
| | | // 获取当前位置的逆地理编码 |
| | |
| | | import Taro, { useRouter, useDidShow } from '@tarojs/taro'; |
| | | import Taro, { useRouter, useDidShow, useDidHide } from '@tarojs/taro'; |
| | | import { useState, useEffect } from 'react'; |
| | | import { View, Text, Image, Map } from '@tarojs/components'; |
| | | import './index.less'; |
| | |
| | | const [markers, setMarkers] = useState<any[]>([]) // 起点和终点标记 |
| | | const [polyline, setPolyline] = useState<any[]>([]) // 行驶路径 |
| | | |
| | | const getPointsCenter = (points: Array<{ longitude: number; latitude: number }>) => { |
| | | if (!points.length) { |
| | | return null; |
| | | } |
| | | let minLng = points[0].longitude; |
| | | let maxLng = points[0].longitude; |
| | | let minLat = points[0].latitude; |
| | | let maxLat = points[0].latitude; |
| | | points.forEach((point) => { |
| | | minLng = Math.min(minLng, point.longitude); |
| | | maxLng = Math.max(maxLng, point.longitude); |
| | | minLat = Math.min(minLat, point.latitude); |
| | | maxLat = Math.max(maxLat, point.latitude); |
| | | }); |
| | | return { longitude: (minLng + maxLng) / 2, latitude: (minLat + maxLat) / 2 }; |
| | | }; |
| | | |
| | | useEffect(() => { |
| | | if (orderId) { |
| | | fetchOrderDetail(orderId); |
| | | } |
| | | }, [orderId]); |
| | | |
| | | useDidHide(() => { |
| | | setMarkers([]); |
| | | setPolyline([]); |
| | | setLongitude(116.397128); |
| | | setLatitude(39.916527); |
| | | setOrderData(null); |
| | | setShowEvaluatePopup(false); |
| | | setActiveIndex(null); |
| | | }); |
| | | |
| | | const getNavTitle = (status: number) => { |
| | | if (status == 0) { |
| | |
| | | |
| | | // 处理行驶路径 |
| | | const routePath = trajectories?.length > 0 |
| | | ? trajectories.map(item => ({ longitude: item.location.split(',')[0], latitude: item.location.split(',')[1] })) |
| | | ? trajectories.map(item => ({ longitude: Number(item.location.split(',')[0]), latitude: Number(item.location.split(',')[1]) })) |
| | | : [ |
| | | { longitude: startLon, latitude: startLat }, |
| | | { longitude: endLon, latitude: endLat } |
| | | ]; |
| | | const center = getPointsCenter(routePath); |
| | | if (center) { |
| | | setLongitude(center.longitude); |
| | | setLatitude(center.latitude); |
| | | } |
| | | |
| | | const polylineData = [{ |
| | | points: routePath, |