src/robotaxi/pages/begin-route/components/calling-car-modules/door-trunk-control.tsx
@@ -67,7 +67,7 @@ doorType, ...locationPayload }).then((res: any) => { console.log(res,'***********'); console.log('解锁结果:', res); if (!res) { Taro.showToast({ title: '解锁失败,请重试或联系客服', icon: 'none' }); @@ -75,22 +75,34 @@ } if (doorType === 'trunk') { const loadingText = trunkStatus ? '正在关闭后备箱' : '正在开启后备箱'; const isCloseAction = !!trunkStatus; const loadingText = isCloseAction ? '正在关闭后备箱' : '正在开启后备箱'; Taro.showLoading({ title: loadingText, mask: true }); let pollCount = 0; const maxPolls = 3; const maxPolls = 5; const pollInterval = 2000; const expectedTrunkState = trunkStatus ? '0' : '1'; const expectedTrunkState = isCloseAction ? 0 : 1; const successToastText = isCloseAction ? '关闭后备箱成功' : '打开后备箱成功'; const failToastText = isCloseAction ? '关闭后备箱失败' : '开启后备箱失败'; const stopPolling = () => { if (trunkPollTimerRef.current) { clearTimeout(trunkPollTimerRef.current); trunkPollTimerRef.current = null; } }; const handlePollFail = (reason: string, actualValue?: any) => { pollCount++; if (pollCount < maxPolls) { stopPolling(); trunkPollTimerRef.current = setTimeout(doPoll, pollInterval); } else { stopPolling(); Taro.hideLoading(); Taro.showToast({ title: trunkStatus ? '关闭后备箱失败' : '开启后备箱失败', title: failToastText, icon: 'none' }); } @@ -98,19 +110,31 @@ const doPoll = () => { queryVehicleTrunkOpenStatus({ orderId: targetOrderId }).then((pollRes: any) => { const data = pollRes; const rawValue = data?.stateMap?.trunkAjarCloseSt?.value; if (!data || rawValue === undefined || rawValue === null || rawValue === '') { console.log('第', pollCount, '次查询后备箱状态:', pollRes); const rawValue = typeof pollRes === 'number' ? pollRes : ( pollRes?.data ?? pollRes?.stateMap?.trunkAjarCloseSt?.value ?? pollRes?.value ); if (rawValue === undefined || rawValue === null || rawValue === '') { handlePollFail('empty_data_or_value', rawValue); return; } const value = String(rawValue); const value = Number(rawValue); if (Number.isNaN(value)) { handlePollFail('invalid_value', rawValue); return; } if (value === expectedTrunkState) { const isOpen = value === '1'; stopPolling(); const isOpen = !isCloseAction; setTrunkStatus(isOpen); Taro.hideLoading(); Taro.showToast({ title: isOpen ? '打开成功' : '关闭成功', title: successToastText, icon: 'none' }); onSuccess?.(); @@ -139,7 +163,7 @@ if (tripStatus === 5) { return ( <View className="car-card-arrive"> <View className={`car-card-arrive-item ${trunkStatus && 'close-btn-item'}`} onClick={() => handleUnlock('trunk')}> <View className={`car-card-arrive-item ${trunkStatus && 'close-btn-item'}`} onClick={() => handleUnlock('trunk', () => setTrunkStatus(!trunkStatus))}> <Image className="car-card-arrive-item-img" src={trunkStatus ? require('../../../../assets/trunk-open.png') : require('../../../../assets/trunk-close.png')} /> <View className="car-card-arrive-item-text">{trunkStatus ? '关闭后备箱' : '打开后备箱'}</View> </View> @@ -157,7 +181,7 @@ <View className="car-card-reach-text">点击按钮开车门</View> <Image className='car-card-reach-img' src='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/door-anim.webp' /> <View className="car-card-reach-btn"> <View className={`car-card-reach-btn-item ${trunkStatus && 'close-btn-item'}`} onClick={() => handleUnlock('trunk')}> <View className={`car-card-reach-btn-item ${trunkStatus && 'close-btn-item'}`} onClick={() => handleUnlock('trunk', () => setTrunkStatus(!trunkStatus))}> <Image className="car-card-reach-btn-item-img" src={trunkStatus ? require('../../../../assets/trunk-open.png') : require('../../../../assets/trunk-close.png')} /> <View className="car-card-reach-btn-item-text">{trunkStatus ? '关闭后备箱' : '打开后备箱'}</View> </View> @@ -171,4 +195,4 @@ } return null; } } src/robotaxi/pages/begin-route/hooks/use-vehicle-tracking.ts
@@ -22,17 +22,11 @@ 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 TRANSLATE_DURATION_MS = 100; // 更新车辆位置并维护最近位置引用 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; @@ -44,20 +38,17 @@ if (!statusRule.translateCar) return; if (!vehicleLocation) return; const mapCtx = Taro.createMapContext('map'); const timer = setTimeout(() => { mapCtx.translateMarker({ markerId: vehicleMarkerId, destination: { latitude: vehicleLocation.latitude, longitude: vehicleLocation.longitude, }, autoRotate: false, moveWithRotate: true, rotate: typeof vehicleDirection === 'number' ? ((vehicleDirection % 360) + 360) % 360 : 0, duration: translateDurationRef.current }); }, 100); return () => clearTimeout(timer); mapCtx.translateMarker({ markerId: vehicleMarkerId, destination: { latitude: vehicleLocation.latitude, longitude: vehicleLocation.longitude, }, autoRotate: false, moveWithRotate: true, rotate: typeof vehicleDirection === 'number' ? ((vehicleDirection % 360) + 360) % 360 : 0, duration: TRANSLATE_DURATION_MS }); }, [statusRule.translateCar, vehicleLocation, vehicleDirection, vehicleMarkerId]); return { src/robotaxi/pages/begin-route/hooks/use-web-socket-events.ts
@@ -182,6 +182,14 @@ return null; }; const resolveVehiclePointForErase = (points: any[], servedPoints: any[] = []) => { const firstPoint = points?.[0]; if (firstPoint && typeof firstPoint.latitude === 'number' && typeof firstPoint.longitude === 'number') { return firstPoint; } return resolveVehiclePoint(points, servedPoints); }; const syncVehiclePointWithRoute = (points: any[], deps: UseWebSocketEventsDeps, servedPoints: any[] = []) => { const targetPoint = resolveVehiclePoint(points, servedPoints); if (!targetPoint) { @@ -191,7 +199,10 @@ }; const handleEraseRouteStatus = (points: any[], servedPoints: any[], deps: UseWebSocketEventsDeps) => { const targetPoint = resolveVehiclePoint(points, servedPoints); const targetPoint = resolveVehiclePointForErase(points, servedPoints); if (targetPoint) { deps.updateVehicleLocationThrottled(targetPoint.latitude, targetPoint.longitude, true); } if (deps.orderRouteInitializedRef.current && deps.currentFullRouteRef.current.length > 0) { deps.erasePassedRouteSegments(points); } else { @@ -201,11 +212,6 @@ Taro.nextTick(() => { deps.applyRoutePoints(points); }); } if (targetPoint) { setTimeout(() => { deps.updateVehicleLocationThrottled(targetPoint.latitude, targetPoint.longitude, true); }, 50); } }; @@ -241,7 +247,6 @@ }; const handleOrderRoutePayload = (payload: any, deps: UseWebSocketEventsDeps) => { if (deps.tripStatusRef.current === 5) return; const points = payload?.points || []; const servedPoints = Array.isArray(payload?.servedPoints) ? payload.servedPoints : []; const forceFullRedraw = payload?.forceFullRedraw === true;