fix(share-trip): 修复分享行程页地图视口抖动并新增行程结束状态处理
5个文件已修改
133 ■■■■■ 已修改文件
src/robotaxi/api/begin-route.ts 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/hooks/use-map-markers.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/hooks/use-map-viewport.ts 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/hooks/use-share-trip-runtime.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/api/begin-route.ts
@@ -327,7 +327,8 @@
    payload: QueryOrderRoutePayload
): Promise<any> => {
    return request({
        url: _ROBOTAXI_HOST + `/order/api/v1/mini-program/order/queryOrderTrajectory`,
        // url: _ROBOTAXI_HOST + `/order/api/v1/mini-program/order/queryOrderTrajectory`,
        url: _ROBOTAXI_HOST + `/order/base/v1/mini-program/orderActive/share/queryOrderTrajectory`,
        method: 'GET',
        payload,
        showToast: false,
@@ -346,14 +347,6 @@
    }, true);
}
// 分享订单查询实时轨迹路线
export const shareQueryOrderRoute = async (orderId: OrderId): Promise<ShareQueryOrderRouteResponse> => {
    return request({
        url: _ROBOTAXI_HOST + `/order/base/v1/mini-program/orderActive/share/queryOrderRoute/${orderId}`,
        method: 'GET'
    }, true);
}
// 静默查询分享订单实时路线,供分享页自行处理业务异常,避免默认拦截 toast。
export const shareQueryOrderRouteSilently = async (orderId: OrderId): Promise<any> => {
    return request({
@@ -361,17 +354,6 @@
        method: 'GET',
        showToast: false,
        skipException: true
    }, true);
}
// 分享订单查询订单详情
export const shareQueryOrderInfo = async (
    payload: ShareQueryOrderInfoPayload
): Promise<ShareQueryOrderInfoResponse> => {
    return request({
        url: _ROBOTAXI_HOST + '/order/base/v1/mini-program/orderActive/share/orderInfo',
        method: 'GET',
        payload
    }, true);
}
src/robotaxi/pages/share-trip/hooks/use-map-markers.ts
@@ -85,7 +85,7 @@
        useAndroidNativeTrip1Callout: boolean
    ) => {
        if (!(pickupSite?.latitude && pickupSite?.longitude)) return null;
        if (deps.isAndroid && [TripStatus.VehicleArrivedPickup, TripStatus.InService].includes(deps.tripStatus)) {
        if (deps.isAndroid && deps.tripStatus === TripStatus.InService) {
            return null;
        }
        return {
@@ -129,7 +129,7 @@
    ) => {
        if (!(dropoffSite?.latitude && dropoffSite?.longitude)) return null;
        // 分享行程只有从 5/6 及之后的状态才渲染下车点,避免 4 态提前入列引发地图多次缩放。
        if (deps.tripStatus < TripStatus.VehicleArrivedPickup) return null;
        if (deps.tripStatus <= TripStatus.VehicleArrivedPickup) return null;
        const dropoffName =
            [TripStatus.ArrivedDestination].includes(deps.tripStatus) ? '已到达' : dropoffSite.name || '目的地';
        return {
@@ -293,7 +293,7 @@
        const shouldWaitArrivedDirection = deps.tripStatus === TripStatus.ArrivedDestination && !deps.arrivedMarkerReady;
        const effectiveShowCar = deps.statusRule.showCar && !shouldWaitArrivedDirection;
        const shouldUseAndroidDropoffOnly =
            deps.isAndroid && [TripStatus.VehicleArrivedPickup, TripStatus.InService].includes(deps.tripStatus);
            deps.isAndroid && deps.tripStatus === TripStatus.InService;
        const carMarker = createCarMarker();
        const nextMarkers: any[] = [];
        if (!shouldUseAndroidDropoffOnly && deps.statusRule.showPickup && pickupMarker) nextMarkers.push(pickupMarker);
src/robotaxi/pages/share-trip/hooks/use-map-viewport.ts
@@ -100,7 +100,6 @@
    const viewportKeyRef = useRef<string>("");
    const orderDetailSyncTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
    const completedOrderDetailViewportKeyRef = useRef<string>("");
    const arrivedPickupCenteredRef = useRef(false); // 到达上车点后仅回中一次,避免重复抖动
    const dynamicScaleHoldUntilRef = useRef(0);
    const lastActiveTripViewportSyncAtRef = useRef(0);
    const activeTripViewportSyncingRef = useRef(false);
@@ -257,6 +256,12 @@
            keyParts.push(pickupSite?.latitude, pickupSite?.longitude);
            return { points, keyParts };
        }
        if (viewportType === "pickup_center") {
            const pickupPoint = buildSiteViewportPoint(pickupSite);
            if (pickupPoint) points.push(pickupPoint);
            keyParts.push(pickupSite?.latitude, pickupSite?.longitude);
            return { points, keyParts };
        }
        if (viewportType === "route") {
            if (deps.routePoints.length > 0) points.push(...deps.routePoints);
            keyParts.push(buildPointsSignature(deps.routePoints));
@@ -322,6 +327,26 @@
                : [topPadding, 50, bottomPadding, 50];
        holdDynamicScale();
        Taro.nextTick(() => {
            if (viewportType === "pickup_center") {
                if (activeTripViewportSyncTimerRef.current) {
                    clearTimeout(activeTripViewportSyncTimerRef.current);
                    activeTripViewportSyncTimerRef.current = null;
                }
                mapCtx.moveToLocation({
                    latitude: points[0].latitude,
                    longitude: points[0].longitude
                });
                activeTripViewportSyncTimerRef.current = setTimeout(() => {
                    if (typeof deps.setLatitude === "function") {
                        deps.setLatitude(points[0].latitude);
                    }
                    if (typeof deps.setLongitude === "function") {
                        deps.setLongitude(points[0].longitude);
                    }
                    activeTripViewportSyncTimerRef.current = null;
                }, ACTIVE_TRIP_VIEWPORT_SYNC_ANIMATION_MS);
                return;
            }
            if (viewportType === "dropoff") {
                mapCtx.moveToLocation({
                    latitude: points[0].latitude,
@@ -461,6 +486,10 @@
        if (![TripStatus.VehicleApproaching, TripStatus.InService].includes(deps.tripStatus)) {
            lastActiveTripViewportSyncAtRef.current = 0;
            activeTripViewportSyncingRef.current = false;
            if (activeTripViewportSyncTimerRef.current) {
                clearTimeout(activeTripViewportSyncTimerRef.current);
                activeTripViewportSyncTimerRef.current = null;
            }
            return;
        }
        syncActiveTripViewportToVehicle();
@@ -469,66 +498,6 @@
        deps.vehicleLocation?.latitude,
        deps.vehicleLocation?.longitude,
        syncActiveTripViewportToVehicle
    ]);
    // 与 begin-route 保持一致:待上车时把车辆/上车点一次性回中到可用视区中央,
    // 并回写受控中心点,避免后续重渲染把地图拉回旧中心。
    useEffect(() => {
        if (deps.tripStatus !== TripStatus.VehicleArrivedPickup) {
            arrivedPickupCenteredRef.current = false;
            return;
        }
        const pickupLatitude = Number(deps.startSite?.latitude);
        const pickupLongitude = Number(deps.startSite?.longitude);
        if (!Number.isFinite(pickupLatitude) || !Number.isFinite(pickupLongitude)) {
            return;
        }
        if (arrivedPickupCenteredRef.current) {
            return;
        }
        arrivedPickupCenteredRef.current = true;
        holdDynamicScale();
        const moveAndCommitCenter = (centerLatitude: number, centerLongitude: number) => {
            Taro.createMapContext("map").moveToLocation({
                latitude: centerLatitude,
                longitude: centerLongitude
            });
            setTimeout(() => {
                deps.setLatitude?.(centerLatitude);
                deps.setLongitude?.(centerLongitude);
            }, ACTIVE_TRIP_VIEWPORT_SYNC_ANIMATION_MS);
        };
        Promise.all([ensureMapRect(), getMapRegion()])
            .then(([mapRect, region]) => {
                const safeAreaMetrics = buildActiveTripSafeAreaMetrics({
                    tripStatus: TripStatus.VehicleArrivedPickup,
                    mapHeight: Number(mapRect?.height),
                    bottomPadding: mapBottomPaddingRef.current,
                    safeTopInset: resolveSafeTopInset()
                });
                const pickupScreenPosition = computeMapPointScreenPosition(
                    { latitude: pickupLatitude, longitude: pickupLongitude },
                    mapRect,
                    region
                );
                const centerLatitude = (safeAreaMetrics && pickupScreenPosition)
                    ? pickupLatitude - (0.5 - safeAreaMetrics.targetMapRatio) * pickupScreenPosition.latitudeSpan
                    : pickupLatitude;
                moveAndCommitCenter(centerLatitude, pickupLongitude);
            })
            .catch(() => {
                moveAndCommitCenter(pickupLatitude, pickupLongitude);
            });
    }, [
        computeMapPointScreenPosition,
        deps.setLatitude,
        deps.setLongitude,
        deps.startSite?.latitude,
        deps.startSite?.longitude,
        deps.tripStatus,
        ensureMapRect,
        getMapRegion,
        holdDynamicScale
    ]);
    useEffect(() => {
src/robotaxi/pages/share-trip/hooks/use-share-trip-runtime.ts
@@ -350,7 +350,7 @@
    ]);
    // 路线态统一交给 includePoints 计算视口,避免先写一次几何中心,再被视口纠正,出现地图“先偏后回”的抖动。
    // 这里只保留无路线视口的轻量兜底。
    if (center && [TripStatus.Publishing, TripStatus.CallingCar, TripStatus.VehicleArrivedPickup].includes(mappedStatus)) {
    if (center && [TripStatus.Publishing, TripStatus.CallingCar].includes(mappedStatus)) {
      deps.setLongitude(center.longitude);
      deps.setLatitude(center.latitude);
    }
@@ -593,6 +593,16 @@
          stopPolling();
          return;
        }
        if ([TripStatus.TripFinished, TripStatus.PaymentSuccess].includes(infoState.mappedStatus)) {
          const routeResponse = unwrapSilentResponse(
            await requestShareRouteByStatus(infoState.mappedStatus)
          );
          if (cancelled) return;
          syncShareRoute(routeResponse, infoState.mappedStatus, infoState.nextStartSite, infoState.nextEndSite);
          stopPolling();
          errorToastShownRef.current = false;
          return;
        }
        const shouldContinuePolling = await fetchShareTripData();
        if (cancelled) return;
        if (shouldContinuePolling) {
src/robotaxi/pages/share-trip/index.tsx
@@ -69,7 +69,7 @@
    [TripStatus.Publishing]: { showPickup: true, showDropoff: false, showCar: false, showRoute: false, showWalking: false, viewport: 'pickup', translateCar: false },
    [TripStatus.CallingCar]: { showPickup: true, showDropoff: false, showCar: false, showRoute: false, showWalking: false, viewport: 'pickup', translateCar: false },
    [TripStatus.VehicleApproaching]: { showPickup: true, showDropoff: false, showCar: true, showRoute: true, showWalking: false, viewport: 'route', translateCar: true },
    [TripStatus.VehicleArrivedPickup]: { showPickup: true, showDropoff: false, showCar: true, showRoute: false, showWalking: false, viewport: 'car_user', translateCar: true },
    [TripStatus.VehicleArrivedPickup]: { showPickup: true, showDropoff: false, showCar: true, showRoute: false, showWalking: false, viewport: 'pickup_center', translateCar: true },
    [TripStatus.InService]: { showPickup: false, showDropoff: true, showCar: true, showRoute: true, showWalking: false, viewport: 'route', translateCar: true },
    [TripStatus.ArrivedDestination]: { showPickup: false, showDropoff: true, showCar: false, showRoute: true, showWalking: false, viewport: 'order_detail', translateCar: false },
    [TripStatus.TripFinished]: { showPickup: true, showDropoff: true, showCar: false, showRoute: true, showWalking: false, viewport: 'order_detail', translateCar: false },