Merge branch 'feature_CR_issue' into feature_v1.0
| | |
| | | return request({ |
| | | url: _ROBOTAXI_HOST + '/vehicleConvoy/api/v1/mini-program/order/vehicle/unlock', |
| | | method: 'POST', |
| | | payload |
| | | payload, |
| | | showToast: true, |
| | | skipException: true |
| | | }, true); |
| | | } |
| | | |
| | |
| | | doorType, |
| | | ...locationPayload |
| | | }).then((res: any) => { |
| | | console.log(res,'***********'); |
| | | |
| | | if (!res) { |
| | | Taro.showToast({ title: '解锁失败,请重试或联系客服', icon: 'none' }); |
| | | return; |
| | |
| | | } |
| | | } |
| | | }).catch(() => { |
| | | console.log(res,'***********'); |
| | | |
| | | Taro.showToast({ title: '解锁失败,请重试或联系客服', icon: 'none' }); |
| | | }); |
| | | }; |
| | |
| | | const cachedOrderId = Taro.getStorageSync('orderId'); |
| | | const cachedTripStatusStorage = Taro.getStorageSync('tripStatus'); |
| | | const cachedTripStatus = Number(cachedTripStatusStorage) || deps.getCurrentTripStatus(); |
| | | deps.setTripStatus(cachedTripStatus); |
| | | syncCachedOrderVehicle(cachedOrderId); |
| | | syncSitesFromActiveOrder(cachedTripStatusStorage, s, e); |
| | | if (cachedOrderId && [4, 5, 6, 7, 8, 9].includes(cachedTripStatus)) { |
| | |
| | | const [trunkStatus, setTrunkStatus] = useState(false); |
| | | const lastVehiclePointRef = useRef<{ latitude: number; longitude: number } | null>(null); |
| | | const lastVehicleUpdateAtRef = useRef<number>(0); |
| | | const translateDurationRef = useRef<number>(900); |
| | | |
| | | // 更新车辆位置并维护最近位置引用 |
| | | const updateVehicleLocationThrottled = (lat: number, lng: number, force = false) => { |
| | | const now = Date.now(); |
| | | const prevUpdateAt = lastVehicleUpdateAtRef.current; |
| | | if (prevUpdateAt > 0) { |
| | | // 基于推送间隔动态调整平移时长,适配 1-2 秒频率的轨迹推送 |
| | | const interval = now - prevUpdateAt; |
| | | translateDurationRef.current = Math.max(350, Math.min(1600, Math.floor(interval * 0.85))); |
| | | } |
| | | if (Number.isFinite(lat) && Number.isFinite(lng)) { |
| | | lastVehiclePointRef.current = { latitude: lat, longitude: lng }; |
| | | lastVehicleUpdateAtRef.current = now; |
| | |
| | | |
| | | useEffect(() => { |
| | | if (!statusRule.translateCar) return; |
| | | if (vehicleMoveAlongPoints.length > 1) return; |
| | | if (!vehicleLocation) return; |
| | | const mapCtx = Taro.createMapContext('map'); |
| | | const timer = setTimeout(() => { |
| | |
| | | autoRotate: false, |
| | | moveWithRotate: true, |
| | | rotate: typeof vehicleDirection === 'number' ? ((vehicleDirection % 360) + 360) % 360 : 0, |
| | | duration: 100 |
| | | duration: translateDurationRef.current |
| | | }); |
| | | }, 100); |
| | | return () => clearTimeout(timer); |
| | | }, [statusRule.translateCar, vehicleLocation, vehicleDirection, vehicleMarkerId, vehicleMoveAlongPoints]); |
| | | |
| | | useEffect(() => { |
| | | if (!statusRule.translateCar) return; |
| | | if (vehicleMoveAlongPoints.length < 2) return; |
| | | const mapCtx = Taro.createMapContext('map'); |
| | | const duration = Math.min(2000, Math.max(300, vehicleMoveAlongPoints.length * 100)); |
| | | const timer = setTimeout(() => { |
| | | mapCtx.moveAlong({ |
| | | markerId: vehicleMarkerId, |
| | | path: vehicleMoveAlongPoints, |
| | | autoRotate: true, |
| | | duration |
| | | }); |
| | | }, 50); |
| | | return () => clearTimeout(timer); |
| | | }, [statusRule.translateCar, vehicleMoveAlongPoints, vehicleMarkerId]); |
| | | }, [statusRule.translateCar, vehicleLocation, vehicleDirection, vehicleMarkerId]); |
| | | |
| | | return { |
| | | vehicleLocation, |
| | |
| | | if (typeof mappedTripStatus !== 'number') { |
| | | return null; |
| | | } |
| | | const currentLocalStatus = Number(Taro.getStorageSync('tripStatus')); |
| | | if (currentLocalStatus > mappedTripStatus && currentLocalStatus !== 10) { |
| | | const currentTripStatus = Number(deps.tripStatusRef.current); |
| | | if (currentTripStatus > mappedTripStatus && currentTripStatus !== 10) { |
| | | return null; |
| | | } |
| | | deps.setTripStatus(mappedTripStatus); |
| | |
| | | } |
| | | }; |
| | | |
| | | const syncVehiclePointWithRoute = (points: any[], deps: UseWebSocketEventsDeps) => { |
| | | const resolveVehiclePoint = (points: any[], servedPoints: any[] = []) => { |
| | | const servedLastPoint = Array.isArray(servedPoints) && servedPoints.length > 0 |
| | | ? servedPoints[servedPoints.length - 1] |
| | | : null; |
| | | if (servedLastPoint && typeof servedLastPoint.latitude === 'number' && typeof servedLastPoint.longitude === 'number') { |
| | | return servedLastPoint; |
| | | } |
| | | const firstPoint = points?.[0]; |
| | | if (!firstPoint || typeof firstPoint.latitude !== 'number' || typeof firstPoint.longitude !== 'number') { |
| | | if (firstPoint && typeof firstPoint.latitude === 'number' && typeof firstPoint.longitude === 'number') { |
| | | return firstPoint; |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | const syncVehiclePointWithRoute = (points: any[], deps: UseWebSocketEventsDeps, servedPoints: any[] = []) => { |
| | | const targetPoint = resolveVehiclePoint(points, servedPoints); |
| | | if (!targetPoint) { |
| | | return; |
| | | } |
| | | deps.updateVehicleLocationThrottled(firstPoint.latitude, firstPoint.longitude, true); |
| | | deps.updateVehicleLocationThrottled(targetPoint.latitude, targetPoint.longitude, true); |
| | | }; |
| | | |
| | | const handleEraseRouteStatus = (points: any[], servedPoints: any[], deps: UseWebSocketEventsDeps) => { |
| | | const firstPoint = points?.[0]; |
| | | const targetPoint = resolveVehiclePoint(points, servedPoints); |
| | | if (deps.orderRouteInitializedRef.current && deps.currentFullRouteRef.current.length > 0) { |
| | | deps.erasePassedRouteSegments(points, servedPoints); |
| | | } else { |
| | |
| | | deps.applyRoutePoints(points); |
| | | }); |
| | | } |
| | | if (firstPoint && typeof firstPoint.latitude === 'number' && typeof firstPoint.longitude === 'number') { |
| | | if (targetPoint) { |
| | | setTimeout(() => { |
| | | deps.updateVehicleLocationThrottled(firstPoint.latitude, firstPoint.longitude, true); |
| | | deps.updateVehicleLocationThrottled(targetPoint.latitude, targetPoint.longitude, true); |
| | | }, 50); |
| | | } |
| | | }; |
| | | |
| | | const handleNormalRouteStatus = (points: any[], deps: UseWebSocketEventsDeps) => { |
| | | const handleNormalRouteStatus = (points: any[], deps: UseWebSocketEventsDeps, servedPoints: any[] = []) => { |
| | | Taro.nextTick(() => { |
| | | const updated = deps.applyRoutePoints(points); |
| | | if (!updated) return; |
| | | if (![4, 5, 6].includes(deps.tripStatusRef.current)) return; |
| | | syncVehiclePointWithRoute(points, deps); |
| | | syncVehiclePointWithRoute(points, deps, servedPoints); |
| | | }); |
| | | }; |
| | | |
| | | const handleForceFullRouteRedraw = (points: any[], deps: UseWebSocketEventsDeps) => { |
| | | const handleForceFullRouteRedraw = (points: any[], deps: UseWebSocketEventsDeps, servedPoints: any[] = []) => { |
| | | deps.setRoutePoints([]); |
| | | deps.setPolyline([]); |
| | | deps.orderRouteInitializedRef.current = false; |
| | |
| | | deps.currentFullRouteRef.current = [...points]; |
| | | deps.lastErasedIndexRef.current = 0; |
| | | deps.applyRoutePoints(points); |
| | | syncVehiclePointWithRoute(points, deps); |
| | | syncVehiclePointWithRoute(points, deps, servedPoints); |
| | | }); |
| | | }; |
| | | |
| | |
| | | deps.setVehicleMoveAlongPoints(servedPoints); |
| | | } |
| | | if (forceFullRedraw) { |
| | | handleForceFullRouteRedraw(points, deps); |
| | | handleForceFullRouteRedraw(points, deps, servedPoints); |
| | | return; |
| | | } |
| | | const isEraseStatus = [4, 6].includes(deps.tripStatusRef.current); |
| | |
| | | handleEraseRouteStatus(points, servedPoints, deps); |
| | | return; |
| | | } |
| | | handleNormalRouteStatus(points, deps); |
| | | handleNormalRouteStatus(points, deps, servedPoints); |
| | | }; |
| | | |
| | | export default function useWebSocketEvents(deps: UseWebSocketEventsDeps) { |
| | |
| | | const tripStatusRef = useRef(tripStatus); // 行程状态引用 |
| | | const lastTripStatusRef = useRef(tripStatus); // 上一次行程状态,用于检测状态变化 |
| | | const tripStatusForMapSyncRef = useRef(tripStatus); // 用于地图同步的行程状态引用 |
| | | useEffect(() => { |
| | | tripStatusRef.current = tripStatus; |
| | | tripStatusForMapSyncRef.current = tripStatus; |
| | | Taro.setStorageSync('tripStatus', tripStatus); |
| | | }, [tripStatus]); |
| | | // 行程状态显示规则配置:showPickup-显示上车点,showDropoff-显示下车点,showCar-显示车辆,showRoute-显示路线,showWalking-显示步行路线,viewport-视口类型,translateCar-车辆是否平移 |
| | | const STATUS_RULES: Record<number, any> = { |
| | | 1: { showPickup: true, showDropoff: true, showCar: false, showRoute: true, showWalking: true, viewport: 'route_walking', translateCar: false }, |