zjk
2026-06-06 be46a8f6870b6bd505f8d1a4cbc554ae4184d1df
feat(begin-route): 适配车辆朝向和预终点优化地图气泡布局

- 新增基于车辆行驶方向的气泡偏移计算逻辑
- 为预终点场景添加额外偏移避免遮挡车辆
- 修复代码格式问题,优化Android覆盖物计算
- 同步传递业务参数并调整支付hook注释格式
4个文件已修改
90 ■■■■■ 已修改文件
src/robotaxi/pages/begin-route/hooks/use-android-overlays.ts 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-map-markers.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-order-payment.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-android-overlays.ts
@@ -13,8 +13,58 @@
  startSite: any;
  endSite: any;
  vehicleLocation: { latitude: number; longitude: number } | null;
  vehicleDirection?: number;
  hasBeforeUserEndSite?: boolean;
  longitude: number | null;
  latitude: number | null;
};
type AndroidCarCalloutPlacement = {
  offsetX: number;
  offsetY: number;
  anchorTransform: string;
};
/**
 * Android 车辆气泡走固定 overlay,需要单独根据朝向计算“车辆后方”偏移。
 */
const resolveAndroidCarCalloutPlacement = (vehicleDirection?: number, hasBeforeUserEndSite?: boolean): AndroidCarCalloutPlacement => {
  const verticalExtraOffset = hasBeforeUserEndSite ? 18 : 0;
  const horizontalExtraOffset = hasBeforeUserEndSite ? 12 : 0;
  const normalizedDirection = typeof vehicleDirection === 'number'
    ? ((vehicleDirection % 360) + 360) % 360
    : 0;
  if (normalizedDirection >= 45 && normalizedDirection < 135) {
    // 向东行驶,后方在左侧。
    return {
      offsetX: -(28 + horizontalExtraOffset),
      offsetY: 0,
      anchorTransform: 'translate(calc(-100% - 6px), -50%)'
    };
  }
  if (normalizedDirection >= 135 && normalizedDirection < 225) {
    // 向南行驶,后方在上方。
    return {
      offsetX: 0,
      offsetY: -(28 + verticalExtraOffset),
      anchorTransform: 'translate(-50%, calc(-100% - 6px))'
    };
  }
  if (normalizedDirection >= 225 && normalizedDirection < 315) {
    // 向西行驶,后方在右侧。
    return {
      offsetX: 28 + horizontalExtraOffset,
      offsetY: 0,
      anchorTransform: 'translate(6px, -50%)'
    };
  }
  // 向北行驶,后方在下方。
  return {
    offsetX: 0,
    offsetY: 34 + verticalExtraOffset,
    anchorTransform: 'translate(-50%, 6px)'
  };
};
export default function useAndroidOverlays(deps: Deps) {
@@ -105,9 +155,13 @@
      return;
    }
    const rect = await ensureMapRect();
    const pos = await computeScreenPosition(deps.vehicleLocation, rect, 60);
    const pos = await computeScreenPosition(deps.vehicleLocation, rect, 0);
    if (!pos) return;
    setCarCalloutStyle(buildTransformOverlayStyle(pos, 'translate(-50%, -120%)'));
    const placement = resolveAndroidCarCalloutPlacement(deps.vehicleDirection, deps.hasBeforeUserEndSite);
    setCarCalloutStyle(buildTransformOverlayStyle({
      x: pos.x + placement.offsetX,
      y: pos.y + placement.offsetY
    }, placement.anchorTransform));
    setCarCalloutVisible(true);
  };
@@ -179,7 +233,15 @@
  useEffect(() => {
    updateCarCalloutPosition();
  }, [deps.isAndroid, deps.isModifyDestinationReviewVisible, deps.vehicleLocation?.latitude, deps.vehicleLocation?.longitude, deps.tripStatus]);
  }, [
    deps.hasBeforeUserEndSite,
    deps.isAndroid,
    deps.isModifyDestinationReviewVisible,
    deps.tripStatus,
    deps.vehicleDirection,
    deps.vehicleLocation?.latitude,
    deps.vehicleLocation?.longitude
  ]);
  useEffect(() => {
    updateArriveCalloutPosition();
src/robotaxi/pages/begin-route/hooks/use-map-markers.ts
@@ -180,15 +180,15 @@
    // 车辆图标高 40,宽 20。普通气泡高约 40,连环派单气泡更高。
    // anchorY/anchorX 的基准是基于 marker 自身的坐标点 (0, 0)
    let anchorY = 80 + verticalExtraOffset; // 默认向北行驶,气泡放在正下方
    let anchorY = 80 + verticalExtraOffset ; // 默认向北行驶,气泡放在正下方
    let anchorX = 0;
    if (typeof deps.vehicleDirection === 'number') {
      const normalizedDirection = ((deps.vehicleDirection % 360) + 360) % 360;
      if (normalizedDirection >= 45 && normalizedDirection < 135) {
        // 向东行驶,后方为西(左侧)
        // 连环派单气泡更高,左侧场景同步增加一点垂直与水平避让,防止左上角压住车身。
        anchorY = 20 + Math.round(verticalExtraOffset / 2);
        anchorX = -(85 + horizontalExtraOffset);
        anchorY = 20 + Math.round(verticalExtraOffset / 2)
        anchorX = -(85 + horizontalExtraOffset );
      } else if (normalizedDirection >= 135 && normalizedDirection < 225) {
        // 向南行驶,后方为北(上方)
        // 连环派单气泡更高,需要继续上移,避免底部压住车辆图标。
@@ -197,8 +197,8 @@
      } else if (normalizedDirection >= 225 && normalizedDirection < 315) {
        // 向西行驶,后方为东(右侧)
        // 连环派单气泡更高,右侧场景同步增加一点垂直与水平避让,防止右上角压住车身。
        anchorY = 20 + Math.round(verticalExtraOffset / 2);
        anchorX = 85 + horizontalExtraOffset;
        anchorY = 20 + Math.round(verticalExtraOffset / 2)
        anchorX = 85 + horizontalExtraOffset
      }
    }
src/robotaxi/pages/begin-route/hooks/use-order-payment.ts
@@ -6,7 +6,7 @@
  getOrderPayment
} from '../../../api/begin-route';
import { getOrderDetail } from '../../../api/order';
// import { RobotaxiPaymentEntryStatus, SignedOrderPaymentValue } from '../../../api/types/begin-route';
import { RobotaxiPaymentEntryStatus, SignedOrderPaymentValue } from '../../../api/types/begin-route';
import { getOrderDistance } from '../../../api/select-map-site';
import { getOrderId } from '../../../utils/order';
import { createTripInProgressCompleteTripReportPayload } from '../constants/confirm-ride-report';
@@ -185,10 +185,10 @@
    }
    paySubmittingRef.current = true;
    try {
      await getOrderPayment({ orderId: targetOrderId });
      syncPaymentSuccessStatus();
      // await getOrderPayment({ orderId: targetOrderId });
      // syncPaymentSuccessStatus();
      /*
      const paymentResult = await getOrderPayment({ orderId: targetOrderId });
      const paymentStatus = Number(paymentResult?.status);
@@ -213,7 +213,7 @@
      }
      Taro.showToast({ title: '暂不支持当前支付方式', icon: 'none' });
      */
    } catch (error) {
      Taro.showToast({ title: '支付失败,请重试', icon: 'none' });
    } finally {
src/robotaxi/pages/begin-route/index.tsx
@@ -669,6 +669,8 @@
    startSite,
    endSite: effectiveEndSite,
    vehicleLocation,
    vehicleDirection,
    hasBeforeUserEndSite: hasValidBeforeUserEndSite,
    longitude,
    latitude
  }); // Android 覆盖物状态编排