zjk
2026-06-13 f3097cc6a6982f31d8205de72e7bcc2dd037100a
fix(share-trip): 修复车辆旋转延迟及地图视觉残留问题

- 提前同步车辆朝向参数,修复iOS端车辆marker旋转慢半拍的问题
- 关闭分享页已行驶轨迹绘制,避免出现车辆移动后残留的浅蓝色影子
- 调整 completed 订单的地图视口更新逻辑
- 优化车辆跟踪钩子的代码格式与定时器逻辑
7个文件已修改
79 ■■■■■ 已修改文件
src/robotaxi/pages/begin-route/hooks/use-vehicle-tracking.ts 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/hooks/use-map-markers.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/hooks/use-map-viewport.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/hooks/use-polyline-render.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/hooks/use-share-trip-runtime.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/hooks/use-vehicle-tracking.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/index.tsx 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-vehicle-tracking.ts
@@ -18,7 +18,7 @@
 * 判断经纬度是否发生了可见位移。
 */
const hasMeaningfulLocationDelta = (
  nextLocation: { latitude: number; longitude: number },
  nextLocation: { latitude: number; longitude: number },
  previousLocation: { latitude: number; longitude: number } | null
) => {
  if (!previousLocation) {
@@ -129,7 +129,7 @@
        flushTranslateTask();
      }
    };
    // 兜底定时器,防止回调丢失导致动画队列卡死
    fallbackTimer = setTimeout(() => {
      finishTranslate();
src/robotaxi/pages/share-trip/hooks/use-map-markers.ts
@@ -50,6 +50,7 @@
    startSite: any;
    endSite: any;
    vehicleLocation: { latitude: number; longitude: number } | null;
    vehicleDirection: number | null;
    vehicleMarkerId: number;
    arrivedMarkerReady: boolean;
    onVehicleMarkerReady: () => void;
@@ -62,6 +63,7 @@
    startSite: null,
    endSite: null,
    vehicleLocation: null,
    vehicleDirection: null,
    vehicleMarkerId: 3,
    arrivedMarkerReady: false,
    onVehicleMarkerReady: () => { }
@@ -178,6 +180,9 @@
            anchor: { x: 0.5, y: 0.5 },
            zIndex: 2,
            name: '车辆位置',
            ...(deps.isAndroid ? {
                rotate: typeof deps.vehicleDirection === 'number' ? deps.vehicleDirection : 0,
            } : {}),
            customCallout: { anchorY: 80, anchorX: 0, display: 'ALWAYS' }
        };
    };
@@ -326,6 +331,7 @@
        deps.endSite?.latitude,
        deps.endSite?.longitude,
        deps.vehicleLocation,
        deps.vehicleDirection,
        deps.vehicleMarkerId,
        deps.isAndroid,
        deps.statusRule.showPickup,
src/robotaxi/pages/share-trip/hooks/use-map-viewport.ts
@@ -472,9 +472,12 @@
    useEffect(() => {
        viewportKeyRef.current = "";
        completedOrderDetailViewportKeyRef.current = "";
        if (deps.tripStatus < TripStatus.ArrivedDestination || deps.statusRule.viewport !== "order_detail") {
            completedOrderDetailViewportKeyRef.current = "";
        }
    }, [
        deps.tripStatus,
        deps.statusRule.viewport
    ]);
    useEffect(() => {
@@ -516,6 +519,9 @@
        if (deps.statusRule.viewport !== "order_detail") {
            return;
        }
        if (completedOrderDetailViewportKeyRef.current) {
            return;
        }
        const { pickupSite, dropoffSite } = resolveViewportSites();
        const points: ViewportPoint[] = [];
        const pickupPoint = buildSiteViewportPoint(pickupSite);
@@ -533,9 +539,6 @@
            return;
        }
        const nextKey = buildOrderDetailRouteSignature(deps.routePoints, pickupSite, dropoffSite);
        if (nextKey === completedOrderDetailViewportKeyRef.current) {
            return;
        }
        completedOrderDetailViewportKeyRef.current = nextKey;
        if (orderDetailSyncTimerRef.current) {
            clearTimeout(orderDetailSyncTimerRef.current);
src/robotaxi/pages/share-trip/hooks/use-polyline-render.ts
@@ -226,7 +226,10 @@
    };
    const getPassedRoutePoints = () => {
        const shouldShowPassedRoute = deps.tripStatus === TripStatus.InService
        // 对齐 begin-route 当前主链:分享页不单独绘制贴着车辆的浅色已行驶轨迹,
        // 避免视觉上像车辆 marker 移动后残留一层浅蓝色影子。
        const shouldShowPassedRoute = false
            && deps.tripStatus === TripStatus.InService
            && Array.isArray(deps.vehicleMoveAlongPoints)
            && deps.vehicleMoveAlongPoints.length > 1;
        if (!shouldShowPassedRoute) {
src/robotaxi/pages/share-trip/hooks/use-share-trip-runtime.ts
@@ -313,6 +313,11 @@
      servedPointsLength: servedPoints.length,
      routePointsLength: extractedRoutePoints.length,
    });
    if (typeof resolvedDirection === 'number') {
      // 对齐 begin-route:路线数据到达时先直接同步一次朝向,
      // 不只等后面的 RouteSnapshot 消费,避免 iOS 上旋转看起来慢半拍。
      deps.setVehicleDirection(resolvedDirection);
    }
    const routeSnapshot = buildShareRouteSnapshot({
      points: extractedRoutePoints,
      servedPoints,
src/robotaxi/pages/share-trip/hooks/use-vehicle-tracking.ts
@@ -94,7 +94,20 @@
        translateSessionIdRef.current += 1;
    };
    const flushTranslateTask = useCallback(() => {
    const notifyVehicleMarkerReady = useCallback(() => {
        if (vehicleMarkerReadyRef.current) {
            return;
        }
        clearVehicleMarkerReadyTimer();
        vehicleMarkerReadyTimerRef.current = setTimeout(() => {
            vehicleMarkerReadyTimerRef.current = null;
            vehicleMarkerReadyRef.current = true;
            flushTranslateTask();
        }, FIRST_VEHICLE_MARKER_READY_DELAY_MS);
    }, []);
    // 执行一次平移动画,完成后自动消费最新待执行目标
    const flushTranslateTask = () => {
        if (!vehicleMarkerReadyRef.current) return;
        if (isTranslatingRef.current) return;
        if (!pendingTranslateRef.current) return;
@@ -103,29 +116,30 @@
        pendingTranslateRef.current = null;
        isTranslatingRef.current = true;
        let finished = false;
        let fallbackTimer: ReturnType<typeof setTimeout> | null = null;
        let fallbackTimer: any = null;
        const finishTranslate = () => {
            if (finished) return;
            if (translateSessionId !== translateSessionIdRef.current) return;
            finished = true;
            if (fallbackTimer) {
                clearTimeout(fallbackTimer);
            }
            if (fallbackTimer) clearTimeout(fallbackTimer);
            isTranslatingRef.current = false;
            if (pendingTranslateRef.current) {
                flushTranslateTask();
            }
        };
        // 兜底定时器,防止回调丢失导致动画队列卡死
        fallbackTimer = setTimeout(() => {
            finishTranslate();
        }, TRANSLATE_DURATION_MS + 50);
        Taro.nextTick(() => {
            Taro.createMapContext("map").translateMarker({
            const mapCtx = Taro.createMapContext('map');
            mapCtx.translateMarker({
                markerId: task.markerId,
                destination: {
                    latitude: task.latitude,
                    longitude: task.longitude
                    longitude: task.longitude,
                },
                autoRotate: false,
                moveWithRotate: true,
@@ -155,19 +169,7 @@
                }
            });
        });
    }, []);
    const notifyVehicleMarkerReady = useCallback(() => {
        if (vehicleMarkerReadyRef.current) {
            return;
        }
        clearVehicleMarkerReadyTimer();
        vehicleMarkerReadyTimerRef.current = setTimeout(() => {
            vehicleMarkerReadyTimerRef.current = null;
            vehicleMarkerReadyRef.current = true;
            flushTranslateTask();
        }, FIRST_VEHICLE_MARKER_READY_DELAY_MS);
    }, [flushTranslateTask]);
    };
    // 更新车辆位置并维护最近位置引用
    const updateVehicleLocationThrottled = (
@@ -176,9 +178,6 @@
        force = false
    ) => {
        const now = Date.now();
        if (!force && !Number.isFinite(lat) && !Number.isFinite(lng)) {
            return;
        }
        if (Number.isFinite(lat) && Number.isFinite(lng)) {
            lastVehiclePointRef.current = { latitude: lat, longitude: lng };
            lastVehicleUpdateAtRef.current = now;
@@ -209,7 +208,7 @@
            duration: hasLocationDelta ? TRANSLATE_DURATION_MS : ROTATE_ONLY_DURATION_MS
        };
        flushTranslateTask();
    }, [statusRule.translateCar, vehicleLocation, vehicleDirection, vehicleMarkerId, flushTranslateTask]);
    }, [statusRule.translateCar, vehicleLocation, vehicleDirection, vehicleMarkerId]);
    useEffect(() => {
        if (!statusRule.translateCar) {
src/robotaxi/pages/share-trip/index.tsx
@@ -129,6 +129,7 @@
    startSite,
    endSite,
    vehicleLocation,
    vehicleDirection,
    vehicleMarkerId,
    arrivedMarkerReady,
    onVehicleMarkerReady: notifyVehicleMarkerReady,