hejianhao
2026-06-29 89ee603ba8676c8eb5f5be6da7d9e4b192b97874
feat(robotaxi): 优化多页面样式与交互功能
15个文件已修改
159 ■■■■■ 已修改文件
src/pages/robotaxi/home/index.less 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/calling-car-modules/temperature-control.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/calling-car-modules/vehicle-info-card.tsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/calling-car.less 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/evaluate-popup.less 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/passenger-notice.less 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/release-route.less 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/evaluate-popup.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.less 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/expense-description/index.tsx 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/order/detail/index.less 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/share-trip/hooks/use-view-delegates.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/site-search/index.tsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/index.less
@@ -736,7 +736,6 @@
    .activity-item {
      margin-bottom: 24px;
      border: 2px solid #fff;
      border-radius: 24px;
      height: 190px;
src/robotaxi/pages/begin-route/components/calling-car-modules/temperature-control.tsx
@@ -52,7 +52,7 @@
    const canAdjustTemperature = canToggleSwitch && acStatusLoaded && acSwitchOn && typeof tempStatus === 'number';
    // 温度展示文案:到达最高温显示 HI,到达最低温显示 LO,其余显示具体温度值
    const tempDisplayText = typeof tempStatus === 'number'
        ? (tempStatus >= TEMP_MAX ? 'HI' : (tempStatus <= TEMP_MIN ? 'LO' : `${tempStatus.toFixed(1)}°C`))
        ? (tempStatus >= TEMP_MAX ? 'HI' : (tempStatus <= TEMP_MIN ? 'LO' : `${tempStatus.toFixed(1)}℃`))
        : '--';
    const isAtMinTemperature = typeof tempStatus === 'number' && tempStatus <= TEMP_MIN;
    const isAtMaxTemperature = typeof tempStatus === 'number' && tempStatus >= TEMP_MAX;
src/robotaxi/pages/begin-route/components/calling-car-modules/vehicle-info-card.tsx
@@ -18,9 +18,10 @@
            <View>
                <View className="car-card-detail-num">{vehicleInfo?.plateNumber}</View>
                <View className="car-card-detail-color">
                    {vehicleInfo?.vehicleColor}
                    {/* <View className="car-card-detail-color-line"></View>
                    车身编码: {vehicleInfo?.vehicleCode} */}
                    <View className="car-card-detail-color-text">小鹏GX</View>
                    <View className="car-card-detail-color-line"></View>
                    <View className="car-card-detail-color-text">{vehicleInfo?.vehicleColor}</View>
                    {/* 车身编码: {vehicleInfo?.vehicleCode} */}
                </View>
            </View>
            {
src/robotaxi/pages/begin-route/components/css-folder/calling-car.less
@@ -10,7 +10,7 @@
.calling-car {
  position: relative;
  padding: 38px 42px 68px 34px;
  padding: 40px 42px 68px 34px;
  background: #f2f3f7;
  border-top: 2px solid #fff;
  border-radius: 40px 40px 0 0;
@@ -29,6 +29,7 @@
    z-index: 1;
    display: flex;
    justify-content: space-between;
    margin-bottom: 40px;
    &-title {
      font-size: 32px;
@@ -114,9 +115,13 @@
        margin-top: 4px;
        display: flex;
        align-items: center;
        font-size: 24px;
        letter-spacing: normal;
        color: rgba(0, 0, 0, 0.6);
        &-text {
          font-size: 24px;
          line-height: 44px;
          color: rgba(0, 0, 0, 0.6);
          letter-spacing: normal;
        }
        &-line {
          width: 1.4px;
@@ -144,14 +149,14 @@
        flex: 1;
        border-radius: 16px;
        background: #F5F6FA;
        padding: 24px 0;
        padding: 34px 0;
        display: flex;
        align-items: center;
        justify-content: space-between;
        &-btn {
          flex-shrink: 0;
          padding: 34px 24px;
          padding: 24px;
          display: flex;
          align-items: center;
@@ -166,7 +171,7 @@
          flex-direction: column;
          align-items: center;
          justify-content: center;
          gap: 20px;
          gap: 16px;
          &-temp {
            font-size: 52px;
@@ -177,7 +182,6 @@
          }
          &-desc {
            /*  */
            font-size: 24px;
            font-weight: normal;
            line-height: 24px;
@@ -222,7 +226,7 @@
        &-text {
          font-size: 24px;
          font-weight: normal;
          line-height: 35px;
          line-height: 40px;
          letter-spacing: normal;
          color: rgba(0, 0, 0, 0.9);
        }
@@ -469,10 +473,8 @@
    &-item {
      display: flex;
      align-items: center;
      justify-content: center;
      box-sizing: border-box;
      flex: 1;
      &-disabled {
        opacity: 0.4;
      }
@@ -549,6 +551,7 @@
      margin-top: 28px;
      display: flex;
      align-items: center;
      margin-bottom: 16px;
      gap: 30px;
      height: 156px;
      text-align: center;
@@ -726,7 +729,6 @@
.bluetooth-operate-card {
  position: relative;
  z-index: 1;
  margin-top: 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
@@ -767,4 +769,4 @@
      height: 17.5px;
    }
  }
}
}
src/robotaxi/pages/begin-route/components/css-folder/evaluate-popup.less
@@ -67,13 +67,13 @@
                &-content {
                    margin-top: 24px;
                    display: flex;
                    flex-wrap: wrap;
                    gap: 24px;
                    display: grid;
                    grid-template-columns: 1fr 1fr;
                    gap: 20px 34px;
                    &-item {
                        padding: 0 40px;
                        height: 60px;
                        padding: 0 16px;
                        height: 64px;
                        display: flex;
                        justify-content: center;
                        align-items: center;
@@ -82,9 +82,17 @@
                        box-sizing: border-box;
                        border: 2px solid rgba(0, 0, 0, 0.2);
                        font-size: 28px;
                        line-height: 44px;
                        letter-spacing: normal;
                        color: rgba(0, 0, 0, 0.6);
                        min-width: 0;
                        &-text {
                            display: block;
                            max-width: 100%;
                            overflow: hidden;
                            white-space: nowrap;
                            text-overflow: ellipsis;
                        }
                    }
                    .active-tag {
@@ -254,4 +262,4 @@
            background: linear-gradient(97deg, #8475FF 0%, #7DD6FF 103%);
        }
    }
}
}
src/robotaxi/pages/begin-route/components/css-folder/passenger-notice.less
@@ -21,8 +21,8 @@
        left: 0;
        right: 0;
        background: #ffffff;
        border-radius: 16px 16px 0 0;
        padding: 48px 45px 88px 45px;
        border-radius: 40px 40px 0 0;
        padding: 48px 18px 68px 48px;
        height: 75vh;
        overflow: hidden;
        .passenger-content-bg {
@@ -68,7 +68,7 @@
                top: 0;
                width: 6px;
                height: 100%;
                background-color: rgba(0, 0, 0, 0.05);
                background-color: rgba(0, 0, 0, 0.03);
                border-radius: 4px;
                z-index: 10;
            }
@@ -79,7 +79,7 @@
                right: 0;
                top: 0;
                width: 6px;
                background-color: rgba(0, 0, 0, 0.25);
                background-color: rgba(0, 0, 0, 0.05);
                border-radius: 4px;
                z-index: 11;
            }
@@ -89,7 +89,7 @@
            margin-top: 32px;
            display: flex;
            align-items: center;
            gap: 4px;
            gap: 8px;
            font-size: 24px;
            letter-spacing: normal;
            color: rgba(0, 0, 0, 0.6);
@@ -103,6 +103,7 @@
        &-btn {
            margin-top: 30px;
            margin-right: 32px;
            border-radius: 16px;
            background: linear-gradient(96deg, #8475FF -1%, #7DD6FF 103%);
            line-height: 96px;
src/robotaxi/pages/begin-route/components/css-folder/release-route.less
@@ -316,7 +316,7 @@
                border-radius: 6px;
                background: rgba(245, 137, 0, 0.06);
                box-sizing: border-box;
                border: 1px solid rgba(245, 137, 0, 0.2);
                border: 2px solid #F58900;
                line-height: 30px;
                text-align: center;
                padding: 0px 6px;
@@ -396,7 +396,7 @@
                        line-height: 40px;
                        letter-spacing: normal;
                        color: rgba(0, 0, 0, 0.9);
                        margin-bottom: 2px;
                        margin-bottom: 10px;
                        font-weight: 500;
                    }
                }
src/robotaxi/pages/begin-route/components/evaluate-popup.tsx
@@ -14,9 +14,21 @@
    orderId?: string;
    orderRating?: number;
    submitMode?: 'comment' | 'complaint';
    /**
     * 是否隐藏问题类型选择
     */
    hideFeedbackType?: boolean;
}
export default function EvaluatePopup({ show = false, onClose, onConfirm, orderId, orderRating, submitMode = 'comment' }: Props) {
export default function EvaluatePopup({
    show = false,
    onClose,
    onConfirm,
    orderId,
    orderRating,
    submitMode = 'comment',
    hideFeedbackType = false
}: Props) {
    const activeBad = 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/active-bad.png';
    const activeNormal = 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/active-normal.png';
    const activeGood = 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/active-good.png';
@@ -68,6 +80,8 @@
        1: 3
    };
    const evaluateDimension = evaluateDimensionMap[currentOrderRating] || 3; // 接口维度:1 满意,2 一般,3 不满意
    const shouldRequireFeedbackType = !hideFeedbackType;
    const canSubmit = shouldRequireFeedbackType ? !!selectedTypeId && !!feedbackContent.trim() : !!feedbackContent.trim();
    // 控制弹窗开合动画
    useEffect(() => {
@@ -98,7 +112,7 @@
        if (isSubmittingRef.current) {
            return;
        }
        if (!selectedTypeId) {
        if (shouldRequireFeedbackType && !selectedTypeId) {
            Taro.showToast({
                title: '请选择问题类型',
                icon: 'none'
@@ -134,13 +148,16 @@
                .filter(p => p.status === 'success' && p.server && p.server.id && p.server.url)
                .map(p => ({ id: p.server!.id, name: p.server!.name, url: p.server!.url }))
        );
        submitter({
        const payload: any = {
            orderRating: orderRating ?? 1,
            feedbackTypeId: selectedTypeId,
            feedbackContent,
            feedbackPictures: picturePayload,
            orderId: targetOrderId
        }).then((res: any) => {
        };
        if (!hideFeedbackType && selectedTypeId) {
            payload.feedbackTypeId = selectedTypeId;
        }
        submitter(payload).then((res: any) => {
            const isFailure = res?.success === false || (typeof res?.code === 'number' && res.code !== 0);
            if (isFailure) {
                Taro.showToast({
@@ -199,14 +216,18 @@
                    <View>{popupDisplayConfig.title}</View>
                </View>
                <View className='content-box'>
                    <View className='evaluate-problem-type'>
                        <View className='evaluate-problem-type-title'>反馈的问题类型:</View>
                        <View className='evaluate-problem-type-content'>
                            {typeOptions.map((item) => (
                                <View key={item?.id} className={`evaluate-problem-type-content-item ${selectedTypeId === item?.id && 'active-tag'}`} onClick={() => setSelectedTypeId(item?.id)}>{item?.tagContent}</View>
                            ))}
                    {!hideFeedbackType && (
                        <View className='evaluate-problem-type'>
                            <View className='evaluate-problem-type-title'>反馈的问题类型:</View>
                            <View className='evaluate-problem-type-content'>
                                {typeOptions.map((item) => (
                                    <View key={item?.id} className={`evaluate-problem-type-content-item ${selectedTypeId === item?.id && 'active-tag'}`} onClick={() => setSelectedTypeId(item?.id)}>
                                        <Text className='evaluate-problem-type-content-item-text'>{item?.tagContent}</Text>
                                    </View>
                                ))}
                            </View>
                        </View>
                    </View>
                    )}
                    <View className='evaluate-problem-desc-box'>
                        <Textarea
                            className='evaluate-problem-desc'
@@ -257,7 +278,7 @@
                    </View>
                </View>
                <View className='evaluate-content-confirm'>
                    <View className={`evaluate-content-confirm-btn ${(selectedTypeId && feedbackContent) && 'ok-btn'}`} onClick={submit}>提交反馈</View>
                    <View className={`evaluate-content-confirm-btn ${canSubmit && 'ok-btn'}`} onClick={submit}>提交反馈</View>
                </View>
            </View>
        </View>
src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx
@@ -232,7 +232,7 @@
            {routeDistance?.unit === "m" ? "米" : "公里"}
          </View>
          <View
            style={{ marginLeft: "2.5px", marginBottom: 0 }}
            style={{ marginLeft: "2px", marginBottom: 0 }}
            className="car-time-num"
          >
            {durationDisplay.value}
@@ -401,6 +401,7 @@
      >
        {item.isRouteSummaryBubble ? (
          routeSummaryText ? (
            // 路由摘要气泡
            <CoverView className="route-summary-callout">
              <CoverImage
                className="route-summary-callout-bg"
@@ -438,8 +439,8 @@
                    }}
                  >
                    {item.name}
                    {!deps.isAndroid && (
                      <CoverView style={{ color: "transparent" }}>占</CoverView>
                    {!deps.isAndroid && item.name.length > 16 && (
                      <CoverView style={{ color: "transparent",width: "3px" }}>占</CoverView>
                    )}
                  </CoverView>
                  {deps.isAndroid && (
@@ -489,7 +490,7 @@
                      {deps.routeDistance?.unit === "m" ? "米" : "公里"}
                    </CoverView>
                    <CoverView
                      style={{ marginLeft: "2.5px" }}
                      style={{ marginLeft: "2px" }}
                      className="car-time-num"
                    >
                      {vehicleMetricDurationDisplay.value}
src/robotaxi/pages/begin-route/index.less
@@ -67,7 +67,7 @@
            /* 相对于父级(底部卡片容器)顶部 */
            margin-bottom: 24px;
            /* 距离底部卡片24px */
            right: 24px;
            right: 32px;
            z-index: 1;
            display: flex;
            flex-direction: column;
@@ -191,10 +191,11 @@
}
.car-time-num {
    font-size: 36px;
    font-size: 28px;
    letter-spacing: normal;
    color: #6D7FD9;
    margin-bottom: -4px;
    margin-right: 2px;
}
.custom-callout-icon {
src/robotaxi/pages/begin-route/index.tsx
@@ -989,7 +989,7 @@
      width: 1,
      height: 1,
      alpha: 0,
      zIndex: 3,
      zIndex: 0,
      isRouteSummaryBubble: true,
      customCallout: { anchorY: 22, anchorX: 42, display: 'ALWAYS' }
    };
src/robotaxi/pages/expense-description/index.tsx
@@ -264,6 +264,7 @@
        orderId={orderId}
        orderRating={1}
        submitMode="complaint"
        hideFeedbackType
        onClose={() => setShowEvaluatePopup(false)}
        onConfirm={() => {
          setShowEvaluatePopup(false);
src/robotaxi/pages/order/detail/index.less
@@ -237,7 +237,7 @@
          width: 8px;
          height: 8px;
          z-index: 0;
          background: #65C3FC;
          background: #8CB654;
          border-radius: 50%;
          margin-right: 16px;
          flex-shrink: 0;
@@ -254,7 +254,7 @@
        }
        .first-icon {
          background: #768AFF;
          background: #6D7FD9;
        }
      }
src/robotaxi/pages/share-trip/hooks/use-view-delegates.tsx
@@ -111,7 +111,7 @@
          <CoverView className={`custom-callout-content ${deps.isAndroid && 'txt-center '}`} style={{ zIndex: 1 }}>
            <CoverView style={{ lineHeight: '22px', whiteSpace: 'nowrap', display: 'flex' }}>
              {item.name}
              {!deps.isAndroid && <CoverView style={{ color: 'transparent' }}>占</CoverView>}
              {!deps.isAndroid && item.name.length > 16 && <CoverView style={{ color: "transparent",width: "3px" }}>占</CoverView>}
            </CoverView>
            {deps.isAndroid && <CoverView style={{ width: '2px' }}></CoverView>}
            {deps.tripStatus === TripStatus.PublishRoute && (
src/robotaxi/pages/site-search/index.tsx
@@ -62,6 +62,7 @@
  completeConfirmRideSelectionSession,
  writeConfirmRideSiteSourceType
} from '../../constants/confirm-ride-report';
import { hasActiveTripOrderInStorage } from '../../utils/order';
import { withRobotaxiWhitelist } from '../../../utils/whitelist';
function SiteSearchPage() {
@@ -126,6 +127,15 @@
    item: any,
    sourceType = UNKNOWN_CONFIRM_RIDE_SOURCE_TYPE
  ) => {
    // 检查是否有行程订单
    const modifySession = Taro.getStorageSync(MODIFY_DESTINATION_SESSION_KEY);
    if (!modifySession?.active && hasActiveTripOrderInStorage()) {
      Taro.reLaunch({
        url: '/robotaxi/pages/begin-route/index?skipPageFlag=1',
      });
      return;
    }
    // 检查起终点是否在同一运营区域
    const resolvedDistanceConfig = await ensureDistanceConfigReady();
    const startSiteCache = Taro.getStorageSync('startSite');
    if (startSiteCache?.electronicAreaId && item?.electronicAreaId && startSiteCache.electronicAreaId !== item.electronicAreaId) {
@@ -146,7 +156,7 @@
        return;
      }
    } catch { }
    const modifySession = Taro.getStorageSync(MODIFY_DESTINATION_SESSION_KEY);
    // 检查是否与上一个选择的终点相同
    if (modifySession?.active && isSameModifyDestinationSite(modifySession?.previousEndSite, item)) {
      Taro.setStorageSync(MODIFY_DESTINATION_PENDING_SAME_SITE_TOAST_KEY, 1);
    }