hejianhao
2026-02-26 7050bf0d809f4b542ff6015d76685bc9f91fe262
style(robotaxi): 调整样式细节并优化代码逻辑

- 统一多个组件的圆角大小和边框样式
- 优化优惠券页面布局和状态显示
- 移除未使用的IP定位工具函数
- 简化API响应处理逻辑
- 修复文本溢出和依赖项问题
13个文件已修改
224 ■■■■■ 已修改文件
src/pages/robotaxi/home/components/privacy-popup/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/index.less 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/index.tsx 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/api/coupon.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/calling-car.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/calling-car.less 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/css-folder/release-route.less 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.tsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/coupon/index.less 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/coupon/index.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/expense-description/index.less 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/expense-description/index.tsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/Robotaxi-public-method.ts 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/components/privacy-popup/index.tsx
@@ -104,7 +104,7 @@
        <View className='privacy-text'>
          <Text className='text-content'>
            欢迎使用小鹏Robotaxi App!为了更好地保障您的个人权益,我们将通过 《用户服务协议》、《隐私政策》、以及《关于路Robotaxi平台向第三方提供个人信息情况的说明》、《关于关于路Robotaxi平台向第三方提供个人信息情况的说明》等文档来保护您的个人信息。
            欢迎使用小鹏Robotaxi App!为了更好地保障您的个人权益,我们将通过 《用户服务协议》、《隐私政策》、以及《关于路Robotaxi平台向第三方提供个人信息情况的说明》、《关于关于路Robotaxi平台向第三方提供个人信息情况的说明》等文档来保护您的个人信息。
          </Text>
          <View className='txt-tip'>我已满十四周岁,阅读并同意:</View>
        </View>
src/pages/robotaxi/home/index.less
@@ -225,7 +225,7 @@
  background-color: transparent;
  overflow: hidden;
  margin-top: -52px;
  border-radius: 32px 32px 0 0;
  border-radius: 38px 38px 0 0;
  .select-site {
    position: relative;
@@ -280,6 +280,13 @@
            line-height: 44px;
            letter-spacing: normal;
            color: rgba(0, 0, 0, 0.9);
            overflow: hidden;
            display: -webkit-box;
            -webkit-line-clamp: 1;
            /* 设置最大显示行数 */
            -webkit-box-orient: vertical;
            text-overflow: ellipsis;
            word-break: break-all;
            .now-site-address-text {
              margin: 0 2px;
@@ -464,7 +471,8 @@
    .activity-item {
      margin-bottom: 24px;
      border-top: 2px solid #fff;
      border: 2px solid #fff;
      border-radius: 32px;
      .activity-img {
        border-radius: 32px;
src/pages/robotaxi/home/index.tsx
@@ -283,7 +283,7 @@
  // 监听 Banner 列表变化,重新计算高度
  useEffect(() => {
    calculateBoxHeight();
  }, [bannerList]);
  }, [bannerList, tripStatus]);
  // 监听城市变化,更新电子围栏
  useEffect(() => {
@@ -831,7 +831,7 @@
              {
                [4, 5, 6, 7].includes(tripStatus) &&
                <View className="order-status-left">
                  <Image className="order-status-left-icon" src='https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/e76e8fd6-1f52-482f-b9c0-6a026f4d2797.png' />
                  <Image className="order-status-left-icon" src='https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/552a3a31-e4dd-4a28-8748-fd8b87dd3055.png' />
                  <View className="order-status-left-detail">
                    <View>{orderData.plateNumber}</View>
                    <View>{ORDER_STATUS[tripStatus]}</View>
src/robotaxi/api/coupon.ts
@@ -30,26 +30,12 @@
}
// 优惠券列表
export const getCouponList = async (payload: GetCouponListPayload): Promise<GetCouponListResponse> => {
    const res = await request({
export const getCouponList = (payload: GetCouponListPayload): Promise<GetCouponListResponse> => {
    return request({
        url: _ROBOTAXI_HOST + '/account/api/v1/mini-program/coupon/list',
        method: 'POST',
        payload
    });
    // 手动转换下划线字段为驼峰
    const list = (res.list || []).map((item: any) => ({
        couponId: item.coupon_id,
        title: item.title,
        discountAmount: item.discount_amount,
        expireTime: item.expire_time,
        status: item.status,
    }));
    return {
        total: res.total || 0,
        list
    };
}
// 领取优惠券
@@ -62,19 +48,9 @@
}
// 优惠券详情
export const getCouponDetail = async (couponId: string): Promise<CouponDetail> => {
    const res = await request({
export const getCouponDetail = (couponId: string): Promise<CouponDetail> => {
    return request({
        url: _ROBOTAXI_HOST + `/account/api/v1/mini-program/coupon/detail/${couponId}`,
        method: 'POST'
        method: 'GET'
    });
    // 手动转换下划线字段为驼峰
    return {
        couponId: res.coupon_id,
        title: res.title,
        expireTime: res.expire_time,
        validTimeRange: res.valid_time_range,
        applicableCities: res.applicable_cities || [],
        usageInstructions: res.usage_instructions
    };
}
src/robotaxi/pages/begin-route/components/calling-car.tsx
@@ -177,7 +177,7 @@
            }
            const targetOrderId = orderId || Taro.getStorageSync('orderId');
            if (targetOrderId) {
                // 暂时不调用车辆温度 // 2-12 新增
                // 暂时不调用车辆温度
                setTempStatus(19);
                lastConfirmedTempRef.current = 19;
                // queryTemperatureByOrderId({ orderId: targetOrderId }).then((res: any) => {
@@ -187,17 +187,13 @@
                //         lastConfirmedTempRef.current = currentTemperature;
                //     }
                // }).catch(() => { });
                // 2-12 新增
            }
        } else if (tripStatus === 5) {
            // 已到达上车点:根据限停时间启动倒计时并处理超时
            // 2-12 新增
            const duration = Number(Taro.getStorageSync('orderRouteDuration'));
            if (!Number.isNaN(duration)) {
                setRouteDuration(duration);
            }
            // 2-12 新增
            const s = Taro.getStorageSync('startSite');
            const time = Number(s?.time);
            if (!Number.isNaN(time) && time > 0) {
@@ -430,7 +426,7 @@
                                车身编码: {vehicleInfo?.vehicleCode}
                            </View>
                        </View>
                        <Image className="car-card-detail-img" src={vehicleInfo?.vehiclePictures?.[0].url || 'https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/825d7fa2-6cf6-4a31-aaac-3a4de806e9a3.png'} />
                        <Image className="car-card-detail-img" src={vehicleInfo?.vehiclePictures?.[0].url || 'https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/552a3a31-e4dd-4a28-8748-fd8b87dd3055.png'} />
                    </View>
                    {
                        tripStatus == 4 && <View>
@@ -450,23 +446,13 @@
                    {
                        tripStatus == 5 &&
                        <View className="car-card-arrive">
                            <View className="car-card-arrive-item" onClick={() => handleUnlock('trunk', () => setTrunkStatus((prev) => !prev))}>
                                {
                                    trunkStatus ?
                                        <Image className="car-card-arrive-item-img" src={require('../../../assets/trunk-open.png')} />
                                        :
                                        <Image className="car-card-arrive-item-img" src={require('../../../assets/trunk-close.png')} />
                                }
                                <View className="car-card-arrive-item-text">{trunkStatus ? '关闭后备箱' : '打开后备箱'}</View>
                            <View className="car-card-arrive-item" onClick={() => handleUnlock('trunk', () => setTrunkStatus(true))}>
                                <Image className="car-card-arrive-item-img" src={require('../../../assets/trunk-close.png')} />
                                <View className="car-card-arrive-item-text">打开后备箱</View>
                            </View>
                            <View className="car-card-arrive-item" onClick={() => handleUnlock('door', () => setLockStatus((prev) => !prev))}>
                                {
                                    lockStatus ?
                                        <Image className="car-card-arrive-item-img" src={require('../../../assets/lock-open.png')} />
                                        :
                                        <Image className="car-card-arrive-item-img" src={require('../../../assets/lock-close.png')} />
                                }
                                <View className="car-card-arrive-item-text">{lockStatus ? '加锁车门' : '解锁车门'}</View>
                            <View className="car-card-arrive-item" onClick={() => handleUnlock('door', () => setLockStatus(true))}>
                                <Image className="car-card-arrive-item-img" src={require('../../../assets/lock-close.png')} />
                                <View className="car-card-arrive-item-text">解锁车门</View>
                            </View>
                        </View>
                    }
src/robotaxi/pages/begin-route/components/css-folder/calling-car.less
@@ -1,9 +1,9 @@
.calling-car {
    position: relative;
    padding: 40px 42px 132px 34px;
    padding: 40px 42px 88px 34px;
    background: #F2F3F7;
    border-top: 2px solid #fff;
    border-radius: 32px 32px 0 0;
    border-radius: 38px 38px 0 0;
    &-bg {
        position: absolute;
src/robotaxi/pages/begin-route/components/css-folder/release-route.less
@@ -2,10 +2,11 @@
    .select-site {
        position: relative;
        padding: 32px;
        padding-bottom: 56px;
        padding-top: 40px;
        background: #F2F3F7;
        border-top: 2px solid #fff;
        border-radius: 32px 32px 0 0;
        border-radius: 38px 38px 0 0;
        .site-top-bg {
            position: absolute;
src/robotaxi/pages/begin-route/index.tsx
@@ -433,7 +433,7 @@
      if (routePoints.length > 0) {
        lines.push({
          points: routePoints,
          color: '#6D7FD9',
          color: '#7B91FF',
          width: 10,
          arrowLine: true,
        });
@@ -441,7 +441,7 @@
      if (walkingPoints.length > 0) {
        lines.push({
          points: walkingPoints,
          color: '#6D7FD9',
          color: '#7B91FF',
          width: 6,
          dottedLine: true,
          arrowLine: true,
@@ -659,10 +659,6 @@
      const { orderId } = await saveOrder(payload);
      Taro.setStorageSync('orderId', orderId);
    } catch (error) {
      Taro.showToast({
        title: '下单失败,请重试',
        icon: 'none',
      })
      return
    }
    setTripStatus(2);
src/robotaxi/pages/coupon/index.less
@@ -51,20 +51,29 @@
    /* Firefox */
    .coupon-item {
      position: relative;
      width: 686px;
      height: 204px;
      z-index: 0;
      border-radius: 24px;
      background: #FFFFFF;
      padding: 32px;
      padding-right: 28px;
      margin-bottom: 24px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      .coupon-content {
        display: flex;
        align-items: center;
      }
      .coupon-price {
        display: flex;
        align-items: center;
        flex-shrink: 0;
        margin-right: 48px;
      }
      .price {
@@ -85,7 +94,7 @@
        letter-spacing: normal;
        /* 功能色/提示色/提示色1 */
        color: #F58900;
        margin: 0px 48px 0px 2px;
        margin-left: 2px;
      }
      .coupon-info {
@@ -136,6 +145,7 @@
      }
      .receive {
        flex-shrink: 0;
        width: 104px;
        height: 56px;
        /* 自动布局 */
@@ -146,7 +156,6 @@
        padding: 25px 0px;
        border-radius: 110px;
        background: #F58900;
        margin-left: 44px;
        /* 辅助文字/辅助文字 常规 12 */
        font-family: PingFang SC;
@@ -158,6 +167,14 @@
        /* 文字色/白色/白色 100% */
        color: #FFFFFF;
      }
      .status-img {
        width: 136px;
        height: 140px;
        position: absolute;
        bottom: 0;
        right: 0;
      }
    }
  }
src/robotaxi/pages/coupon/index.tsx
@@ -102,6 +102,12 @@
    }
  }
  const toHome = () => {
    Taro.switchTab({
      url: '/robotaxi/pages/home/index'
    })
  }
  return (
    <View className='coupon-page'>
      <View className='tab-card'>
@@ -113,29 +119,30 @@
        couponList.length > 0 &&
        <View className='coupon-card'>
          {couponList.map((item, index) => {
            return <View className='coupon-item' key={item.couponId || index}>
              <View className='coupon-price'>
                <Text className='price'>{item.discountAmount}</Text>
                <Text className='unit'>元</Text>
              </View>
              <View className='coupon-info'>
                <Text className='name'>{item.title}</Text>
                <Text className='time'>{item.expireTime}到期</Text>
                <View className='more' onClick={() => openPopup(item)}>
                  <Text className='more-detail'>查看详情</Text>
                  <Image className='more-img' src={icon}></Image>
            return <View className='coupon-item' key={item.couponId || index} style={{ opacity: ![0, 1].includes(item.status) ? 0.5 : 1 }}>
              <View className='coupon-content'>
                <View className='coupon-price'>
                  <Text className='price'>{item.discountAmount}</Text>
                  <Text className='unit'>元</Text>
                </View>
                <View className='coupon-info'>
                  <Text className='name'>{item.title}</Text>
                  <Text className='time'>{item.expireTime}到期</Text>
                  <View className='more' onClick={() => openPopup(item)}>
                    <Text className='more-detail'>查看详情</Text>
                    <Image className='more-img' src={icon}></Image>
                  </View>
                </View>
              </View>
              {/* 状态 1-未使用 2-已使用 3-已过期 0待领取 */}
              {item.status === 0 ? (
                <View className='receive' onClick={(e) => handleReceive(e, item)}>领取</View>
              ) : item.status === 1 ? (
                <View className='receive' style={{ backgroundColor: '#ccc' }}>未使用</View>
                <View onClick={toHome} className='receive' style={{ backgroundColor: '#F58900' }}>去使用</View>
              ) : item.status === 2 ? (
                <View className='receive' style={{ backgroundColor: '#f5f5f5', color: '#999' }}>已使用</View>
                <Image className='status-img' src={require('../../assets/coupon-used.png')} />
              ) : (
                <View className='receive' style={{ backgroundColor: '#f5f5f5', color: '#999' }}>已过期</View>
                <Image className='status-img' src={require('../../assets/coupon-lost-efficacy.png')} />
              )}
            </View>
          })}
@@ -164,7 +171,7 @@
          </View>
          <View className='remark-card'>
            <Text className='remark-label'>使用时段</Text>
            <Text className='remark-value'>{currentCoupon.validTimeRange}</Text>
            <Text className='remark-value'>{currentCoupon.timeRule}</Text>
          </View>
          <View className='remark-card'>
            <Text className='remark-label'>使用地区</Text>
src/robotaxi/pages/expense-description/index.less
@@ -225,7 +225,7 @@
    .complaint-text {
      padding: 24px 0px;
      box-sizing: border-box;
      border: 1.4px solid #000000;
      border: 1px solid #000000;
      width: 548px;
      height: 92px;
      border-radius: 16px;
src/robotaxi/pages/expense-description/index.tsx
@@ -9,7 +9,6 @@
export default function OrderPage() {
  const router = useRouter();
  const { orderId } = router.params;
  const [showAllFaq, setShowAllFaq] = useState(false); // 是否显示全部FAQ
  const [expandedItems, setExpandedItems] = useState<number[]>([]); // 展开的FAQ项ID列表
  const [fareData, setFareData] = useState<FareBreakdownResponse | null>(null);
@@ -17,11 +16,9 @@
  const [showEvaluatePopup, setShowEvaluatePopup] = useState(false);
  useEffect(() => {
    if (orderId) {
      fetchData(orderId);
    }
    fetchData(router.params?.orderId);
    fetchFAQ();
  }, [orderId]);
  }, []);
  const fetchData = async (id: string) => {
    try {
src/utils/Robotaxi-public-method.ts
@@ -254,64 +254,6 @@
  });
};
/**
 * 通过 IP 获取当前位置信息(用于定位授权失败时的兜底)
 */
export const getLocationByIP = (): Promise<any> => {
  return new Promise(async (resolve, reject) => {
    try {
      // 1. 获取当前 network IP
      // 微信小程序没有直接获取公网 IP 的接口,通常由后端从请求头中获取,或者通过第三方接口获取
      // 这里模拟调用服务端提供的 IP 定位接口,假设接口会自动识别请求来源 IP
      const res: any = await request({
        url: _ROBOTAXI_HOST + '/map/base/v1/mini-program/point/getPointByIp',
        method: 'GET',
      });
      if (res && res.point && typeof res.point.latitude === 'number' && typeof res.point.longitude === 'number') {
        resolve({
          longitude: res.point.longitude,
          latitude: res.point.latitude,
          city: res.city || '',
          adcode: res.adcode || ''
        });
      } else {
        // 如果后端接口不可用或未返回数据,尝试使用第三方接口作为备选获取 IP
        Taro.request({
          url: 'https://api.ipify.org?format=json',
          success: (ipRes) => {
            const ip = ipRes.data?.ip;
            if (ip) {
              // 拿着获取到的 IP 去请求服务端接口
              request({
                url: _ROBOTAXI_HOST + '/map/base/v1/mini-program/point/getPointByIp',
                method: 'POST',
                payload: { ip }
              }).then((businessRes: any) => {
                if (businessRes && businessRes.point && typeof businessRes.point.latitude === 'number' && typeof businessRes.point.longitude === 'number') {
                  resolve({
                    longitude: businessRes.point.longitude,
                    latitude: businessRes.point.latitude,
                    city: businessRes.city || '',
                    adcode: businessRes.adcode || ''
                  });
                } else {
                  reject('Business IP location failed');
                }
              }).catch(reject);
            } else {
              reject('Failed to get network IP');
            }
          },
          fail: reject
        });
      }
    } catch (error) {
      reject(error);
    }
  });
};
// 获取城市中心经纬度
export const getCityLocation = (cityName: string): Promise<{ latitude: number, longitude: number }> => {
  return new Promise((resolve, reject) => {