liaof
2026-07-28 b707bfe62752da7478cab6899e58cbb437df3bc4
Merge branch 'feature_v2.4.0_ui_fuqj' into 'feature_v2.4.0_ui'

移除地图路线气泡,修改目的地地图气泡 (符启基)

See merge request robotaxi1/xp-robotaxi-miniprogram!184
2个文件已删除
9个文件已修改
581 ■■■■■ 已修改文件
src/robotaxi/pages/begin-route/components/auth-bluetooth-popup/index.less 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/auth-bluetooth-popup/success-auth/index.less 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/auth-bluetooth-popup/success-auth/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/route-summary-anchor.ts 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-android-overlays.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-map-markers.ts 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-preloaded-map-assets.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-route-summary-anchor-location.ts 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.less 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/auth-bluetooth-popup/index.less
@@ -1,3 +1,5 @@
@import url('../../../../style/ui-variables.less');
.auth-bluetooth-popup {
  position: fixed;
  top: 0;
@@ -20,17 +22,15 @@
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.4);
    background: rgba(0, 0, 0, 0.8);
    z-index: 1;
  }
  .popup-content {
    position: relative;
    z-index: 2;
    background: #FFFFFF;
    border-radius: 40px 40px 0 0;
    background: linear-gradient(180deg, #D9EBFF 0%, #FFFFFF 35%);
    border-radius: 40px 40px 0 0;
    background: @gary-theme;
    border-radius: 60px 60px 0 0;
    width: 100%;
    transform: translateY(100%);
    opacity: 1;
@@ -58,7 +58,7 @@
  .content-main {
    position: relative;
    z-index: 2;
    padding: 80px 58px 80px 40px;
    padding: 96px 48px;
    display: flex;
    flex-direction: column;
  }
@@ -67,33 +67,35 @@
    font-size: 36px;
    font-weight: 500;
    line-height: 52px;
    color: rgba(0, 0, 0, 0.9);
    color: @black-text-main;
  }
  .popup-sub-title {
    font-size: 36px;
    font-weight: 500;
    line-height: 52px;
    color: rgba(0, 0, 0, 0.9);
    color: @black-text-main;
  }
  .popup-desc {
    font-size: 28px;
    line-height: 44px;
    color: rgba(0, 0, 0, 0.6);
    color: @black-text-04;
  }
  .authorize-btn {
    margin-top: 82px;
    margin-top: 80px;
    width: 100%;
    height: 88px;
    margin-left: 18px;
    border-radius: 16px;
    background: linear-gradient(90deg, #7b79ff 0%, #68c0ff 100%);
    height: 106px;
    box-sizing: border-box;
    border-radius: 2000px;
    background: @black-text-main;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 28px;
    text-align: center;
    font-size: 32px;
    font-weight: 500;
    color: #ffffff;
  }
}
}
src/robotaxi/pages/begin-route/components/auth-bluetooth-popup/success-auth/index.less
@@ -1,3 +1,5 @@
@import url('../../../../../style/ui-variables.less');
.success-auth-popup {
  position: fixed;
  top: 0;
@@ -20,7 +22,7 @@
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.4);
    background: rgba(0, 0, 0, 0.8);
    z-index: 1;
  }
@@ -28,19 +30,19 @@
    position: relative;
    z-index: 2;
    width: 100%;
    background: linear-gradient(180deg, #D9EBFF 0%, #FFFFFF 35%);
    border-radius: 40px 40px 0 0;
    background: @gary-theme;
    border-radius: 60px 60px 0 0;
    transform: translateY(100%);
    opacity: 1;
    padding: 58px 134px 80px 140px;
    padding: 96px 120px;
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  .popup-icon {
    width: 148px;
    height: 148px;
    width: 144px;
    height: 144px;
  }
  .popup-title {
@@ -48,7 +50,7 @@
    font-size: 34px;
    font-weight: 500;
    line-height: 52px;
    color: rgba(0, 0, 0, 0.9);
    color: @black-text-main;
    letter-spacing: normal;
  }
@@ -56,20 +58,21 @@
    margin-top: 4px;
    font-size: 24px;
    line-height: 36px;
    color: rgba(0, 0, 0, 0.6);
    color: @black-text-04;
    text-align: center;
  }
  .popup-confirm-btn {
    margin-top: 66px;
    width: 100%;
    height: 88px;
    border-radius: 16px;
    border: 2px solid rgba(0, 0, 0, 1);
    height: 106px;
    border-radius: 2000px;
    border: 4px solid @black-text-main;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 28px;
    color: rgba(0, 0, 0, 0.9);
    font-size: 32px;
    font-weight: 500;
    color: @black-text-main;
  }
}
}
src/robotaxi/pages/begin-route/components/auth-bluetooth-popup/success-auth/index.tsx
@@ -22,7 +22,7 @@
    <View className={`success-auth-popup ${show ? 'show' : ''}`} catchMove>
      <View className='popup-mask' onClick={onClose}></View>
      <View className='popup-content' animation={animationData}>
        <Image className='popup-icon' src={'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/bluetooth-success-auth.png'} />
        <Image className='popup-icon' src={'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/bluetooth-popup-icon-20260726.png'} />
        <Text className='popup-title'>已授权蓝牙,无感自动解锁车门</Text>
        <Text className='popup-desc'>授权并打开蓝牙连接,手机靠近车辆即可自动解锁车门</Text>
        <View className='popup-confirm-btn' onClick={handleConfirm}>
src/robotaxi/pages/begin-route/hooks/route-summary-anchor.ts
File was deleted
src/robotaxi/pages/begin-route/hooks/use-android-overlays.ts
@@ -9,7 +9,6 @@
  mapScale: number;
  /** 修改目的地预览态下隐藏车辆气泡。 */
  isModifyDestinationReviewVisible: boolean;
  routeSummaryLocation: { latitude: number; longitude: number } | null;
  startSite: any;
  endSite: any;
  vehicleLocation: { latitude: number; longitude: number } | null;
@@ -38,9 +37,6 @@
  // 到达气泡样式与显示状态
  const [arriveCalloutStyle, setArriveCalloutStyle] = useState<any>({});
  const [arriveCalloutVisible, setArriveCalloutVisible] = useState(false);
  // 路线摘要气泡样式与显示状态
  const [routeSummaryCalloutStyle, setRouteSummaryCalloutStyle] = useState<any>({});
  const [routeSummaryCalloutVisible, setRouteSummaryCalloutVisible] = useState(false);
  const mapRectRef = useRef<any>(null);
  // 读取地图投影上下文,供路线点批量转换屏幕坐标使用。
@@ -181,25 +177,6 @@
    setArriveCalloutVisible(true);
  };
  // 更新路线摘要气泡位置
  const updateRouteSummaryCalloutPosition = async () => {
    if (!deps.isAndroid || !deps.routeSummaryLocation) {
      setRouteSummaryCalloutVisible(false);
      return;
    }
    const rect = await ensureMapRect();
    const pos = await computeScreenPosition(deps.routeSummaryLocation, rect, 0);
    if (!pos) {
      setRouteSummaryCalloutVisible(false);
      return;
    }
    setRouteSummaryCalloutStyle(buildTransformOverlayStyle({
      x: pos.x,
      y: pos.y
    }, ''));
    setRouteSummaryCalloutVisible(true);
  };
  // 地图区域变化时同步覆盖物显隐与重算
  // 注意:这里把「begin 隐藏」与「end 重算」解耦,避免历史上的两类问题:
  // 1) 若 begin 对所有区域变化都隐藏,则 fitRouteIntoView/includePoints 等程序化视口调整会
@@ -219,7 +196,6 @@
        setWaitingRadarVisible(false);
        setCarCalloutVisible(false);
        setArriveCalloutVisible(false);
        setRouteSummaryCalloutVisible(false);
      }
      return;
    }
@@ -230,7 +206,6 @@
      updateWaitingRadarPosition();
      updateCarCalloutPosition();
      updateArriveCalloutPosition();
      updateRouteSummaryCalloutPosition();
    }
  };
@@ -256,10 +231,6 @@
  }, [deps.isAndroid, deps.tripStatus, deps.endSite?.latitude, deps.endSite?.longitude]);
  useEffect(() => {
    updateRouteSummaryCalloutPosition();
  }, [deps.isAndroid, deps.routeSummaryLocation?.latitude, deps.routeSummaryLocation?.longitude, deps.mapScale, deps.tripStatus]);
  useEffect(() => {
    if (!deps.isAndroid || deps.tripStatus !== TripStatus.ArrivedDestination) return;
    if (deps.mapScale < 20) return;
    const timer = setTimeout(() => {
@@ -275,12 +246,9 @@
    carCalloutVisible,
    arriveCalloutStyle,
    arriveCalloutVisible,
    routeSummaryCalloutStyle,
    routeSummaryCalloutVisible,
    updateWaitingRadarPosition,
    updateCarCalloutPosition,
    updateArriveCalloutPosition,
    updateRouteSummaryCalloutPosition,
    handleRegionChange
  };
}
src/robotaxi/pages/begin-route/hooks/use-map-markers.ts
@@ -197,8 +197,9 @@
    useAndroidNativeTrip1Callout: boolean
  ) => {
    if (!(pickupSite?.latitude && pickupSite?.longitude)) return null;
    const shouldUseChangePickupIcon = deps.isModifyDestinationReviewVisible && deps.tripStatus >= TripStatus.VehicleArrivedPickup; // 修改目的地确认态且进入行程阶段时使用换点上车图标
    const shouldHidePickupName = deps.tripStatus === TripStatus.InService && deps.isModifyDestinationReviewVisible; // 行程中修改目的地时只展示换点图标,不展示上车点名称
    // 修改目的地预览:起点改为 up-triangle 三角图标 + 名称显示在图标下方,不再用换点图标、不隐藏名称
    const shouldUseChangePickupIcon = false;
    const shouldHidePickupName = false;
    // 接驾态(前往上车点):上车点改用三角图标,名称移到图标下方,浮窗展示车图标+限停时间;
    // 待支付/完成态:上车点同样三角图标,浮窗展示 end-site 图片,名称移到图标左侧。
    const isPickupApproaching =
@@ -208,7 +209,9 @@
    const isPickupSettled =
      [TripStatus.TripFinished, TripStatus.PaymentSuccess].includes(deps.tripStatus) &&
      !shouldUseChangePickupIcon;
    const isPickupTriangle = isPickupApproaching || isPickupArrived || isPickupSettled;
    // 修改目的地预览:起点(上车点)统一用三角图标 up-triangle + 名称显示在图标下方
    const isPickupModifyPreview = deps.isModifyDestinationReviewVisible;
    const isPickupTriangle = isPickupApproaching || isPickupArrived || isPickupSettled || isPickupModifyPreview;
    // 名称在图标下方:接驾态 11px,到达/待支付/完成态 22px
    const pickupNameLabelConfig = isPickupApproaching
      ? SITE_NAME_LABEL_BASE
@@ -231,7 +234,7 @@
      anchor: { x: 0.5, y: 1 },
      zIndex: 1,
      name: pickupName,
      hideNameCallout: deps.isModifyDestinationReviewVisible || shouldHidePickupName, // 修改目的地确认态隐藏上车点名称气泡
      hideNameCallout: shouldHidePickupName, // 名称通过图标下方 label 展示;修改态的名称气泡/限停/倒计时由各气泡分支单独控制
      // 三角态在图标下方展示站点名称
      ...(isPickupTriangle && !shouldHidePickupName
        ? { label: { content: pickupName, ...pickupNameLabelConfig } }
@@ -305,7 +308,8 @@
      zIndex: 1,
      name: dropoffName,
      // 三角态在图标下方展示目的地名称:送驾态 11px、待支付/完成态 22px
      ...(isDropoffTriangle
      // 修改目的地预览态下,站点名已在黑色浮窗(endpoint-summary)展示,隐藏图标下方的重复名称
      ...(isDropoffTriangle && !deps.isModifyDestinationReviewVisible
        ? {
            label: {
              content: dropoffName,
src/robotaxi/pages/begin-route/hooks/use-preloaded-map-assets.ts
@@ -10,8 +10,6 @@
  waitingCalloutBgUrl: string;
  /** 等待态雷达图地址。 */
  waitingRadarUrl: string;
  /** 路线概览气泡背景图地址。 */
  routeSummaryBgUrl: string;
};
/** Hook 入参。 */
@@ -30,8 +28,6 @@
  waitingCalloutBgSrc: string;
  /** 等待态雷达图本地地址。 */
  waitingRadarSrc: string;
  /** 路线概览气泡背景图本地地址。 */
  routeSummaryBgSrc: string;
};
/**
@@ -41,7 +37,6 @@
  const [customCalloutIconSrc, setCustomCalloutIconSrc] = useState(params.assetUrls.customCalloutIconUrl); // 自定义气泡箭头图本地地址
  const [waitingCalloutBgSrc, setWaitingCalloutBgSrc] = useState(params.assetUrls.waitingCalloutBgUrl); // 等待态气泡背景图本地地址
  const [waitingRadarSrc, setWaitingRadarSrc] = useState(params.assetUrls.waitingRadarUrl); // 等待态雷达图本地地址
  const [routeSummaryBgSrc, setRouteSummaryBgSrc] = useState(params.assetUrls.routeSummaryBgUrl); // 路线概览气泡背景图本地地址
  /**
   * 预加载单张图片并在组件仍挂载时回写结果。
@@ -56,11 +51,10 @@
  useEffect(() => {
    const cancelledRef = { current: false };
    preloadSingleAsset(params.assetUrls.customCalloutIconUrl, setCustomCalloutIconSrc, cancelledRef);
    preloadSingleAsset(params.assetUrls.routeSummaryBgUrl, setRouteSummaryBgSrc, cancelledRef);
    return () => {
      cancelledRef.current = true;
    };
  }, [params.assetUrls.customCalloutIconUrl, params.assetUrls.routeSummaryBgUrl]);
  }, [params.assetUrls.customCalloutIconUrl]);
  useEffect(() => {
    if (![TripStatus.Publishing, TripStatus.CallingCar].includes(params.tripStatus)) {
@@ -77,7 +71,6 @@
  return {
    customCalloutIconSrc,
    waitingCalloutBgSrc,
    waitingRadarSrc,
    routeSummaryBgSrc
    waitingRadarSrc
  };
}
src/robotaxi/pages/begin-route/hooks/use-route-summary-anchor-location.ts
File was deleted
src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx
@@ -43,10 +43,6 @@
  arriveCalloutVisible: boolean;
  /** 到达气泡样式 */
  arriveCalloutStyle: any;
  /** 路线摘要气泡可见 */
  routeSummaryCalloutVisible: boolean;
  /** 路线摘要气泡样式 */
  routeSummaryCalloutStyle: any;
  /** 到达态气泡渲染就绪(角度与缩放均就绪) */
  arrivedTooltipReady: boolean;
  /** 路线距离 */
@@ -59,8 +55,6 @@
  hasPreviousOrder: boolean;
  /** 自定义气泡图标 */
  customCalloutIconSrc: string;
  /** 路线概览气泡背景图 */
  routeSummaryBgSrc: string;
  /** 是否使用下单前端点气泡样式 */
  showTrip1StyleEndpoint: boolean;
  /** 上车点 */
@@ -307,15 +301,6 @@
  /** 修改目的地预览态和接驾态切路线期间隐藏车辆公里/分钟气泡。 */
  const shouldShowVehicleMetricCallout =
    !deps.isModifyDestinationReviewVisible && !deps.isPickupRouteChangeVisible;
  const routeSummaryText = useMemo(
    () =>
      deps.routeDistance && deps.routeDuration !== null
        ? `${vehicleMetricDurationDisplay.value}${vehicleMetricDurationDisplay.unit
        } ${deps.routeDistance.value}${deps.routeDistance.unit === "m" ? "米" : "公里"
        }`
        : "",
    [deps.routeDistance, deps.routeDuration, vehicleMetricDurationDisplay]
  );
  const shouldHideAndroidMarkerCallout =
    deps.isAndroid &&
    ([
@@ -453,22 +438,7 @@
        }
        style={item.id === 1 ? calloutRepaintStyle : undefined}
      >
        {item.isRouteSummaryBubble ? (
          routeSummaryText ? (
            // 路由摘要气泡
            <CoverView className="route-summary-callout">
              <CoverImage
                className="route-summary-callout-bg"
                src={deps.routeSummaryBgSrc}
              />
              <CoverView className="route-summary-callout-text">
                {routeSummaryText}
                {/* 占位 */}
                <CoverView style={{ color: "transparent" }}>占</CoverView>
              </CoverView>
            </CoverView>
          ) : null
        ) : item.isBeforeUserSite ? (
        {item.isBeforeUserSite ? (
          <CoverView className="before-user-site-callout">
            <CoverView className="before-user-site-txt">上一站终点</CoverView>
          </CoverView>
@@ -507,6 +477,10 @@
                  TripStatus.TripFinished,
                  TripStatus.PaymentSuccess
                ].includes(deps.tripStatus)
              ) &&
              !(
                (item.id === 1 || item.id === 2) &&
                deps.isModifyDestinationReviewVisible
              ) &&
              !item.hideNameCallout && (
                <>
@@ -602,7 +576,7 @@
                </>
              )}
            {item.id === 2 &&
              deps.tripStatus === TripStatus.PublishRoute &&
              (deps.tripStatus === TripStatus.PublishRoute || deps.isModifyDestinationReviewVisible) &&
              !!deps.routeDistance &&
              deps.routeDuration !== null &&
              !item.hideNameCallout && (
@@ -641,10 +615,12 @@
                      </CoverView>
                    </CoverView>
                  </CoverView>
                  <CoverImage
                    className="endpoint-summary-icon"
                    src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/map-white-arrow-20260708.png"
                  />
                  {!deps.isModifyDestinationReviewVisible && (
                    <CoverImage
                      className="endpoint-summary-icon"
                      src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/map-white-arrow-20260708.png"
                    />
                  )}
                </CoverView>
                <CoverImage
                  className="callout-diamond-icon"
@@ -654,6 +630,7 @@
              )}
            {item.id === 1 &&
              deps.tripStatus === TripStatus.VehicleApproaching &&
              !deps.isModifyDestinationReviewVisible &&
              !item.hideNameCallout && (
                <>
                <CoverView
@@ -676,6 +653,7 @@
              )}
            {item.id === 1 &&
              deps.tripStatus === TripStatus.VehicleArrivedPickup &&
              !deps.isModifyDestinationReviewVisible &&
              !item.hideNameCallout &&
              Number(pickupCountdownSeconds) > 0 && (
                <CoverView
@@ -692,9 +670,9 @@
                </CoverView>
              )}
            {item.id === 1 &&
              [TripStatus.TripFinished, TripStatus.PaymentSuccess].includes(
              ([TripStatus.TripFinished, TripStatus.PaymentSuccess].includes(
                deps.tripStatus
              ) &&
              ) || deps.isModifyDestinationReviewVisible) &&
              !item.hideNameCallout && (
                <CoverImage
                  className="site-status-end-img"
@@ -707,6 +685,7 @@
                TripStatus.TripFinished,
                TripStatus.PaymentSuccess
              ].includes(deps.tripStatus) &&
              !deps.isModifyDestinationReviewVisible &&
              !item.hideNameCallout && (
                <CoverImage
                  className="site-status-end-img"
@@ -759,12 +738,10 @@
      deps.isModifyDestinationReviewVisible,
      deps.routeDistance,
      deps.routeDuration,
      deps.routeSummaryBgSrc,
      deps.showTrip1StyleEndpoint,
      deps.tripStatus,
      deps.startSite?.time,
      pickupCountdownSeconds,
      routeSummaryText,
      vehicleMetricDurationDisplay,
      shouldShowVehicleMetricCallout,
      calloutRepaintStyle
@@ -776,13 +753,6 @@
   */
  const renderMarkerCallout = useCallback((item: any, index: number) => {
    const calloutKey = `callout-${item.id}-${item.name || ''}`;
    // 路线摘要气泡需跨平台强制显示,避免被 Android 普通气泡隐藏规则误伤
    if (item.isRouteSummaryBubble) {
      if (deps.isAndroid) return null;
      // iOS 发布路线态:路程/时间已合并进终点浮窗,避免与终点气泡重复展示
      if (deps.tripStatus === TripStatus.PublishRoute) return null;
      return renderDefaultCallout(item, calloutKey);
    }
    // 待支付/完成态的上/下车点浮窗为富内容(end-site 图片),需走 cover-view,不能被 Android 常规隐藏规则误伤
    const isSettledSiteMarker =
      (item.id === 1 || item.id === 2) &&
@@ -815,20 +785,6 @@
            style={deps.waitingRadarStyle}
          />
        )}
        {deps.isAndroid && deps.routeSummaryCalloutVisible && routeSummaryText && (
          <View
            className="route-summary-callout"
            style={deps.routeSummaryCalloutStyle}
          >
            <Image
              className="route-summary-callout-bg"
              src={deps.routeSummaryBgSrc}
            />
            <View className="route-summary-callout-text">
              {routeSummaryText}
            </View>
          </View>
        )}
        {deps.isAndroid && deps.carCalloutVisible && shouldShowVehicleMetricCallout && (
          <View className="car-callout-android" style={deps.carCalloutStyle}>
            {androidCarCalloutContent}
@@ -854,15 +810,11 @@
    deps.isModifyDestinationReviewVisible,
    deps.markers,
    deps.routeDistance,
    deps.routeSummaryBgSrc,
    deps.routeSummaryCalloutStyle,
    deps.routeSummaryCalloutVisible,
    deps.shouldShowWaitingRadar,
    deps.waitingRadarSrc,
    deps.waitingRadarStyle,
    deps.waitingRadarVisible,
    renderMarkerCallout,
    routeSummaryText,
    shouldShowVehicleMetricCallout,
    vehicleMetricDurationDisplay
  ]);
src/robotaxi/pages/begin-route/index.less
@@ -355,38 +355,6 @@
    padding-right: 20px;
}
.route-summary-callout {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 169px;
    height: 45px;
    padding-left: 15px;
    padding-right: 4px;
    box-sizing: border-box;
}
.route-summary-callout-bg {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
}
.route-summary-callout-text {
    position: relative;
    z-index: 2;
    font-size: 20px;
    font-weight: 500;
    line-height: 39px;
    color: #FFFFFF;
    white-space: nowrap;
    text-align: center;
    display: flex;
}
.txt-center {
    text-align: center;
}
src/robotaxi/pages/begin-route/index.tsx
@@ -25,7 +25,6 @@
import useSmoothRouteMotion from './hooks/use-smooth-route-motion';
// Android 覆盖物状态管理
import useAndroidOverlays from './hooks/use-android-overlays';
import useRouteSummaryAnchorLocation from './hooks/use-route-summary-anchor-location';
// 地图视口状态管理
import useMapViewport from './hooks/use-map-viewport';
import useActiveTripScale from './hooks/use-active-trip-scale';
@@ -89,7 +88,6 @@
import { withToast } from '../../components/toast/with-toast';
import type { PickupExceptionInfo } from './pickup-exception';
const ROUTE_SUMMARY_MARKER_ID = 999001;
const MODIFY_DESTINATION_PICKUP_STATUS_GUARD_MS = 5000;
const COUPON_POPUP_CLOSE_VIEWPORT_REFRESH_DELAY_MS = 320; // 优惠券弹窗退场动画结束后,再刷新完成态视口
const ROUTE_SELECTABLE_TRIP_STATUSES = [TripStatus.PublishRoute, TripStatus.VehicleApproaching] as const; // 允许展示并切换候选路线的行程状态
@@ -298,7 +296,6 @@
  const customCalloutIconUrl = 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/maker-tooltip-right.png'; // 自定义气泡图标URL
  const waitingCalloutBgUrl = 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/tooltip-bg-20260715.png'; // 等待气泡背景图URL
  const waitingRadarUrl = 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/waiting-radar.webp'; // 等待雷达动画图URL
  const routeSummaryBgUrl = 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/summary-icon.png'; // 路线概览气泡背景图URL
  const [isRouteSelectExpanded, setIsRouteSelectExpanded] = useState(false); // 路线选择展开状态
  const [isPickupRouteChangeVisible, setIsPickupRouteChangeVisible] = useState(false); // 接驾态路线切换卡片展示状态
  const [isConfirmingPickupRouteChange, setIsConfirmingPickupRouteChange] = useState(false); // 接驾态确认切换路线提交中
@@ -411,15 +408,13 @@
  const vehicleMarkerId = !isAndroid && tripStatus === TripStatus.InService ? 30 : 3; // 车辆标记 ID,iOS 行驶中阶段使用不同 ID
  const {
    customCalloutIconSrc,
    waitingRadarSrc,
    routeSummaryBgSrc
    waitingRadarSrc
  } = usePreloadedMapAssets({
    tripStatus,
    assetUrls: {
      customCalloutIconUrl,
      waitingCalloutBgUrl,
      waitingRadarUrl,
      routeSummaryBgUrl
      waitingRadarUrl
    }
  }); // 地图气泡资源预加载
  const {
@@ -593,7 +588,7 @@
      const isTripBeforePickupArrived = [TripStatus.Publishing, TripStatus.CallingCar, TripStatus.VehicleApproaching].includes(tripStatus); // 车辆未到达上车点前视为“行程未开始”
      return {
        ...baseRule,
        showPickup: baseRule.showPickup, // 行程中(车辆已过上车点)即使在修改目的地态也不展示上车点,沿用基础规则
        showPickup: isModifyDestinationReviewVisible ? true : baseRule.showPickup, // 修改目的地预览强制展示起点(上车点)
        // 预览态强制展示下车点;确认修改后(本地覆盖态)回退至基础规则,避免接驾态错误渲染目的地,且不影响送驾态的正常显示
        showDropoff: isModifyDestinationReviewVisible ? true : baseRule.showDropoff,
        showCar: !isTripBeforePickupArrived && baseRule.showCar,
@@ -626,7 +621,6 @@
    || (tripStatus === TripStatus.VehicleApproaching
      ? isPickupRouteChangeVisible
      : ROUTE_SELECTABLE_TRIP_STATUSES.includes(tripStatus)); // 接驾态仅在展示路线切换卡片时展示多条候选路线
  const shouldShowRouteSummaryBubble = allowSelectableRoutes; // 路线概览气泡与多路线展示条件保持一致
  const showTrip1StyleEndpoint = isModifyDestinationReviewVisible || hasLocalDestinationOverride || isPickupRouteChangeMapMode;
  const vehicleState = useVehicleTracking({
    statusRule: effectiveStatusRule,
@@ -974,45 +968,6 @@
    resetRouteRuntimeState();
  };
  const displayPolyline = polyline;
  const routeSummaryBaseLocation = useMemo(() => {
    if (!shouldShowRouteSummaryBubble || !routeDistance || routeDuration === null || !Array.isArray(routePoints) || routePoints.length === 0) {
      return null;
    }
    const midpoint = routePoints[Math.max(0, Math.floor(routePoints.length / 2))];
    if (!midpoint?.latitude || !midpoint?.longitude) {
      return null;
    }
    return {
      latitude: midpoint.latitude,
      longitude: midpoint.longitude
    };
  }, [routeDistance, routeDuration, routePoints, shouldShowRouteSummaryBubble]);
  const {
    routeSummaryAnchorLocation,
    handleRegionChange: handleRouteSummaryRegionChange
  } = useRouteSummaryAnchorLocation({
    enabled: shouldShowRouteSummaryBubble && !!routeDistance && routeDuration !== null,
    routeSummaryLocation: routeSummaryBaseLocation,
    routePoints
  });
  const routeSummaryMarker = useMemo(() => {
    const summaryLocation = routeSummaryAnchorLocation || routeSummaryBaseLocation;
    if (!summaryLocation?.latitude || !summaryLocation?.longitude) {
      return null;
    }
    return {
      id: ROUTE_SUMMARY_MARKER_ID,
      latitude: summaryLocation.latitude,
      longitude: summaryLocation.longitude,
      iconPath: 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/marker-car-v2.png',
      width: 1,
      height: 1,
      alpha: 0,
      zIndex: 0,
      isRouteSummaryBubble: true,
      customCallout: { anchorY: 22, anchorX: 42, display: 'ALWAYS' }
    };
  }, [routeSummaryAnchorLocation, routeSummaryBaseLocation]);
  const viewportState = useMapViewport({
    tripStatus: mapPresentationTripStatus,
    statusRule: effectiveStatusRule,
@@ -1096,8 +1051,6 @@
    carCalloutVisible,
    arriveCalloutStyle,
    arriveCalloutVisible,
    routeSummaryCalloutStyle,
    routeSummaryCalloutVisible,
    handleRegionChange: handleAndroidOverlayRegionChange
  } = useAndroidOverlays({
    shouldShowWaitingRadar,
@@ -1105,7 +1058,6 @@
    tripStatus: mapPresentationTripStatus,
    mapScale,
    isModifyDestinationReviewVisible,
    routeSummaryLocation: routeSummaryAnchorLocation || routeSummaryBaseLocation,
    startSite,
    endSite: effectiveEndSite,
    vehicleLocation,
@@ -1115,10 +1067,6 @@
    longitude,
    latitude
  }); // Android 覆盖物状态编排
  const markersWithRouteSummary = useMemo(() => {
    if (!routeSummaryMarker) return markers;
    return [...markers, routeSummaryMarker];
  }, [markers, routeSummaryMarker]);
  const hasValidBeforeUserEndSite = useMemo(() => (
    Number.isFinite(Number(beforeUserEndSite?.latitude))
    && Number.isFinite(Number(beforeUserEndSite?.longitude))
@@ -1743,7 +1691,6 @@
      return;
    }
    activeTripScale.handleRegionChange(e);
    handleRouteSummaryRegionChange(e);
    handleAndroidOverlayRegionChange(e);
    // 用户手势导致的缩放/拖拽结束后,把原生地图的实际 scale 同步回 React 状态,
@@ -2107,7 +2054,7 @@
    isAndroid,
    tripStatus,
    mapScale,
    markers: markersWithRouteSummary,
    markers: markers,
    isRouteSelectExpanded,
    isPickupRouteChangeVisible,
    isConfirmingPickupRouteChange,
@@ -2122,15 +2069,12 @@
    carCalloutStyle,
    arriveCalloutVisible,
    arriveCalloutStyle,
    routeSummaryCalloutVisible,
    routeSummaryCalloutStyle,
    arrivedTooltipReady,
    routeDistance,
    routeDuration,
    hasBeforeUserEndSite: hasValidBeforeUserEndSite,
    hasPreviousOrder,
    customCalloutIconSrc,
    routeSummaryBgSrc,
    showTrip1StyleEndpoint,
    startSite,
    elapsedSeconds,
@@ -2265,7 +2209,7 @@
    mapLongitude,
    mapLatitude,
    mapScale: mapScaleRef.current ?? mapScale,
    markers: markersWithRouteSummary,
    markers: markers,
    polyline: displayPolyline,
    showLocation: !!longitude && showLocationFlag,
    handleCalloutTap,