liaof
2026-07-28 259e212d69d095675ed4d6959d1d69559e66fff8
Revert "feat: 合并feature_v2.4.0 带支付功能"

This reverts commit 1c5bffb67c6deb4c3b957a153e2ea1c80671bb73
2个文件已删除
39个文件已修改
1359 ■■■■■ 已修改文件
src/pages/robotaxi/home/components/marketing-popup/index.less 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/components/marketing-popup/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/hooks/use-marketing.ts 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/index.less 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/api/begin-route.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/api/home.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/api/payment.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/api/types/begin-route.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/calling-car-modules/fare-detail-card.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/calling-car.less 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/cancel-popup.less 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/evaluate-popup.less 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/fragrance-control.less 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/passenger-notice.less 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/release-be-being.less 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/release-route.less 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/temperature-control.less 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/wechat-pay-score-loading.less 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/release-be-being.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/wechat-pay-score-loading.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-credit-pay-return.ts 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-order-actions.shared.ts 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-order-cancel.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-order-payment.ts 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-order-submit.ts 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-page-actions.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-web-socket-events.ts 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/web-socket-handlers/create-order-status-socket-handler.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.less 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.tsx 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/operating-area/index.less 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/operating-area/index.tsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/order/index.tsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/passenger-notice/index.tsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/payment-setting-detail/index.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/personal-center/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/select-map-site/index.less 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/index.less 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/site-search/index.less 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/utils/login-agreement.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/components/marketing-popup/index.less
@@ -193,7 +193,7 @@
}
.marketing-popup-multi-panel {
  margin-top: auto;
  margin-top: 408px;
  z-index: 100010;
  width: 560px;
  height: auto;
@@ -261,7 +261,6 @@
.marketing-popup-single-panel {
  position: relative;
  margin-top: 388px;
  margin: auto;
  z-index: 100010;
  width: 540px;
  height: auto;
@@ -290,7 +289,7 @@
    }
  }
  .marketing-popup-coupon-title {
    margin-top: 72px;
    margin-top: 64px;
    font-size: 56px;
    line-height: 68px;
    display: flex;
@@ -337,7 +336,7 @@
    align-items: center;
    justify-content: center;
    margin: 0 auto;
    margin-top: 120px;
    margin-top: 112px;
    font-size: 29.79px;
    font-weight: 500;
    line-height: 44.68px;
@@ -345,13 +344,6 @@
    align-items: center;
    color: #5b290e;
  }
  // .marketing-popup-close-single{
  //   margin-top: 0 !important;
  // }
  // .marketing-popup-close-icon{
  //   position: absolute;
  //   bottom: -120rpx;
  // }
}
.marketing-popup.is-active {
src/pages/robotaxi/home/components/marketing-popup/index.tsx
@@ -67,7 +67,7 @@
        }
        const timer = setTimeout(() => {
            // props.onClose();
            props.onClose();
        }, AUTO_CLOSE_DURATION);
        return () => {
src/pages/robotaxi/home/hooks/use-marketing.ts
@@ -3,8 +3,6 @@
import { FLOAT_ACTIVITY_DEFAULT_IMAGE } from '../constants';
type MarketingData = Record<string, any>;
const DEFAULT_MARKETING_POPUP_TITLE = '恭喜获得优惠券';
const DEFAULT_MARKETING_POPUP_BUTTON_TEXT = '我知道了';
type Deps = {
  /** 首次进入营销弹窗查询。 */
@@ -60,55 +58,6 @@
  };
  /**
   * 兼容旧 firstEnter 与新 exposureCoupon 两种返回结构,统一为首页营销弹窗可消费的数据。
   */
  const normalizeMarketingData = (rawData: any): MarketingData => {
    if (Array.isArray(rawData)) {
      const activities = rawData.filter(Boolean);
      const selectedActivity = activities.find((item: any) => Array.isArray(item?.coupons) && item.coupons.length > 0)
        || activities[0]
        || {};
      const coupons = (Array.isArray(selectedActivity?.coupons) ? selectedActivity.coupons : [])
        .filter(Boolean)
        .map((item: any, index: number) => ({
          ...item,
          id: item?.id ?? item?.couponId ?? index,
          title: item?.title ?? item?.couponName ?? '',
          amount: item?.amount ?? item?.money ?? item?.discountAmount ?? 0,
          unit: item?.unit ?? (Number(item?.couponType) === 1 ? '折' : '元'),
          endTime: item?.endTime ?? item?.expirationTime ?? item?.expireText ?? '',
          quantity: item?.quantity ?? item?.count ?? 1,
          conditionalAmount: item?.conditionalAmount ?? item?.fullMoney ?? 0
        }));
      return {
        ...selectedActivity,
        isFirst: activities.length > 0,
        coupons,
        activityId: selectedActivity?.activityId ?? selectedActivity?.id,
        popupId: selectedActivity?.popupId ?? selectedActivity?.id,
        id: selectedActivity?.id ?? selectedActivity?.activityId,
        miniProgramPopupTitle: selectedActivity?.miniProgramPopupTitle || selectedActivity?.acticityName || DEFAULT_MARKETING_POPUP_TITLE,
        miniProgramBtnText: selectedActivity?.miniProgramBtnText || DEFAULT_MARKETING_POPUP_BUTTON_TEXT
      };
    }
    if (rawData && typeof rawData === 'object') {
      return {
        miniProgramPopupTitle: rawData?.miniProgramPopupTitle || DEFAULT_MARKETING_POPUP_TITLE,
        miniProgramBtnText: rawData?.miniProgramBtnText || DEFAULT_MARKETING_POPUP_BUTTON_TEXT,
        ...rawData
      };
    }
    return {
      isFirst: false,
      coupons: [],
      miniProgramPopupTitle: DEFAULT_MARKETING_POPUP_TITLE,
      miniProgramBtnText: DEFAULT_MARKETING_POPUP_BUTTON_TEXT
    };
  };
  /**
   * 刷新首页营销弹窗与悬浮活动状态。
   */
  const syncMarketingState = async (hasLogin: boolean) => {
@@ -122,28 +71,15 @@
        deps.firstEnter(),
        deps.getFloatActicity()
      ]);
      const firstEnterData = normalizeMarketingData(firstEnterResponse?.data ?? firstEnterResponse ?? {});
      const firstEnterData = firstEnterResponse?.data ?? firstEnterResponse ?? {};
      const floatData = floatResponse?.data ?? floatResponse ?? {};
      const isFloatActivityEnabled = Number(floatData?.enableFloatWindow) === 1;
      setShowMarketing(Array.isArray(firstEnterData?.coupons)
        ? firstEnterData.coupons.length > 0
        : Boolean(firstEnterData?.isFirst));
      setShowMarketing(Boolean(firstEnterData?.isFirst));
      setMarketingData(firstEnterData);
      setShowFloatActivity(isFloatActivityEnabled);
      setFloatActivityUrl(String(floatData?.floatWindowJumpUrl || ''));
      let parsedCoverUrl = '';
      try {
        const coverImage = floatData?.coverImage;
        if (coverImage) {
          const coverArray = typeof coverImage === 'string' ? JSON.parse(coverImage) : coverImage;
          parsedCoverUrl = Array.isArray(coverArray) ? coverArray[0]?.url : '';
        }
      } catch (e) {
        console.error('解析悬浮窗图片失败', e);
      }
      setFloatActivityImg(parsedCoverUrl || FLOAT_ACTIVITY_DEFAULT_IMAGE);
      setFloatActivityImg(String(floatData?.coverImage || '') || FLOAT_ACTIVITY_DEFAULT_IMAGE);
    } catch (error) {
      resetMarketingState();
    }
src/pages/robotaxi/home/index.less
@@ -52,11 +52,7 @@
  .weather-info {
    display: flex;
    align-items: center;
<<<<<<< HEAD
    font-size: 24px;
=======
    font-size: 28px;
>>>>>>> feature_v2.4.0
    font-weight: 500;
    color: @black-text-04;
@@ -224,15 +220,15 @@
  right: 6px;
  bottom: 234px;
  z-index: 10020;
  width: 108px;
  height: 108px;
  width: 96px;
  height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  .activity-float-window-img {
    width: 108px;
    height: 108px;
    width: 96px;
    height: 96px;
  }
}
@@ -348,11 +344,7 @@
        left: 50%;
        top: 100%;
        transform: translate(-50%, -50%);
<<<<<<< HEAD
        width: 28px;
=======
        width: 18px;
>>>>>>> feature_v2.4.0
        height: 28px;
        z-index: -1;
      }
src/robotaxi/api/begin-route.ts
@@ -40,8 +40,7 @@
    UnlockVehiclePayload,
    UnlockVehicleResponse,
    OrderPaymentResponse,
    QueryOrderPaymentResultResponse,
    QueryLedgerCreditOrderResultResponse
    QueryOrderPaymentResultResponse
} from './types/begin-route';
// 导航-获取路线和费用
@@ -117,16 +116,7 @@
    return request({
        url: _ROBOTAXI_HOST + `/order/api/v1/mini-program/order/creditPay/createOrder`,
        method: 'POST',
        payload,
        showToast: false
    }, true);
}
// 查询免密签约状态
export const queryCreditPaySign = async (): Promise<any> => {
    return request({
        url: _ROBOTAXI_HOST + '/order/api/v1/mini-program/order/creditPay/sign',
        method: 'POST'
        payload
    }, true);
}
@@ -329,19 +319,6 @@
        payload: {
            orderId: String(orderId)
        }
    }, true);
}
// 查询信用分授权结果
export const queryLedgerCreditOrderResult = async (orderId: OrderId): Promise<QueryLedgerCreditOrderResultResponse> => {
    return request({
        url: _ROBOTAXI_HOST + `/order/api/v1/mini-program/order/queryLedgerCreditOrderResult`,
        method: 'POST',
        payload: {
            orderId: String(orderId)
        },
        skipException: true,
        showToast: false
    }, true);
}
src/robotaxi/api/home.ts
@@ -130,8 +130,7 @@
// 第一次进入应用
export const firstEnter = async () => {
    return request({
        // url: _ROBOTAXI_HOST + '/operation/api/v1/mini-program/acticity/firstEnter',
        url: _ROBOTAXI_HOST + '/operation/api/v1/mini-program/acticity/exposureCoupon',
        url: _ROBOTAXI_HOST + '/operation/api/v1/mini-program/acticity/firstEnter',
        method: 'GET'
    }, true);
}
src/robotaxi/api/payment.ts
@@ -26,15 +26,6 @@
};
/**
 * 查询支付分开通情况。
 */
export const getPayNoPwd = async (): Promise<GetPayPwdResponse> => {
  return request({
    url: _ROBOTAXI_HOST + '/order/api/v1/mini-program/order/creditPay/sign',
    method: 'POST',
  }, true);
};
/**
 * 设置支付分开通状态。
 */
export const setPayPwd = async (status: RobotaxiPaySettingStatus): Promise<SetPayPwdResponse> => {
src/robotaxi/api/types/begin-route.ts
@@ -605,12 +605,6 @@
/** 订单支付结果查询返回值。 */
export type QueryOrderPaymentResultResponse = {
    payStatus: number;
    payType: number;
    payTime: string;
};
// 信用分授权结果查询响应
export type QueryLedgerCreditOrderResultResponse = {
    creditOrderStatus: 'DOING' | 'REVOKED' | 'EXPIRED' | string;
    status: RobotaxiOrderStatus | number;
    orderId: string;
};
src/robotaxi/pages/begin-route/components/calling-car-modules/fare-detail-card.tsx
@@ -25,12 +25,6 @@
}: Props) {
    const [showDetail, setShowDetail] = useState(false); // 费用明细展开状态
    const canOpenCouponSelect = tripStatus === TripStatus.TripFinished && typeof onOpenCouponSelect === 'function'; // 仅待支付支持切换优惠券
    const isCreditPayProcessing = (
        tripStatus === TripStatus.TripFinished
        && !!orderId
        && String(Taro.getStorageSync('creditPayOrderId') || '') === String(orderId)
    ); // 信用下单结束后,展示免密支付中并阻止重复点击
    const payButtonText = isCreditPayProcessing ? '免密支付中' : '立即支付';
    // 外部重置版本变化时收起明细
    useEffect(() => {
@@ -199,7 +193,7 @@
                    </View>
                </View>
                {
                    (fareBreakdown?.operateFree != 1 && [TripStatus.TripFinished, TripStatus.PaymentSuccess].includes(tripStatus)) && Number(fareBreakdown?.redPacketMoney + fareBreakdown?.couponMoney) > 0 &&
                    (fareBreakdown?.operateFree != 1 && [TripStatus.TripFinished].includes(tripStatus)) && Number(fareBreakdown?.redPacketMoney + fareBreakdown?.couponMoney) > 0 &&
                    <View className="car-card-end-through" onClick={canOpenCouponSelect ? onOpenCouponSelect : undefined}>
                        <View className="car-card-end-through-left">
                            <View className="car-card-end-through-content-title">最佳优惠</View>
@@ -224,16 +218,8 @@
                                    ? 0 : fareBreakdown?.payMoney)}</View><View className="unit">元</View></View>
                            :
                            <View className="pay-box-free">员工内部测试</View>
                    }{/*  */}
                    <View className="pay-box-btn-wrapper">
                        <View
                            onClick={isCreditPayProcessing ? undefined : handlePay}
                            className="pay-box-btn"
                        >
                            {payButtonText}
                        </View>
                        {isCreditPayProcessing && <View className="pay-box-btn-mask" />}
                    </View>
                    } */}
                    <View onClick={handlePay} className="pay-box-btn">立即支付</View>
                </View>
            }
        </View>
src/robotaxi/pages/begin-route/components/css-folder/calling-car.less
@@ -18,11 +18,7 @@
  overflow: hidden;
  .calling-car-content-box {
    position: relative;
<<<<<<< HEAD
    padding: 48px 48px 82px 48px;
=======
    padding: 48px 48px 52px 48px;
>>>>>>> feature_v2.4.0
    background: @gary-theme;
    border-radius: 60px 60px 0 0;
  }
@@ -69,10 +65,7 @@
    font-size: 88px;
    line-height: 108px;
    font-weight: 600;
<<<<<<< HEAD
    font-family: @font-xpsans-bold;
=======
>>>>>>> feature_v2.4.0
    letter-spacing: normal;
    color: #FFFFFF;
  }
@@ -80,11 +73,7 @@
  // 提升特异性:与 .calling-car .fare-box-card { padding-bottom: 0 } 同特异性且在其之前,
  // 用 &.calling-car 组合两个类名避免下方规则覆盖 padding-bottom
  &.calling-car .fare-box-card {
<<<<<<< HEAD
    padding: 24px 48px 208px 48px;
=======
    padding: 48px 48px 208px 48px;
>>>>>>> feature_v2.4.0
    background: @gary-theme;
    border-radius: 60px 60px 0 0;
  }
@@ -174,11 +163,7 @@
  }
  .car-card-detail-num {
    font-size: 44px;
<<<<<<< HEAD
    font-weight: 600;
=======
    font-weight: 500;
>>>>>>> feature_v2.4.0
    line-height: 56px;
    letter-spacing: normal;
    color: @black-text-main;
@@ -340,16 +325,11 @@
    background: rgba(204, 208, 215, 0.25);
    &:first-child {
      position: relative;
<<<<<<< HEAD
      border-radius: 32px;
=======
      border-radius: 16px;
>>>>>>> feature_v2.4.0
      box-sizing: border-box;
    }
    &:last-child {
      position: relative;
<<<<<<< HEAD
      border-radius: 32px;
      box-sizing: border-box;
    }
@@ -377,17 +357,6 @@
    font-size: 28px;
    font-weight: 500;
    color: @black-text-main;
=======
      border-radius: 16px;
      box-sizing: border-box;
    }
  }
  .car-card-arrive-item-status {
    font-size: 20px;
    line-height: normal;
    letter-spacing: normal;
    color: rgba(20, 30, 39, 0.5);
>>>>>>> feature_v2.4.0
  }
  .car-card-arrive-item-img {
    width: 64px;
@@ -485,10 +454,7 @@
        margin-bottom: 16px;
        padding: 24px 20px;
        opacity: 1;
<<<<<<< HEAD
        overflow-y: scroll;
=======
>>>>>>> feature_v2.4.0
      }
    }
    .particulars-detail-item {
@@ -531,14 +497,11 @@
    color: @black-text-04;
    font-size: 28px;
  }
<<<<<<< HEAD
  .car-card-end-cost-money-line {
    display: inline-block;
    margin: 0 20px;
    color: @black-text-04;
  }
=======
>>>>>>> feature_v2.4.0
  .car-card-end-cost-content {
    display: flex;
    align-items: center;
@@ -704,7 +667,6 @@
    padding: 22px 0;
    &:first-child {
      position: relative;
<<<<<<< HEAD
      border-radius: 32px;
      background: rgba(204, 208, 215, 0.25);
      box-sizing: border-box;
@@ -712,17 +674,6 @@
    &:last-child {
      border-radius: 32px;
      background: rgba(204, 208, 215, 0.25);
=======
      border-radius: 16px;
      background: #ffffff;
      box-sizing: border-box;
      border: 2px solid rgba(0, 0, 0, 0.15);
    }
    &:last-child {
      border-radius: 16px;
      background: linear-gradient(110deg, #8475ff 0%, #7dd6ff 99%);
      color: #fff;
>>>>>>> feature_v2.4.0
    }
  }
  .car-card-reach-btn-item-img {
@@ -807,52 +758,8 @@
    font-size: 24px;
    line-height: 40px;
    letter-spacing: normal;
<<<<<<< HEAD
    color: @black-text-main;
  }
=======
    color: rgba(0, 0, 0, 0.9);
    display: flex;
    align-items: center;
    .unit {
      margin-left: 4px;
      font-size: 24px;
      line-height: 40px;
      letter-spacing: normal;
      color: rgba(0, 0, 0, 0.9);
    }
  }
  &-btn-wrapper {
    width: 296px;
    height: 94px;
    position: relative;
  }
  &-btn {
    width: 296px;
    height: 94px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 20px;
    background: linear-gradient(102deg, #8475FF 0%, #7DD6FF 102%);
    font-size: 28px;
    letter-spacing: normal;
    color: #FFFFFF;
  }
  &-btn-mask {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: 20px;
    background: rgba(255, 255, 255, 0.4);
  }
>>>>>>> feature_v2.4.0
}
.pay-box-btn {
  width: 654px;
@@ -870,29 +777,6 @@
  flex-shrink: 0;
  opacity: 0.75;
}
<<<<<<< HEAD
=======
.close-btn-item {
  position: relative;
  border-radius: 16px;
  background: linear-gradient(110deg, rgba(132, 117, 255, 0.2) 0%, rgba(125, 214, 255, 0.2) 99%) !important;
  &::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: 16px;
    padding: 1px;
    background: linear-gradient(180deg, #aaa8ff -10%, rgba(41, 159, 255, 0.0469) 108%, rgba(0, 0, 0, 0) 108%);
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
  }
}
>>>>>>> feature_v2.4.0
.bluetooth-operate-card {
  position: relative;
  z-index: 1;
@@ -1041,10 +925,7 @@
      .distance {
        font-size: 24px;
        font-weight: 500;
<<<<<<< HEAD
        font-family: @font-xpsans-bold;
=======
>>>>>>> feature_v2.4.0
        color: #ffffff;
      }
      .time {
@@ -1052,10 +933,7 @@
        padding: 0;
        font-size: 24px;
        font-weight: 500;
<<<<<<< HEAD
        font-family: @font-xpsans-bold;
=======
>>>>>>> feature_v2.4.0
        color: #ffffff;
      }
    }
@@ -1160,10 +1038,7 @@
    font-size: 48px;
    font-weight: normal;
    line-height: 64px;
<<<<<<< HEAD
    font-family: @font-xpsans-bold;
=======
>>>>>>> feature_v2.4.0
    color: @black-text-main;
  }
src/robotaxi/pages/begin-route/components/css-folder/cancel-popup.less
@@ -124,11 +124,7 @@
            .cancel-btn-cancel {
                flex: 1;
<<<<<<< HEAD
                border: 4px solid #141E27;
=======
                border: 2px solid #141E27;
>>>>>>> feature_v2.4.0
                border-radius: 1000px;
                font-size: 32px;
                line-height: 104px;
@@ -143,11 +139,7 @@
                flex: 1;
                text-align: center;
                border-radius: 1000px;
<<<<<<< HEAD
                border: 4px solid #141E27;
=======
                border: 2px solid #141E27;
>>>>>>> feature_v2.4.0
                font-size: 32px;
                line-height: 104px;
                text-align: center;
src/robotaxi/pages/begin-route/components/css-folder/evaluate-popup.less
@@ -22,26 +22,7 @@
        right: 0;
        background: #F1F5FA;
        border-radius: 60px 60px 0 0;
<<<<<<< HEAD
        padding: 64px 0 88px 0;
        .evaluate-rating-switcher,
        .content-box {
            transition: opacity 180ms ease, transform 180ms ease;
            will-change: opacity, transform;
        }
        &.is-rating-switching {
            .evaluate-rating-switcher,
            .content-box {
                opacity: 0;
                transform: translateY(12px) scale(0.985);
                pointer-events: none;
            }
        }
=======
        padding: 42px 0 88px 0;
>>>>>>> feature_v2.4.0
        .evaluate-rating-switcher,
        .content-box {
@@ -86,11 +67,7 @@
        }
        .evaluate-rating-switcher {
<<<<<<< HEAD
           
=======
            margin-top: 18px;
>>>>>>> feature_v2.4.0
            padding: 0 49px;
            display: flex;
            flex-direction: column;
@@ -328,11 +305,7 @@
                    align-items: center;
                    justify-content: center;
                    gap: 8px;
<<<<<<< HEAD
                    border-radius: 32px;
=======
                    border-radius: 16px;
>>>>>>> feature_v2.4.0
                    background: #E8ECF1;
                    &-img {
@@ -358,7 +331,6 @@
            display: flex;
            justify-content: center;
            align-items: center;
<<<<<<< HEAD
            &-btn {
                width: 100%;
@@ -377,18 +349,6 @@
                border-radius: 1000px;
                background: #D6D9DC;
            }
=======
            padding: 32px 80px;
            gap: 16px;
            box-sizing: border-box;
            z-index: 2;
            font-size: 30px;
            letter-spacing: normal;
            color: #FFFFFF;
            text-align: center;
            border-radius: 1000px;
            background: #141E27;
>>>>>>> feature_v2.4.0
        }
        .ok-btn {
src/robotaxi/pages/begin-route/components/css-folder/fragrance-control.less
@@ -64,11 +64,7 @@
  /* 香氛名称,大小类似温度显示 */
  .tf-card-fragrance-name {
    font-size: 40px;
<<<<<<< HEAD
    font-weight: 500;
=======
    font-weight: normal;
>>>>>>> feature_v2.4.0
    line-height: 64px;
    color: @black-text-main;
    overflow: hidden;
@@ -106,10 +102,6 @@
      background-image: url('https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/fragrance-close-20260703.png');
      // 关闭态卡片文字统一弱化
<<<<<<< HEAD
=======
      .tf-card-header-title,
>>>>>>> feature_v2.4.0
      .tf-card-fragrance-name,
      .tf-card-footer-text {
        color: rgba(20, 30, 39, 0.3);
@@ -148,11 +140,7 @@
      position: relative;
      z-index: 103;
      background: #FFFFFF;
<<<<<<< HEAD
      border-radius: 60px 60px 0 0;
=======
      border-radius: 40px 40px 0 0;
>>>>>>> feature_v2.4.0
      width: 100%;
      // 设计稿左右边距 24px
      padding: 0 0 calc(48px + env(safe-area-inset-bottom));
src/robotaxi/pages/begin-route/components/css-folder/passenger-notice.less
@@ -24,11 +24,7 @@
        right: 0;
        background: @gary-theme;
        border-radius: 60px 60px 0px 0px;
<<<<<<< HEAD
        padding: 48px 48px 80px 48px;
=======
        padding: 48px 18px 68px 48px;
>>>>>>> feature_v2.4.0
        height: 75vh;
        overflow: hidden;
        .passenger-content-bg {
src/robotaxi/pages/begin-route/components/css-folder/release-be-being.less
@@ -10,11 +10,7 @@
    position: relative;
    z-index: 1;
    border-radius: 60px 60px 0px 0px;
<<<<<<< HEAD
    padding: 48px 48px 112px 48px;
=======
    padding: 32px 48px 72px 48px;
>>>>>>> feature_v2.4.0
    background: @gary-theme;
  }
  .release-be-being-top-bg {
@@ -22,11 +18,7 @@
    top: 0;
    left: 0;
    width: 100%;
<<<<<<< HEAD
    height: 276px;
=======
    height: 282px;
>>>>>>> feature_v2.4.0
  }
  .top-box {
    .top-box-title {
src/robotaxi/pages/begin-route/components/css-folder/release-route.less
@@ -78,11 +78,7 @@
                    font-size: 20px;
                    line-height: 20px;
                    letter-spacing: normal;
<<<<<<< HEAD
                    color: @black-text-main;
=======
                    color: rgba(0, 0, 0, 0.9);
>>>>>>> feature_v2.4.0
                }
                .route-select-content-item-time {
@@ -102,11 +98,7 @@
                    font-size: 20px;
                    line-height: 20px;
                    letter-spacing: normal;
<<<<<<< HEAD
                    color: @black-text-main;
=======
                    color: rgba(0, 0, 0, 0.9);
>>>>>>> feature_v2.4.0
                    .traffic-signal-item {
                        display: flex;
@@ -156,10 +148,7 @@
        padding-top: 94px;
        background: @gary-theme;
        border-radius: 60px 60px 0 0;
<<<<<<< HEAD
        box-sizing: border-box;
=======
>>>>>>> feature_v2.4.0
      .select-site-content {
          position: relative;
          z-index: 1;
@@ -278,12 +267,8 @@
        .route-content {
            position: relative;
            margin-top: 16px;
<<<<<<< HEAD
            padding-bottom: 36px;
            box-sizing: border-box;
=======
            margin-bottom: 24px;
>>>>>>> feature_v2.4.0
            z-index: 10;
            display: flex;
            align-items: center;
@@ -348,11 +333,7 @@
            .discount-amount-text {
                flex-shrink: 0;
<<<<<<< HEAD
                border-radius: 8px;
=======
                border-radius: 200px;
>>>>>>> feature_v2.4.0
                background: rgba(255, 255, 255, 0);
                box-sizing: border-box;
                border: 1.4px solid @gold-text;
@@ -391,11 +372,7 @@
            display: flex;
            justify-content: space-between;
            align-items: center;
<<<<<<< HEAD
            padding: 8px 38px 62px 32px;
=======
            padding: 24px 38px 62px 32px;
>>>>>>> feature_v2.4.0
            background: @gary-theme;
            .money-box {
src/robotaxi/pages/begin-route/components/css-folder/temperature-control.less
@@ -1,8 +1,5 @@
<<<<<<< HEAD
@import '../../../../style/ui-variables.less';
=======
>>>>>>> feature_v2.4.0
.ac-control {
  flex-shrink: 0;
@@ -39,11 +36,7 @@
      z-index: 103;
      width: 100%;
      height: 1232px;
<<<<<<< HEAD
      border-radius: 60px 60px 0 0;
=======
      border-radius: 40px 40px 0 0;
>>>>>>> feature_v2.4.0
      overflow: hidden;
      background: #FFFFFF;
      box-sizing: border-box;
@@ -86,11 +79,7 @@
      .popup-ac-title {
        display: block;
        text-align: center;
<<<<<<< HEAD
        font-size: 32px;
=======
        font-size: 28px;
>>>>>>> feature_v2.4.0
        font-weight: 500;
        line-height: 40px;
        color: rgba(0, 0, 0, 0.9);
@@ -128,10 +117,7 @@
      justify-content: center;
      .popup-temp-item-value {
<<<<<<< HEAD
        font-family: @font-xpsans-bold;
=======
>>>>>>> feature_v2.4.0
        font-size: 40px;
        line-height: 44px;
        // 未选中温度:#141E27 透明度 0.2(对齐设计标注)
@@ -147,28 +133,17 @@
          font-size: 64px;
          line-height: 72px;
          font-weight: 600;
<<<<<<< HEAD
          color: @black-text-main;
=======
          color: #141E27;
>>>>>>> feature_v2.4.0
          opacity: 1;
        }
        .popup-temp-item-unit {
          margin-left: 4px;
<<<<<<< HEAD
          font-family: @font-xpsans-bold;
          font-size: 28px;
          line-height: 40px;
          font-weight: 500;
          color: @black-text-main;
=======
          font-size: 28px;
          line-height: 40px;
          font-weight: 500;
          color: #141E27;
>>>>>>> feature_v2.4.0
        }
      }
@@ -200,11 +175,7 @@
      .popup-ac-switch-text {
        font-size: 28px;
        line-height: 40px;
<<<<<<< HEAD
        color: @black-text-main;
=======
        color: rgba(0, 0, 0, 0.9);
>>>>>>> feature_v2.4.0
      }
    }
  }
src/robotaxi/pages/begin-route/components/css-folder/wechat-pay-score-loading.less
File was deleted
src/robotaxi/pages/begin-route/components/release-be-being.tsx
@@ -1,18 +1,15 @@
import Taro from "@tarojs/taro";
import { useEffect, useRef, useState } from 'react';
import { useEffect, useState } from 'react';
import { Image, View } from "@tarojs/components";
import './css-folder/release-be-being.less'
type Props = {
    handleOpenCancelPopup?: () => void;
    onFinish?: () => void;
    finishBlocked?: boolean;
}
export default function ReleaseBeBeing({ handleOpenCancelPopup, onFinish, finishBlocked = false }: Props) {
export default function ReleaseBeBeing({ handleOpenCancelPopup, onFinish }: Props) {
    const [completedCount, setCompletedCount] = useState(0); // 已完成步骤数
    const [finishReady, setFinishReady] = useState(false); // 发布动画是否已走完
    const finishTriggeredRef = useRef(false); // 防止 onFinish 重复触发
    const startSite = Taro.getStorageSync('startSite') || {};
    const endSite = Taro.getStorageSync('endSite') || {};
    const startSiteName = startSite?.name || startSite?.address || '-';
@@ -27,9 +24,9 @@
        const step1 = setTimeout(() => setCompletedCount(1), 1000);
        const step2 = setTimeout(() => setCompletedCount(2), 2000);
        // 3 秒后标记动画完成;是否真正切页由 finishBlocked 控制
        // 3秒后进入呼叫车中状态
        const step3 = setTimeout(() => {
            setFinishReady(true);
            onFinish?.();
        }, 3000);
        return () => {
@@ -38,16 +35,6 @@
            clearTimeout(step3);
        };
    }, []);
    useEffect(() => {
        // 信用分下单时,需要等待用户从支付分确认页返回后再推进到“呼叫车中”。
        if (!finishReady || finishBlocked || finishTriggeredRef.current) {
            return;
        }
        finishTriggeredRef.current = true;
        onFinish?.();
    }, [finishBlocked, finishReady, onFinish]);
  const renderSiteItemMarker = (index, count) => {
  /* 根据 completedCount 动态显示完成图标 */
src/robotaxi/pages/begin-route/components/wechat-pay-score-loading.tsx
File was deleted
src/robotaxi/pages/begin-route/hooks/use-credit-pay-return.ts
@@ -1,16 +1,9 @@
import { useCallback, useEffect, useRef } from 'react';
import Taro from '@tarojs/taro';
import { queryLedgerCreditOrderResult } from '../../../api/begin-route';
type Deps = {
  /** 当前正在下单的订单 ID,用于查询授权结果。 */
  orderId?: string;
  /** 支付分授权成功后的回调。 */
  onAuthorizedReturn: (queryId: string) => void | Promise<void>;
  /** 支付分未授权后的回调。 */
  onUnauthorizedReturn: (orderId?: string) => void | Promise<void>;
  /** 支付分页面拉起失败后的回调。 */
  onLaunchFailed: (orderId?: string) => void | Promise<void>;
  /** 支付分页面返回后的回调。 */
  onReturn: () => void;
};
const PAY_SCORE_REFERRER_APP_ID = 'wxd8f3793ea3b935b8';
@@ -35,25 +28,22 @@
  /**
   * 拉起微信支付分订单确认页。
   */
  const openCreditPayScoreUse = useCallback((packageValue: string, targetOrderId?: string) => {
    const queryOrderId = targetOrderId || deps.orderId;
  const openCreditPayScoreUse = useCallback((packageValue: string) => {
    if (!packageValue) {
      Taro.showToast({ title: '支付参数缺失,请稍后重试', icon: 'none' });
      void deps.onLaunchFailed(queryOrderId);
      return true;
      return false;
    }
    // @ts-ignore
    if (!wx.openBusinessView) {
      Taro.showToast({ title: '请升级微信版本后重试', icon: 'none' });
      void deps.onLaunchFailed(queryOrderId);
      return true;
      return false;
    }
    clearAppShowListener();
    /** 支付分页面返回监听函数。 */
    const handleAppShow = async (res) => {
    const handleAppShow = (res) => {
      if (res?.scene !== 1038) {
        return;
      }
@@ -63,90 +53,8 @@
        return;
      }
      const queryId = String(res?.referrerInfo?.extraData?.query_id || '').trim();
      console.log('[信用分授权返回][AppShow]', {
        scene: res?.scene,
        referrerInfo: res?.referrerInfo,
        queryId
      });
      clearAppShowListener();
      if (!queryId) {
        void deps.onUnauthorizedReturn(queryOrderId);
        return;
      }
      // 根据 query_id 轮询查询真实的授权结果
      if (!queryOrderId) {
        console.log('[信用分授权查询失败] 缺失 orderId');
        void deps.onUnauthorizedReturn(queryOrderId);
        return;
      }
      Taro.showLoading({ title: '授权结果查询中', mask: true });
      const maxPollingCount = 120;
      let currentPollingCount = 0;
      const pollStatus = async () => {
        try {
          const result = await queryLedgerCreditOrderResult(queryOrderId);
          const status = result?.data?.creditOrderStatus;
          console.log(`[信用分授权查询结果] 第${currentPollingCount + 1}次`, result);
          if (status === 'REVOKED' || status === 'EXPIRED') {
            Taro.hideLoading();
            void deps.onUnauthorizedReturn(queryOrderId);
            return;
          }
          if (status === 'DOING' || result?.code === 20710) {
            Taro.hideLoading();
            Taro.showToast({ title: '授权成功', icon: 'none' });
            void deps.onAuthorizedReturn(queryId);
            return;
          }
          if (status === 'CREATED') {
            // CREATED 状态也当作中间状态继续轮询
            currentPollingCount++;
            if (currentPollingCount >= maxPollingCount) {
              Taro.hideLoading();
              console.log('[信用分授权查询超时] CREATED 状态持续2分钟');
              void deps.onUnauthorizedReturn(queryOrderId);
              return;
            }
            setTimeout(pollStatus, 1000);
            return;
          }
          // 其他状态,继续轮询
          currentPollingCount++;
          if (currentPollingCount >= maxPollingCount) {
            Taro.hideLoading();
            console.log('[信用分授权查询超时]');
            void deps.onUnauthorizedReturn(queryOrderId);
            return;
          }
          setTimeout(pollStatus, 1000);
        } catch (error: any) {
          const errorCode = String(error?.code || error?.data?.code || '');
          if (errorCode === '20710') {
            console.log(`[信用分授权查询遇到20710] 第${currentPollingCount + 1}次,当作授权成功处理`);
            Taro.hideLoading();
            Taro.showToast({ title: '授权成功', icon: 'none' });
            void deps.onAuthorizedReturn(queryId);
            return;
          }
          Taro.hideLoading();
          console.log('[信用分授权查询失败]', error);
          void deps.onUnauthorizedReturn(queryOrderId);
        }
      };
      await pollStatus();
      deps.onReturn();
    };
    appShowListenerRef.current = handleAppShow;
@@ -158,19 +66,14 @@
      extraData: {
        package: packageValue
      },
      success: (res) => {
        console.log('[信用分授权拉起][openBusinessView]', res);
      },
      fail: () => {
        clearAppShowListener();
        console.log('[信用分授权拉起失败][openBusinessView]');
        Taro.showToast({ title: '拉起支付分订单失败', icon: 'none' });
        void deps.onLaunchFailed(queryOrderId);
      }
    });
    return true;
  }, [clearAppShowListener, deps.onAuthorizedReturn, deps.onLaunchFailed, deps.onUnauthorizedReturn, deps.orderId]);
  }, [clearAppShowListener, deps.onReturn]);
  useEffect(() => clearAppShowListener, [clearAppShowListener]);
src/robotaxi/pages/begin-route/hooks/use-order-actions.shared.ts
@@ -126,9 +126,7 @@
  /** 未签约态支付处理。 */
  handleUnsignedPayment: (token: string) => void | Promise<void>;
  /** 已签约态支付处理。 */
  handleSignedCreditPayment: (value: SignedOrderPaymentValue, targetOrderId?: string) => boolean | Promise<boolean>;
  /** 结束行程后进入待支付态时,触发信用扣款结果查询。 */
  handleCreditPayTripFinished?: (targetOrderId: string) => void | Promise<void>;
  handleSignedCreditPayment: (value: SignedOrderPaymentValue) => void | Promise<void>;
  /** 同步上车点。 */
  setStartSite?: (site: any) => void;
};
src/robotaxi/pages/begin-route/hooks/use-order-cancel.ts
@@ -50,7 +50,6 @@
    deps.setVehicleInfo({});
    clearOrderTripStorage();
    Taro.removeStorageSync('pickupEndTime');
    Taro.removeStorageSync('creditPayOrderId');
    Taro.removeStorageSync(WAITING_TIMER_START_STORAGE_KEY);
    Taro.removeStorageSync(WAITING_TIMER_ELAPSED_STORAGE_KEY);
  };
@@ -176,7 +175,7 @@
   */
  const handleOpenCancelPopupByTripStatus = (status: TripStatus, displayInfo?: any) => {
    const waitMinutes = Number(displayInfo?.waitMinutes);
    if ([TripStatus.CallingCar, TripStatus.VehicleApproaching].includes(status) && Number.isFinite(waitMinutes)) {
    if (status === TripStatus.VehicleApproaching && Number.isFinite(waitMinutes)) {
      deps.setCancelPopupWaitMinutes(waitMinutes);
    } else {
      deps.setCancelPopupWaitMinutes(null);
src/robotaxi/pages/begin-route/hooks/use-order-payment.ts
@@ -92,10 +92,7 @@
    } else {
      syncTripFinishedStatus();
    }
    return {
      orderDetail,
      nextTripStatus
    };
    return orderDetail;
  };
  /**
@@ -148,11 +145,7 @@
    try {
      const endOrderResult: any = await endOrder(targetOrderId);
      const { orderDetail, nextTripStatus } = await syncPostEndOrderTripStatus(targetOrderId);
      if (nextTripStatus === TripStatus.TripFinished) {
        // 结束行程后若仍待支付,立即触发信用扣款结果查询,避免依赖页面 effect 才能进入。
        await deps.handleCreditPayTripFinished?.(targetOrderId);
      }
      const orderDetail = await syncPostEndOrderTripStatus(targetOrderId);
      reportTripPayStartEvent(orderDetail);
      if (endOrderResult) {
        Taro.showToast({
@@ -178,11 +171,7 @@
      await endOrder(targetOrderId);
    } catch (error) {
    }
    const { nextTripStatus } = await syncPostEndOrderTripStatus(targetOrderId);
    if (nextTripStatus === TripStatus.TripFinished) {
      // 倒计时自动结束行程时也复用同一套信用扣款结果查询逻辑。
      await deps.handleCreditPayTripFinished?.(targetOrderId);
    }
    await syncPostEndOrderTripStatus(targetOrderId);
  };
  /**
@@ -203,34 +192,35 @@
      mask: false
    });
    try {
      // await getOrderPayment({ orderId: targetOrderId });
      // syncPaymentSuccessStatus();
      await getOrderPayment({ orderId: targetOrderId });
      syncPaymentSuccessStatus();
      const paymentResult = await getOrderPayment({ orderId: targetOrderId });
      const paymentStatus = Number(paymentResult?.status);
      // const paymentResult = await getOrderPayment({ orderId: targetOrderId });
      // const paymentStatus = Number(paymentResult?.status);
      if (paymentStatus === RobotaxiPaymentEntryStatus.Unsigned) {
        const cashierToken = paymentResult?.value?.token;
        if (!cashierToken) {
          Taro.showToast({ title: '支付凭证缺失,请稍后重试', icon: 'none' });
          return;
        }
        await deps.handleUnsignedPayment(cashierToken);
        return;
      }
      // if (paymentStatus === RobotaxiPaymentEntryStatus.Unsigned) {
      //   const cashierToken = paymentResult?.value?.token;
      //   if (!cashierToken) {
      //     Taro.showToast({ title: '支付凭证缺失,请稍后重试', icon: 'none' });
      //     return;
      //   }
      //   await deps.handleUnsignedPayment(cashierToken);
      //   return;
      // }
      if (paymentStatus === RobotaxiPaymentEntryStatus.Signed) {
        const signedPaymentValue = paymentResult?.value as SignedOrderPaymentValue;
        if (!signedPaymentValue?.packageValue) {
          Taro.showToast({ title: '支付参数缺失,请稍后重试', icon: 'none' });
          return;
        }
        await deps.handleSignedCreditPayment(signedPaymentValue);
        return;
      }
      // if (paymentStatus === RobotaxiPaymentEntryStatus.Signed) {
      //   const signedPaymentValue = paymentResult?.value as SignedOrderPaymentValue;
      //   if (!signedPaymentValue?.packageValue) {
      //     Taro.showToast({ title: '支付参数缺失,请稍后重试', icon: 'none' });
      //     return;
      //   }
      //   await deps.handleSignedCreditPayment(signedPaymentValue);
      //   return;
      // }
      Taro.showToast({ title: '暂不支持当前支付方式', icon: 'none' });
      // Taro.showToast({ title: '暂不支持当前支付方式', icon: 'none' });
    } catch (error) {
      Taro.showToast({ title: '支付失败,请重试', icon: 'none' });
    } finally {
src/robotaxi/pages/begin-route/hooks/use-order-submit.ts
@@ -1,9 +1,10 @@
import Taro from '@tarojs/taro';
import { useCallback, useRef } from 'react';
import { formatDateTime, debounce, reportEvent } from '../../../../utils/Robotaxi-public-method';
import { createCreditPayOrder, saveOrder, routeStaleCheck, queryCreditPaySign } from '../../../api/begin-route';
import { createCreditPayOrder, saveOrder, routeStaleCheck } from '../../../api/begin-route';
import type { SaveOrderPayload } from '../../../api/types/begin-route';
import { getAgreement } from '../../../api/home';
import { getPayPwd, RobotaxiPaySettingStatus, setPayPwd } from '../../../api/payment';
import useCreditPaySign from '../../../hooks/use-credit-pay-sign';
import { checkOtp } from '../../../../utils/tools';
import { jumpTo } from '../../../../utils/jump';
@@ -50,9 +51,6 @@
  callImmediately: () => void;
};
/** 当前路线是否为载客测试免费。 */
const isOperateFreeRoute = (selectedRoute: any) => Number(selectedRoute?.operateFree) === 1;
/** 标准化文本,兼容普通空格与不可见空格差异。 */
const normalizeText = (value: any) => String(value || '').replace(/\s+/g, ' ').trim().toLowerCase();
@@ -96,28 +94,9 @@
  skipCreditPayCheck?: boolean;
  /** 是否跳过下单起始埋点。 */
  skipPayStartReport?: boolean;
  /** 跳过校验后强制指定信用下单模式。 */
  forcedCreditPaySubmitMode?: 'credit_pay_submit' | 'credit_pay_skip_auth_submit';
};
type CreditPayCheckResult =
  | 'normal_submit'
  | 'credit_pay_submit'
  | 'credit_pay_skip_auth_submit'
  | 'blocked';
/** 将签约状态转换为后续下单模式。 */
const resolveCreditPaySubmitMode = (
  status: any
): Extract<CreditPayCheckResult, 'credit_pay_submit' | 'credit_pay_skip_auth_submit'> | null => {
  if (Number(status) === 2) {
    return 'credit_pay_skip_auth_submit';
  }
  if (Number(status) === 3) {
    return 'credit_pay_submit';
  }
  return null;
};
type CreditPayCheckResult = 'normal_submit' | 'credit_pay_submit' | 'blocked';
/**
 * 管理下单前校验与提交动作。
@@ -125,32 +104,6 @@
export default function useOrderSubmit(deps: OrderActionsDeps): UseOrderSubmitResult {
  const waitingCreditPayReturnRef = useRef(false); // 是否正在等待微信支付分签约页返回
  const submitOrderFlowRef = useRef<(options?: SubmitOrderFlowOptions) => Promise<void>>(); // 始终指向最新的下单流程
  /**
   * 查询长期签约回跳后的最新支付分状态,并决定是否继续信用下单。
   */
  const resolveCreditPayModeAfterSignReturn = useCallback(async () => {
    Taro.showLoading({ title: '授权结果查询中', mask: true });
    let shouldHideLoading = true;
    try {
      const signResult = await queryCreditPaySign();
      const latestStatus = signResult?.data?.status ?? signResult?.status;
      const resolvedCreditPaySubmitMode = resolveCreditPaySubmitMode(latestStatus);
      if (resolvedCreditPaySubmitMode) {
        Taro.hideLoading();
        shouldHideLoading = false;
        Taro.showToast({ title: '授权成功', icon: 'none' });
        return resolvedCreditPaySubmitMode;
      }
      return resolvedCreditPaySubmitMode;
    } catch (error) {
      return null;
    } finally {
      if (shouldHideLoading) {
        Taro.hideLoading();
      }
    }
  }, []);
  /**
   * 结束下单中状态。
@@ -475,61 +428,66 @@
    }
  };
  const { openCreditPaySign } = useCreditPaySign({
    onReturn: async () => {
      // 长期签约页回跳后,先查询最新授权结果,再决定是否继续信用下单。
      waitingCreditPayReturnRef.current = false;
      const nextCreditPaySubmitMode = await resolveCreditPayModeAfterSignReturn();
      if (!nextCreditPaySubmitMode) {
        stopCallSubmitting();
        Taro.showToast({ title: '支付分授权未完成,请重试', icon: 'none' });
        return;
      }
      void submitOrderFlowRef.current?.({
        skipCreditPayCheck: true,
        forcedCreditPaySubmitMode: nextCreditPaySubmitMode
      });
    },
    onLaunchFail: () => {
      waitingCreditPayReturnRef.current = false;
      stopCallSubmitting();
      Taro.showToast({ title: '拉起签约失败', icon: 'none' });
  /**
   * 继续执行签约页返回后的下单流程。
   */
  const continueSubmitAfterCreditPayReturn = useCallback(() => {
    if (!waitingCreditPayReturnRef.current) {
      return;
    }
    waitingCreditPayReturnRef.current = false;
    void submitOrderFlowRef.current?.({
      skipCreditPayCheck: true,
      skipPayStartReport: true
    });
  }, []);
  /**
   * 拉起签约失败后,降级为继续正常下单。
   */
  const continueSubmitAfterCreditPayLaunchFail = useCallback(() => {
    if (!waitingCreditPayReturnRef.current) {
      return;
    }
    waitingCreditPayReturnRef.current = false;
    // Taro.showToast({ title: '拉起免密开通失败,已继续下单', icon: 'none' });
    void submitOrderFlowRef.current?.({
      skipCreditPayCheck: true,
      skipPayStartReport: true
    });
  }, []);
  const { openCreditPaySign } = useCreditPaySign({
    onReturn: continueSubmitAfterCreditPayReturn,
    onLaunchFail: continueSubmitAfterCreditPayLaunchFail
  });
  /**
   * 下单前校验免密状态。
   */
  const checkCreditPayReadyBeforeOrder = useCallback(async (selectedRoute: any) => {
    if (isOperateFreeRoute(selectedRoute)) {
      // 载客测试免费单直接走普通下单,不拉起微信信用下单弹窗。
      return 'normal_submit' as CreditPayCheckResult;
    }
  const checkCreditPayReadyBeforeOrder = useCallback(async () => {
    // 免密状态校验,先默认返回正常下单,后续根据校验结果再处理。
    return 'normal_submit' as CreditPayCheckResult;
    try {
      const res = await queryCreditPaySign();
      const status = res?.data?.status ?? res?.status; // 兼容不同包裹层级
      const value = res?.data?.value ?? res?.value;
      const resolvedCreditPaySubmitMode = resolveCreditPaySubmitMode(status);
      if (resolvedCreditPaySubmitMode) {
        // status=2: 已确认签约,信用下单后无需再拉起微信支付分授权页。
        // status=3: 每次下单授权流程,信用下单后仍需拉起微信支付分确认页。
        return resolvedCreditPaySubmitMode;
      const hasEnabledCreditPay = await getPayPwd();
      if (hasEnabledCreditPay === true) {
        return 'normal_submit' as CreditPayCheckResult;
      }
      if (status === 1) {
        // 需要拉起长期授权
        const isCanceled = await deps.handleOpenCreditPayPopup();
        if (isCanceled) {
          // 用户取消开通,中断下单流程
          stopCallSubmitting();
          return 'blocked' as CreditPayCheckResult;
        }
      const isCanceled = await deps.handleOpenCreditPayPopup();
      if (isCanceled) {
        // 用户取消开通,继续下单
        return 'normal_submit' as CreditPayCheckResult;
      }
        // value 为支付中心签约响应对象(CreditPaySignVo),需取其中的 signStr 字段作为预授权 token。
        const signStr = String(value?.signStr ?? value ?? '').trim();
      if (Number(deps.distanceConfig?.creditPayNeedConfirm) !== 0) {
        // 默认优先走信用下单,只有后端明确返回 0 时才继续旧的签约流程。
        return 'credit_pay_submit' as CreditPayCheckResult;
      }
      try {
        const response = await setPayPwd(RobotaxiPaySettingStatus.Enable);
        const signStr = String(response?.signStr || '').trim();
        if (!signStr) {
          // 获取免密签约信息失败,降级为继续下单
          return 'normal_submit' as CreditPayCheckResult;
@@ -547,13 +505,11 @@
        // 等待微信签约页返回后再恢复下单,避免当前流程继续往下执行。
        stopCallSubmitting();
        return 'blocked' as CreditPayCheckResult;
      } catch (e) {
        // 免密状态校验失败,降级为继续下单
        return 'normal_submit' as CreditPayCheckResult;
      }
      // 未知状态降级为继续下单
      return 'normal_submit' as CreditPayCheckResult;
    } catch (error) {
      // 接口失败,降级为继续下单
      return 'normal_submit' as CreditPayCheckResult;
    }
  }, [openCreditPaySign, deps]);
@@ -607,9 +563,9 @@
      return;
    }
    let submitMode: CreditPayCheckResult = options.forcedCreditPaySubmitMode || 'normal_submit';
    let submitMode: CreditPayCheckResult = 'normal_submit';
    if (!options.skipCreditPayCheck) {
      submitMode = await checkCreditPayReadyBeforeOrder(selectedRoute);
      submitMode = await checkCreditPayReadyBeforeOrder();
      if (submitMode === 'blocked') {
        return;
      }
@@ -619,70 +575,34 @@
    await waitForOrderSuccessSubscribePopup();
    try {
      const isCreditPaySubmit = submitMode === 'credit_pay_submit'
        || submitMode === 'credit_pay_skip_auth_submit';
      if (isCreditPaySubmit) {
        Taro.showLoading({ title: '加载中', mask: true });
      }
      const submitResult = isCreditPaySubmit
      const submitResult = submitMode === 'credit_pay_submit'
        ? await submitCreditPayOrder(startSite, openCityId, selectedRoute)
        : await submitOrder(startSite, openCityId);
      if (!submitResult?.orderId) {
        Taro.hideLoading();
        stopCallSubmitting();
        return;
      }
      deps.setOrderId(submitResult.orderId);
      deps.setTripStatus(TripStatus.Publishing);
      deps.bindSocketListeners();
      void subscribeAfterOrderSuccess(submitResult.orderId);
      if (!isCreditPaySubmit) {
        Taro.removeStorageSync('creditPayOrderId');
      }
      if (isCreditPaySubmit) {
        Taro.setStorageSync('creditPayOrderId', submitResult.orderId);
        if (submitMode === 'credit_pay_skip_auth_submit') {
          Taro.hideLoading();
          // status=2 代表当前已是免确认模式,信用下单成功后直接进入发单态。
          deps.setTripStatus(TripStatus.Publishing);
          return;
        }
      if (submitMode === 'credit_pay_submit') {
        const creditPayPackageValue = String(submitResult.creditPayPackageValue || '').trim();
        if (!creditPayPackageValue) {
          Taro.hideLoading();
          Taro.showToast({ title: '支付参数缺失,请稍后重试', icon: 'none' });
          return;
        }
        // 复用现有支付分确认页拉起与回跳查询链路。
        const launched = await deps.handleSignedCreditPayment({
        void deps.handleSignedCreditPayment({
          businessOrderId: '',
          authOrderId: '',
          channelOrderId: '',
          payType: 13,
          packageValue: creditPayPackageValue
        }, submitResult.orderId);
        Taro.hideLoading();
        // 只有拉起失败才立刻进入发单状态(或者依靠 abort 逻辑终止)
        if (!launched) {
          deps.setTripStatus(TripStatus.Publishing);
        }
        return;
        });
      }
      deps.setTripStatus(TripStatus.Publishing);
    } catch (error) {
      Taro.hideLoading();
      const errorMessage = String((error as any)?.msg || (error as any)?.message || '下单失败,请重试');
      if (submitMode === 'credit_pay_submit' || submitMode === 'credit_pay_skip_auth_submit') {
        Taro.showToast({ title: errorMessage, icon: 'none' });
      }
      reportPayResultEvent(resolvePayResultStatus(errorMessage));
      reportPayResultEvent(resolvePayResultStatus((error as any)?.msg || (error as any)?.message || error));
      stopCallSubmitting();
    }
  };
src/robotaxi/pages/begin-route/hooks/use-page-actions.ts
@@ -18,7 +18,6 @@
type Deps = {
  tripStatus: TripStatus;
  startSite: any;
  returnSource?: string;
  getCheckedEnter: () => boolean;
  setCheckedEnter: (checked: boolean) => void;
  onBeforeBack?: () => void;
@@ -94,21 +93,13 @@
  };
  /**
   * 根据来源返回上一页或首页,并清理必要缓存。
   * 返回首页并清理必要缓存。
   */
  const toBack = () => {
    deps.onBeforeBack?.();
    Taro.removeStorageSync('selectedCouponId');
    clearModifyDestinationStorage();
    clearPassedRouteCache();
    if (deps.returnSource === 'order') {
      if (deps.tripStatus === TripStatus.PaymentSuccess || deps.tripStatus === TripStatus.PublishRoute) {
        clearOrderTripStorage();
        Taro.removeStorageSync('endSite');
      }
      Taro.navigateBack();
      return;
    }
    if (deps.tripStatus === TripStatus.PaymentSuccess || deps.tripStatus === TripStatus.PublishRoute) {
      if (deps.tripStatus === TripStatus.PublishRoute) {
        retainStartSiteForNextHome();
src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx
@@ -71,8 +71,6 @@
  endSite: any;
  /** 发单 */
  callImmediately: () => void;
  /** 是否正在等待信用分确认页返回结果 */
  isWaitingSignedCreditPayResult?: boolean;
  /** 预估态选择上下车点 */
  handleEstimateSelectSite: (pageType: "start" | "end") => void;
  /** 费用信息 */
@@ -96,8 +94,6 @@
  handlePickupTimeoutAutoCancel: () => void;
  /** 行程状态设置 */
  setTripStatus: (value: TripStatus) => void;
  /** 发布中动画结束 */
  handlePublishingAnimationFinish?: () => void;
  /** 完成倒计时启用 */
  finishCountdownEnabled: boolean;
  /** 订单 ID */
@@ -945,12 +941,7 @@
          handleOpenCancelPopup={() =>
            deps.handleOpenCancelPopupByTripStatus(TripStatus.Publishing)
          }
          finishBlocked={Boolean(deps.isWaitingSignedCreditPayResult)}
          onFinish={() => {
            if (deps.handlePublishingAnimationFinish) {
              deps.handlePublishingAnimationFinish();
              return;
            }
            deps.setTripStatus(TripStatus.CallingCar);
            Taro.setStorageSync("tripStatus", TripStatus.CallingCar);
          }}
src/robotaxi/pages/begin-route/hooks/use-web-socket-events.ts
@@ -17,10 +17,6 @@
export type UseWebSocketEventsDeps = {
    tripStatusRef: React.MutableRefObject<TripStatus>;
    isWaitingSignedCreditPayResultRef?: React.MutableRefObject<boolean>;
    pendingSignedCreditPayTripStatusRef?: React.MutableRefObject<TripStatus | null>;
    isHoldingTripStatusDuringPublishingAnimationRef?: React.MutableRefObject<boolean>;
    pendingTripStatusAfterPublishingAnimationRef?: React.MutableRefObject<TripStatus | null>;
    pickupArrivedReportedOrderIdRef: React.MutableRefObject<string>;
    tripInProgressReportedOrderIdRef: React.MutableRefObject<string>;
    arrivedDestinationReportedOrderIdRef: React.MutableRefObject<string>;
src/robotaxi/pages/begin-route/hooks/web-socket-handlers/create-order-status-socket-handler.ts
@@ -96,14 +96,6 @@
  if (currentTripStatus === mappedTripStatus) {
    return mappedTripStatus;
  }
  if (deps.isWaitingSignedCreditPayResultRef?.current) {
    deps.pendingSignedCreditPayTripStatusRef && (deps.pendingSignedCreditPayTripStatusRef.current = mappedTripStatus);
    return currentTripStatus;
  }
  if (deps.isHoldingTripStatusDuringPublishingAnimationRef?.current && currentTripStatus === TripStatus.Publishing) {
    deps.pendingTripStatusAfterPublishingAnimationRef && (deps.pendingTripStatusAfterPublishingAnimationRef.current = mappedTripStatus);
    return currentTripStatus;
  }
  deps.setTripStatus(mappedTripStatus);
  deps.tripStatusRef.current = mappedTripStatus;
  Taro.setStorageSync('tripStatus', mappedTripStatus);
src/robotaxi/pages/begin-route/index.less
@@ -160,11 +160,7 @@
// 气泡底部中间的钻石指示图标
.callout-diamond-icon {
<<<<<<< HEAD
    width: 28px;
=======
    width: 18px;
>>>>>>> feature_v2.4.0
    height: 28px;
    margin-top: -14px;
    flex-shrink: 0;
@@ -225,15 +221,9 @@
    flex-direction: row;
    align-items: center;
    justify-content: center;
<<<<<<< HEAD
    background: @black-text-main;
    border-radius: 100px;
    padding: 16px 20px;
=======
    background: #141E27;
    border-radius: 100px;
    padding: 16px 16px 16px 20px;
>>>>>>> feature_v2.4.0
}
.site-countdown-icon {
@@ -244,10 +234,7 @@
}
.site-countdown-time {
<<<<<<< HEAD
    font-family: @font-xpsans-bold;
=======
>>>>>>> feature_v2.4.0
    font-size: 24px;
    font-weight: normal;
    line-height: 32px;
src/robotaxi/pages/begin-route/index.tsx
@@ -60,12 +60,11 @@
import useBluetoothCarControl from './hooks/use-bluetooth-car-control';
import { toTripStatus, TripStatus } from '../../constants/trip-status';
import { MODIFY_DESTINATION_SOCKET_STATUS_KEY } from '../../constants/modify-destination';
import { cancelOrder, selectNavigationRoute } from '../../api/begin-route';
import { selectNavigationRoute } from '../../api/begin-route';
import { getAddressByLocation, getDistance, reportEvent } from '../../../utils/Robotaxi-public-method';
import { CurrentUserLocation, RouteDistanceValue } from './hooks/use-route-manager.shared';
import { MODIFY_DESTINATION_SESSION_KEY } from '../../constants/modify-destination';
import { getOrderId } from '../../utils/order';
import { getOrderDetail } from '../../api/order';
import { _ROBOTAXI_WS_HOST } from '../../../constants/api';
import { RobotaxiSignedPayType, SignedOrderPaymentValue } from '../../api/types/begin-route';
@@ -307,7 +306,6 @@
  const [pageDidShowVersion, setPageDidShowVersion] = useState(0); // 页面展示版本号,用于触发子模块重查
  const [resetDetailVersion, setResetDetailVersion] = useState(0); // 重置详情版本号,用于触发组件更新
  const [priceUpdateVersion, setPriceUpdateVersion] = useState(0); // 价格更新版本号
  const [, setCreditPayFallbackRefreshVersion] = useState(0); // 信用扣款回落普通支付后,触发页面重渲染
  const [evaluateSubmitVersion, setEvaluateSubmitVersion] = useState(0); // 评价提交版本号
  const [evaluateCloseVersion, setEvaluateCloseVersion] = useState(0); // 评价关闭版本号
  const [evaluateOrderRating, setEvaluateOrderRating] = useState(1); // 当前评价弹窗对应评分
@@ -318,16 +316,7 @@
  const [pickupExceptionInfo, setPickupExceptionInfo] = useState<PickupExceptionInfo | null>(null); // 接驾异常信息
  const [showPickupExceptionPopup, setShowPickupExceptionPopup] = useState(false); // 接驾异常弹窗展示状态
  const [showCreditPayPopup, setShowCreditPayPopup] = useState(false); // 免密支付开通弹窗
  const [isWaitingSignedCreditPayResult, setIsWaitingSignedCreditPayResult] = useState(false); // 信用分确认页已拉起,等待用户返回结果
  const creditPayResolverRef = useRef<((value: boolean) => void) | null>(null); // 免密弹窗的 Promise resolve 回调
  const isWaitingSignedCreditPayResultRef = useRef(false); // 信用分确认结果等待态引用,供 socket 状态同步拦截使用
  const pendingSignedCreditPayTripStatusRef = useRef<TripStatus | null>(null); // 等待信用分结果期间暂存的最新行程状态
  const pendingPublishingAfterSignedCreditPayRef = useRef(false); // 信用分下单成功后,等待结果返回再进入发布态
  const isHoldingTripStatusDuringPublishingAnimationRef = useRef(false); // 信用分返回后,发布中 3 秒动画期间暂存 socket 状态
  const pendingTripStatusAfterPublishingAnimationRef = useRef<TripStatus | null>(null); // 发布中动画结束后待恢复的最新状态
  const clearActiveOrderRuntimeRef = useRef<(() => void) | null>(null); // 信用分取消发单后复用订单清理逻辑
  const restartPlanningRouteRef = useRef<(() => void) | null>(null); // 信用分取消发单后复用发单前页面恢复逻辑
  const stopCallSubmittingRef = useRef<(() => void) | null>(null); // 信用分中止发单后复位“立即呼叫”提交态
  const [orderRouteMetrics, setOrderRouteMetrics] = useState<OrderRouteMetrics>({
    distanceMeters: null,
    durationSeconds: null
@@ -420,7 +409,6 @@
  }, []);
  const shouldShowWaitingRadar = isAndroid && [TripStatus.Publishing, TripStatus.CallingCar].includes(tripStatus); // 是否显示等待雷达动画(Android 且处于发布中/呼叫车中)
  const vehicleMarkerId = !isAndroid && tripStatus === TripStatus.InService ? 30 : 3; // 车辆标记 ID,iOS 行驶中阶段使用不同 ID
  const router = Taro.useRouter();
  const {
    customCalloutIconSrc,
    waitingRadarSrc,
@@ -445,7 +433,6 @@
  } = usePageActions({
    tripStatus,
    startSite,
    returnSource: router?.params?.from,
    getCheckedEnter: () => isCheckedEnter.current,
    setCheckedEnter: (checked) => {
      isCheckedEnter.current = checked;
@@ -1235,6 +1222,7 @@
    getCurrentVehicleLocation: () => vehicleLocation,
    updatePickupRouteChangeEligibleOrder
  }); // 页面恢复与初始化编排
  const router = Taro.useRouter();
  const tripRuntime = useTripRuntime({
    waitingTimerStartKey: WAITING_TIMER_START_KEY,
    waitingTimerElapsedKey: WAITING_TIMER_ELAPSED_KEY,
@@ -1370,52 +1358,6 @@
  }, []);
  /**
   * 统一维护“等待信用分结果”状态,同时同步 ref,供异步回调和 socket 读取。
   */
  const syncWaitingSignedCreditPayResult = useCallback((value: boolean) => {
    isWaitingSignedCreditPayResultRef.current = value;
    setIsWaitingSignedCreditPayResult(value);
  }, []);
  /**
   * 信用分结果返回后,恢复页面状态推进。
   */
  const resumeTripStatusAfterSignedCreditPayReturn = useCallback(() => {
    syncWaitingSignedCreditPayResult(false);
    const deferredTripStatus = pendingSignedCreditPayTripStatusRef.current;
    pendingSignedCreditPayTripStatusRef.current = null;
    if (pendingPublishingAfterSignedCreditPayRef.current) {
      pendingPublishingAfterSignedCreditPayRef.current = false;
      pendingTripStatusAfterPublishingAnimationRef.current = deferredTripStatus;
      isHoldingTripStatusDuringPublishingAnimationRef.current = true;
      setTripStatus(TripStatus.Publishing);
      tripStatusRef.current = TripStatus.Publishing;
      Taro.setStorageSync('tripStatus', TripStatus.Publishing);
      return;
    }
    if (deferredTripStatus !== null) {
      setTripStatus(deferredTripStatus);
      tripStatusRef.current = deferredTripStatus;
      Taro.setStorageSync('tripStatus', deferredTripStatus);
    }
  }, [syncWaitingSignedCreditPayResult]);
  /**
   * 发布中 3 秒动画结束后,再恢复信用分结果等待期间暂存的最新状态。
   */
  const handlePublishingAnimationFinish = useCallback(() => {
    const deferredTripStatus = pendingTripStatusAfterPublishingAnimationRef.current;
    pendingTripStatusAfterPublishingAnimationRef.current = null;
    isHoldingTripStatusDuringPublishingAnimationRef.current = false;
    const nextTripStatus = deferredTripStatus ?? TripStatus.CallingCar;
    setTripStatus(nextTripStatus);
    tripStatusRef.current = nextTripStatus;
    Taro.setStorageSync('tripStatus', nextTripStatus);
  }, []);
  /**
   * 确认开通免密支付。
   */
  const handleConfirmCreditPayPopup = useCallback(() => {
@@ -1449,10 +1391,6 @@
  const { bindSocketListeners, ensureSocketListeners } = useWebSocketEvents({
    tripStatusRef,
    isWaitingSignedCreditPayResultRef,
    pendingSignedCreditPayTripStatusRef,
    isHoldingTripStatusDuringPublishingAnimationRef,
    pendingTripStatusAfterPublishingAnimationRef,
    pickupArrivedReportedOrderIdRef,
    tripInProgressReportedOrderIdRef,
    arrivedDestinationReportedOrderIdRef,
@@ -1554,155 +1492,9 @@
    onPaySuccess: handlePaymentSuccess
  });
  // 信用分结束行程 loading 状态
  const creditPayLoadingTimerRef = useRef<any>(null);
  const creditPayFallbackCheckTimerRef = useRef<any>(null);
  const creditPayFallbackActiveOrderIdRef = useRef('');
  const clearCreditPayFallbackRuntime = useCallback((hideLoading = true) => {
    if (creditPayLoadingTimerRef.current) {
      clearTimeout(creditPayLoadingTimerRef.current);
      creditPayLoadingTimerRef.current = null;
    }
    if (creditPayFallbackCheckTimerRef.current) {
      clearInterval(creditPayFallbackCheckTimerRef.current);
      creditPayFallbackCheckTimerRef.current = null;
    }
    creditPayFallbackActiveOrderIdRef.current = '';
    if (hideLoading) {
      Taro.hideLoading();
    }
  }, []);
  const handleCreditPayTripFinished = useCallback(async (targetOrderId: string) => {
    const resolvedOrderId = String(targetOrderId || '').trim();
    const creditPayOrderId = String(Taro.getStorageSync('creditPayOrderId') || '').trim();
    if (!resolvedOrderId || !creditPayOrderId || creditPayOrderId !== resolvedOrderId) {
      return;
    }
    if (
      creditPayFallbackActiveOrderIdRef.current === resolvedOrderId
      && (creditPayLoadingTimerRef.current || creditPayFallbackCheckTimerRef.current)
    ) {
      return;
    }
    clearCreditPayFallbackRuntime(false);
    creditPayFallbackActiveOrderIdRef.current = resolvedOrderId;
    Taro.showLoading({ title: '扣款结果查询中,请勿重复支付', mask: true });
    const checkCreditPayFallback = async () => {
      try {
        const orderDetail: any = await getOrderDetail(resolvedOrderId);
        if (Number(orderDetail?.payType) === 1) {
          Taro.removeStorageSync('creditPayOrderId');
          clearCreditPayFallbackRuntime();
          setCreditPayFallbackRefreshVersion((prev) => prev + 1);
          Taro.showToast({ title: '免密扣款失败,请手动支付', icon: 'none' });
        }
      } catch (error) {
      }
    };
    // 先立即查一次,再轮询订单详情感知 payType 是否从信用支付回落到普通支付。
    await checkCreditPayFallback();
    if (creditPayFallbackActiveOrderIdRef.current !== resolvedOrderId) {
      return;
    }
    creditPayFallbackCheckTimerRef.current = setInterval(() => {
      void checkCreditPayFallback();
    }, 1000);
    creditPayLoadingTimerRef.current = setTimeout(() => {
      clearCreditPayFallbackRuntime();
      Taro.redirectTo({
        url: '/pages/robotaxi/home/index',
      });
    }, 10000);
  }, [clearCreditPayFallbackRuntime]);
  useEffect(() => {
    if (tripStatus === TripStatus.TripFinished) {
      void handleCreditPayTripFinished(orderId);
      return () => {
        clearCreditPayFallbackRuntime();
      };
    } else {
      clearCreditPayFallbackRuntime();
    }
    return () => {
      clearCreditPayFallbackRuntime();
    };
  }, [tripStatus, orderId, handleCreditPayTripFinished, clearCreditPayFallbackRuntime]);
  /**
   * 信用分流程未完成时,统一取消订单并终止发单。
   */
  const abortSignedCreditPayFlow = useCallback(async (reason: 'unauthorized' | 'launch_failed', fallbackOrderId?: string) => {
    const targetOrderId = getOrderId(orderId) || fallbackOrderId;
    console.log('[信用分流程中止]', {
      reason,
      orderId: targetOrderId
    });
    stopCallSubmittingRef.current?.();
    syncWaitingSignedCreditPayResult(false);
    pendingPublishingAfterSignedCreditPayRef.current = false;
    pendingSignedCreditPayTripStatusRef.current = null;
    pendingTripStatusAfterPublishingAnimationRef.current = null;
    isHoldingTripStatusDuringPublishingAnimationRef.current = false;
    if (!targetOrderId) {
      clearActiveOrderRuntimeRef.current?.();
      restartPlanningRouteRef.current?.();
      return;
    }
    try {
      await cancelOrder(targetOrderId);
      // Taro.showToast({
      //   title: reason === 'launch_failed' ? '拉起信用分失败,已取消发单' : '未完成信用分授权,已取消发单',
      //   icon: 'none'
      // });
      clearActiveOrderRuntimeRef.current?.();
      if (restartPlanningRouteRef.current) {
        restartPlanningRouteRef.current();
        return;
      }
      setTripStatus(TripStatus.PublishRoute);
      tripStatusRef.current = TripStatus.PublishRoute;
      Taro.setStorageSync('tripStatus', TripStatus.PublishRoute);
    } catch (error) {
      console.log('[信用分流程中止][取消订单失败]', {
        reason,
        error
      });
      Taro.showToast({ title: '取消订单失败,请重试', icon: 'none' });
    }
  }, [orderId, syncWaitingSignedCreditPayResult]);
  /**
   * 信用分页面返回但未拿到 query_id,视为未授权。
   */
  const handleSignedCreditPayUnauthorizedReturn = useCallback((targetOrderId?: string) => {
    return abortSignedCreditPayFlow('unauthorized', targetOrderId);
  }, [abortSignedCreditPayFlow]);
  /**
   * 信用分页面拉起失败,直接终止本次发单。
   */
  const handleSignedCreditPayLaunchFailed = useCallback((targetOrderId?: string) => {
    return abortSignedCreditPayFlow('launch_failed', targetOrderId);
  }, [abortSignedCreditPayFlow]);
  const { openCreditPayScoreUse } = useCreditPayReturn({
    orderId,
    // 信用下单链路回跳后,有 query_id 且结果为 DOING 或已确认时,继续正常发单。
    onAuthorizedReturn: () => resumeTripStatusAfterSignedCreditPayReturn(),
    // 授权结果为失败/撤销等,立即取消订单并终止发单。
    onUnauthorizedReturn: handleSignedCreditPayUnauthorizedReturn,
    // 拉起失败同样取消订单并终止发单。
    onLaunchFailed: handleSignedCreditPayLaunchFailed
    // 信用下单链路回跳后仅关闭监听,不再主动查询支付结果。
    onReturn: () => {}
  });
  useCashierPayListener({
@@ -1722,30 +1514,14 @@
  /**
   * 处理已签约态支付分支付。
   */
  const handleSignedCreditPayment = useCallback((value: SignedOrderPaymentValue, targetOrderId?: string) => {
  const handleSignedCreditPayment = useCallback((value: SignedOrderPaymentValue) => {
    if (Number(value?.payType) !== RobotaxiSignedPayType.WechatCredit) {
      Taro.showToast({ title: '暂不支持当前支付方式', icon: 'none' });
      return false;
      return;
    }
    pendingPublishingAfterSignedCreditPayRef.current = true;
    pendingSignedCreditPayTripStatusRef.current = null;
    syncWaitingSignedCreditPayResult(true);
    const launched = openCreditPayScoreUse(value.packageValue, targetOrderId);
    if (!launched) {
      pendingPublishingAfterSignedCreditPayRef.current = false;
      syncWaitingSignedCreditPayResult(false);
    }
    return launched;
  }, [openCreditPayScoreUse, syncWaitingSignedCreditPayResult]);
  useEffect(() => {
    if (tripStatus !== TripStatus.Publishing) {
      syncWaitingSignedCreditPayResult(false);
      isHoldingTripStatusDuringPublishingAnimationRef.current = false;
      pendingTripStatusAfterPublishingAnimationRef.current = null;
    }
  }, [tripStatus, syncWaitingSignedCreditPayResult]);
    openCreditPayScoreUse(value.packageValue);
  }, [openCreditPayScoreUse]);
  const orderActions = useOrderActions({
    tripStatus,
@@ -1784,7 +1560,6 @@
    routeRequestRouteAndFare,
    handleUnsignedPayment,
    handleSignedCreditPayment,
    handleCreditPayTripFinished,
    setStartSite
  });
@@ -1796,14 +1571,8 @@
    handlePickupTimeoutAutoCancel,
    handleConfirmOverRoute,
    handleFinishCountdownTimeout,
    handlePay,
    stopCallSubmitting,
    clearActiveOrderRuntime,
    restartPlanningRoute
    handlePay
  } = orderActions;
  stopCallSubmittingRef.current = stopCallSubmitting;
  clearActiveOrderRuntimeRef.current = clearActiveOrderRuntime;
  restartPlanningRouteRef.current = restartPlanningRoute;
  const {
    authSuccess: bluetoothAuthSuccess,
    startAuth: startBluetoothAuth,
@@ -1855,14 +1624,6 @@
  useDidShow(() => {
    setPageDidShowVersion((v) => v + 1);
    setDoorUnlockedInCurrentPage(false);
    // 信用分结果页返回后,需要先保留“发布中”动画,不要立刻走页面恢复链路把状态顶到最新。
    if (
      isWaitingSignedCreditPayResultRef.current
      || isHoldingTripStatusDuringPublishingAnimationRef.current
    ) {
      updateMapViewportPadding();
      return;
    }
    handleDidShow(router.params?.skipPageFlag, router.params?.fromModifyDestination);
    updateMapViewportPadding();
    // 完成态下隐藏小程序再恢复时,受控中心点可能与原生地图实际中心脱钩,主动触发一次
@@ -2375,7 +2136,6 @@
    elapsedSeconds,
    endSite: effectiveEndSite,
    callImmediately: handleCallImmediately,
    isWaitingSignedCreditPayResult,
    handleEstimateSelectSite,
    fareEstimate,
    handleOpenCouponSelect,
@@ -2386,7 +2146,6 @@
    handleOpenCancelPopupWithType,
    handlePickupTimeoutAutoCancel,
    setTripStatus,
    handlePublishingAnimationFinish,
    finishCountdownEnabled,
    orderId,
    vehicleInfo,
src/robotaxi/pages/operating-area/index.less
@@ -123,7 +123,7 @@
      border-radius: 24px;
      padding: 32rpx 32rpx 36rpx 32rpx;
      box-sizing: border-box;
      max-height: 410rpx;
      height: 410rpx;
      overflow: auto;
      .content-title {
src/robotaxi/pages/operating-area/index.tsx
@@ -11,7 +11,7 @@
const DEFAULT_MAP_LONGITUDE = 116.397128;
const DEFAULT_MAP_LATITUDE = 39.916527;
const MAP_INCLUDE_POINTS_PADDING = [120, 10, 50, 10];
const MAP_INCLUDE_POINTS_PADDING = [10, 10, 10, 10];
// includePoints 缩放动画的预估时长,动画结束后再显示地图,避免“先展示再放大”的跳动
const MAP_FIT_ANIMATION_DURATION = 700;
const POLYGON_STROKE_COLOR = '#DFB369'; // rgb(223, 179, 105)
@@ -348,7 +348,7 @@
        // scale={30}
        polygons={polygons}
        showLocation={false}
        style={{ width: '100%', height: '70%' }}
        style={{ width: '100%', height: '65%' }}
        onPolygonTap={handlePolygonTap}
        onTap={handleMapTap}
      >
@@ -395,14 +395,14 @@
            </View>
            <View className="content-desc">
              <View className="desc-item">
                <Text className="text">各站点运营时间可能存在调整,实际运营情况请以页面实时展示为准</Text>
                <Text className="text">1. 运营时间内可正常使用打车服务,超出运营时间无法使用打车功能</Text>
              </View>
               {/* <View className="desc-item">
               <View className="desc-item">
                <Text className="text">2. 各站点运营时间可能存在差异,站点运营情况请依照实际情况</Text>
              </View>
               <View className="desc-item">
                <Text className="text">3. 有问题可联系区域负责人,联系电话:4008208820</Text>
              </View> */}
              </View>
            </View>
          </View>
        </View>
src/robotaxi/pages/order/index.tsx
@@ -7,12 +7,6 @@
  OrderHistoryGroup
} from "../../../robotaxi/api/order";
import { _INVOICE_CHARGE_URL } from "../../../constants/api";
import {
  clearOrderTripStorage,
  mapOrderStatusToTripStatus
} from "../../../utils/Robotaxi-public-method";
// import { hasActiveTripOrderInStorage } from "../../../utils/order";
import { hasActiveTripOrderInStorage } from '../../utils/order';
type OrderFilterKey = "all" | "pendingPay" | "completed" | "cancelled";
@@ -140,13 +134,8 @@
      formatOrderStatus(item.status) == "进行中" ||
      formatOrderStatus(item.status) == "待支付"
    ) {
      Taro.setStorageSync("orderId", item.orderId || "");
      Taro.setStorageSync(
        "tripStatus",
        mapOrderStatusToTripStatus(item.status || 1)
      );
      Taro.navigateTo({
        url: "/robotaxi/pages/begin-route/index?from=order"
        url: "/robotaxi/pages/begin-route/index"
      });
      return;
    }
@@ -156,13 +145,6 @@
  };
  const againOrder = (item: any) => {
    if (hasActiveTripOrderInStorage()) {
      Taro.navigateTo({
        url: "/robotaxi/pages/begin-route/index?from=order"
      });
      return;
    }
    Taro.setStorageSync("startSite", {
      id: item.startPointId || "",
      name: item.startPointName || "",
@@ -179,9 +161,8 @@
      electronicAreaId: item.xpElectronicFenceAreaId || "",
      time: item.endParkingTimeLimit || 0
    });
    clearOrderTripStorage();
    Taro.navigateTo({
      url: "/robotaxi/pages/begin-route/index?from=order"
      url: "/robotaxi/pages/begin-route/index"
    });
  };
@@ -243,15 +224,6 @@
    }
    if (status == 10) {
      return "已完成";
    }
    if (status == 11) {
      return "退款中";
    }
    if (status == 12) {
      return "已退款";
    }
    if (status == 13) {
      return "退款失败";
    }
  };
@@ -317,7 +289,7 @@
                        <View
                          onClick={e => {
                            e.stopPropagation();
                            toOrderDetail(item);
                            againOrder(item);
                          }}
                        >
                          <View
@@ -329,7 +301,7 @@
                        </View>
                      )}
                      {/* 发票功能暂未上线,屏蔽入口 */}
                      { ["已完成", "待评价"].includes(
                      {false && ["已完成", "待评价"].includes(
                        formatOrderStatus(item.status)
                      ) &&
                        item.invoiceStatus != 2 &&
@@ -348,7 +320,7 @@
                            </View>
                          </View>
                        )}
                      {["已完成", "已取消", "待评价", "退款中", "已退款", "退款失败"].includes(
                      {["已完成", "已取消", "待评价"].includes(
                        formatOrderStatus(item.status)
                      ) &&
                        canAgainOrder(item) && (
src/robotaxi/pages/passenger-notice/index.tsx
@@ -14,7 +14,7 @@
function PassengerNotice() {
  const [content, setContent] = useState('');
  const [title, setTitle] = useState('乘车须知');
  // const [title, setTitle] = useState('乘车须知');
  const RIDE_NOTICE_TYPE = 5; // 乘车须知协议类型
  const normalizeContent = (rawContent: string) => {
@@ -51,7 +51,7 @@
    getLoginAgreementContentInfo(typeParam || '').then((res: any) => {
      const target = resolveAgreementItem(res);
      if (target) {
        setTitle(String(target.name || '乘车须知'));
        // setTitle(String(target.name || '乘车须知'));
        setContent(normalizeContent(target.content || ''));
        console.log('normalizeContent(target.content ||', normalizeContent(target.content || ''));
        return;
@@ -64,7 +64,7 @@
  return (
    <View className='passenger-notice'>
      <View className="passenger-notice-title">{title}</View>
      {/* <View className="passenger-notice-title">{title}</View> */}
      <View className="passenger-notice-content">
        <RichText nodes={content} />
      </View>
src/robotaxi/pages/payment-setting-detail/index.tsx
@@ -2,7 +2,6 @@
import { View, Text, Image } from '@tarojs/components';
import { useCallback, useState } from 'react';
import { getPayPwd, RobotaxiPaySettingStatus, setPayPwd } from '../../api/payment';
import { getOrderActive } from '../../api/home';
import { withRobotaxiWhitelist } from '../../../utils/whitelist';
import './index.less';
@@ -33,29 +32,6 @@
  }, []);
  /**
   * 关闭免密支付前,先确认当前没有进行中的订单。
   */
  const ensureNoActiveOrderBeforeClose = useCallback(async () => {
    try {
      const activeOrder = await getOrderActive();
      if (activeOrder) {
        Taro.showToast({
          title: '有进行中的订单,暂无法关闭服务',
          icon: 'none'
        });
        return false;
      }
      return true;
    } catch (error) {
      Taro.showToast({
        title: '查询订单状态失败,请稍后重试',
        icon: 'none'
      });
      return false;
    }
  }, []);
  /**
   * 关闭微信免密支付。
   */
  const handleClosePayment = async () => {
@@ -75,14 +51,8 @@
      return;
    }
    setIsOperating(true);
    const canClosePayment = await ensureNoActiveOrderBeforeClose();
    if (!canClosePayment) {
      setIsOperating(false);
      return;
    }
    try {
      setIsOperating(true);
      await setPayPwd(RobotaxiPaySettingStatus.Disable);
      Taro.showToast({
        title: '微信免密支付已关闭',
src/robotaxi/pages/personal-center/index.tsx
@@ -33,7 +33,7 @@
const toolMenuList: ToolMenuItem[] = [
  { key: "service", label: "联系客服" },
  { key: "invoice", label: "开发票" }, // 暂未上线,屏蔽入口
  // { key: "invoice", label: "开发票" }, // 暂未上线,屏蔽入口
  { key: "payment", label: "支付设置" },
  { key: "favorite", label: "收藏站点" }
];
src/robotaxi/pages/select-map-site/index.less
@@ -201,11 +201,7 @@
                left: 50%;
                top: 100%;
                transform: translate(-50%, -50%);
<<<<<<< HEAD
                width: 28px;
=======
                width: 18px;
>>>>>>> feature_v2.4.0
                height: 28px;
                z-index: -1;
            }
@@ -401,11 +397,7 @@
            margin-top: 32px;
            font-size: 32px;
            font-weight: 500;
<<<<<<< HEAD
            color: @gold-text;
=======
            color: #141E27;
>>>>>>> feature_v2.4.0
            display: flex;
            align-items: center;
            height: 120px;
@@ -443,18 +435,11 @@
            align-items: center;
            border-radius: 1000px;
            box-sizing: border-box;
<<<<<<< HEAD
            border: 4px solid #141E27;
            font-size: 32px;
            letter-spacing: normal;
            color: #141E27;
            font-weight: 760;
=======
            border: 2px solid #141E27;
            font-size: 28px;
            letter-spacing: normal;
            color: #141E27;
>>>>>>> feature_v2.4.0
        }
        .no-confirm {
src/robotaxi/pages/share-trip/index.less
@@ -516,11 +516,7 @@
// 浮窗底部的钻石指示图标,对齐 begin-route .callout-diamond-icon
.callout-diamond-icon {
<<<<<<< HEAD
  width: 28px;
=======
  width: 18px;
>>>>>>> feature_v2.4.0
  height: 28px;
  margin-top: -14px;
  flex-shrink: 0;
src/robotaxi/pages/site-search/index.less
@@ -45,13 +45,8 @@
    }
    .end-icon {
<<<<<<< HEAD
      background: @gold-light ;
    } 
=======
      background: @black-text-main;
    }
>>>>>>> feature_v2.4.0
    .search-input {
      flex: 1;
@@ -176,15 +171,9 @@
      justify-content: center;
      .collect-icon {
<<<<<<< HEAD
        width: 40px;
        height: 40px;
        margin-bottom: 4px;
=======
        width: 32px;
        height: 32px;
        margin-bottom: 8px;
>>>>>>> feature_v2.4.0
      }
      .history-distance {
src/robotaxi/utils/login-agreement.ts
@@ -56,5 +56,5 @@
      ...normalized.slice(insertIndex),
    ];
  }
  return [...normalized];
  return [...normalized, RIDE_NOTICE_ITEM];
};