hejianhao
2026-03-10 56a9f9f728cad368b85e899e0048e25bb0b3179b
fix(robotaxi): 修复评价失败提示文案和首页布局计算问题

- 将评价失败提示文案统一从“请重试”改为“请稍后重试”
- 修复首页活动区域高度计算逻辑,移除对状态变量的依赖
- 将地图浮层提示移出滚动区域,改为固定定位
- 简化图片上传响应数据解析逻辑,移除冗余字段处理
5个文件已修改
314 ■■■■■ 已修改文件
src/pages/robotaxi/home/index.less 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/index.tsx 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/calling-car.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/evaluate-popup.tsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/order/detail/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/index.less
@@ -21,18 +21,23 @@
  0% {
    transform: translateY(0);
  }
  20% {
    transform: translateY(-10px);
  }
  40% {
    transform: translateY(6px);
  }
  60% {
    transform: translateY(-4px);
  }
  80% {
    transform: translateY(2px);
  }
  100% {
    transform: translateY(0);
  }
@@ -40,13 +45,99 @@
.origin-box {
  position: absolute;
  top: 62%;
  top: 64%;
  right: 32px;
  z-index: 1;
  .origin-icon {
    width: 88px;
    height: 88px;
  }
}
.content-box-top {
  width: 100%;
  position: absolute;
  bottom: 26%;
  left: 0px;
  z-index: 1;
  .position-box {
    .is-operating-area {
      margin: 0 auto;
      // margin-top: 20px;
      width: fit-content;
      line-height: 64px;
      font-size: 24px;
      font-weight: normal;
      letter-spacing: normal;
      color: #FFFFFF;
      border-radius: 200px;
      background: rgba(0, 0, 0, 0.4);
      backdrop-filter: blur(40px);
      padding: 0 44px;
    }
    .is-maintain {
      margin-top: 20px;
      border-radius: 16px;
      background: rgba(255, 249, 226, 0.9);
      box-sizing: border-box;
      border: 2px solid #FFFFFF;
      backdrop-filter: blur(40px);
      box-shadow: 0px 4px 16px 0px rgba(84, 92, 143, 0.1);
      font-size: 24px;
      font-weight: normal;
      line-height: 64px;
      text-align: center;
      letter-spacing: normal;
      color: #F58900;
      padding: 0 24px;
      width: fit-content;
      &.maintain-bounce {
        animation: maintain-bounce 700ms cubic-bezier(0.22, 1, 0.36, 1);
        will-change: transform;
      }
    }
    .ml-32 {
      margin-left: 32px;
    }
    .mt-20 {
      margin-top: 20px;
    }
    .visitor-stste {
      width: fit-content;
      // margin-top: 20px;
      display: flex;
      align-items: center;
      border-radius: 16px;
      background: rgba(0, 0, 0, 0.4);
      backdrop-filter: blur(40px);
      padding: 9px 24px;
      .visitor-stste-tip {
        font-size: 24px;
        font-weight: normal;
        line-height: 46px;
        letter-spacing: normal;
        color: #FFFFFF;
      }
      .visitor-stste-go {
        margin-left: 24px;
        font-size: 24px;
        font-weight: normal;
        line-height: 46px;
        letter-spacing: normal;
        color: #AFEA60;
      }
    }
  }
}
@@ -246,87 +337,6 @@
  background-color: transparent;
  margin-top: 0;
  border-radius: 40px 40px 0 0;
  .content-box-top {
    padding-bottom: 50px;
  }
  .position-box {
    .is-operating-area {
      margin: 0 auto;
      // margin-top: 20px;
      width: fit-content;
      line-height: 64px;
      font-size: 24px;
      font-weight: normal;
      letter-spacing: normal;
      color: #FFFFFF;
      border-radius: 200px;
      background: rgba(0, 0, 0, 0.4);
      backdrop-filter: blur(40px);
      padding: 0 44px;
    }
    .is-maintain {
      margin-top: 20px;
      border-radius: 16px;
      background: rgba(255, 249, 226, 0.9);
      box-sizing: border-box;
      border: 2px solid #FFFFFF;
      backdrop-filter: blur(40px);
      box-shadow: 0px 4px 16px 0px rgba(84, 92, 143, 0.1);
      font-size: 24px;
      font-weight: normal;
      line-height: 64px;
      text-align: center;
      letter-spacing: normal;
      color: #F58900;
      padding: 0 24px;
      width: fit-content;
      &.maintain-bounce {
        animation: maintain-bounce 700ms cubic-bezier(0.22, 1, 0.36, 1);
        will-change: transform;
      }
    }
    .ml-32 {
      margin-left: 32px;
    }
    .mt-20 {
      margin-top: 20px;
    }
    .visitor-stste {
      width: fit-content;
      // margin-top: 20px;
      display: flex;
      align-items: center;
      border-radius: 16px;
      background: rgba(0, 0, 0, 0.4);
      backdrop-filter: blur(40px);
      padding: 9px 24px;
      .visitor-stste-tip {
        font-size: 24px;
        font-weight: normal;
        line-height: 46px;
        letter-spacing: normal;
        color: #FFFFFF;
      }
      .visitor-stste-go {
        margin-left: 24px;
        font-size: 24px;
        font-weight: normal;
        line-height: 46px;
        letter-spacing: normal;
        color: #AFEA60;
      }
    }
  }
  .select-site {
    overflow: hidden;
@@ -600,4 +610,4 @@
    background-clip: text;
    text-fill-color: transparent;
  }
}
}
src/pages/robotaxi/home/index.tsx
@@ -50,7 +50,7 @@
  const [isMaintain, setIsMaintain] = useState(false); // 是否维护中
  const [maintainBounce, setMaintainBounce] = useState(false);
  const [hotfixEndText, setHotfixEndText] = useState('');
  const [isOperatingArea, setIsOperatingArea] = useState(false); // 是否在运营区域内
  const [isOperatingArea, setIsOperatingArea] = useState(true); // 是否在运营区域内
  const [polygons, setPolygons] = useState<any[]>([]); // 地图围栏
  const [tripStatus, setTripStatus] = useState<number>(0); // 行程状态
  const [currentSite, setCurrentSite] = useState<any>({}); // 当前站点
@@ -63,7 +63,7 @@
  const [orderData, setOrderData] = useState<any>({}); // 订单数据
  const [isLogin, setIsLogin] = useState(false); // 是否登录
  const [boxHeight, setBoxHeight] = useState<number>(0); // 活动区域高度
  const [boxHeight, setBoxHeight] = useState<number>(280); // 活动区域高度
  const [originOpacity, setOriginOpacity] = useState(1);
  const startY = useRef(0); // 拖动开始时的Y坐标
  const startHeight = useRef(0); // 拖动开始时的高度
@@ -394,7 +394,7 @@
  // 监听展示项与 Banner 变化,重新计算高度
  useEffect(() => {
    calculateBoxHeight();
  }, [bannerList, tripStatus, isLogin, isLocationAuthDenied, isMaintain, isOperatingArea]);
  }, [bannerList, tripStatus]);
  // 监听城市变化,更新电子围栏
  useEffect(() => {
@@ -408,21 +408,6 @@
      if (res && Array.isArray(res) && res.length > 0) {
        const newPolygons = formatGeofencePolygons(res);
        setPolygons(newPolygons);
        // if ((orderData || orderData?.id) && JSON.stringify(orderData) != '{}') return;
        // 定位到第一个运营区域的第一个点
        // const firstPolygon = res[0];
        // if (firstPolygon && firstPolygon.points && firstPolygon.points.length > 0) {
        //   const firstPoint = firstPolygon.points[0];
        //   setLatitude(Number(firstPoint.lat));
        //   setLongitude(Number(firstPoint.lng));
        //   skipNextLocationCenterRef.current = true;
        //   shouldIgnoreRegionChange.current = true;
        //   const mapCtx = Taro.createMapContext('map');
        //   mapCtx.moveToLocation({
        //     latitude: Number(firstPoint.lat),
        //     longitude: Number(firstPoint.lng),
        //   });
        // }
        if (!Taro.getStorageSync('startSite')) {
          if (skipFenceIncludePointsRef.current) {
            skipFenceIncludePointsRef.current = false;
@@ -481,25 +466,21 @@
    // 延迟计算,确保 DOM 渲染完成
    setTimeout(() => {
      const query = Taro.createSelectorQuery();
      query.select('.content-body').boundingClientRect();
      query.selectAll('.position-box .visitor-stste, .position-box .is-maintain, .position-box .is-operating-area').boundingClientRect();
      query.exec((res: any[]) => {
        const bodyRect = res?.[0];
        const itemRects: Array<{ height: number }> = res?.[1] || [];
        const dynamicTopHeight = itemRects.reduce((sum, r) => sum + (r?.height || 0), 0);
        if (bodyRect && bodyRect.height) {
          const contentHeight = bodyRect.height;
          const baseHeight = 320 + dynamicTopHeight;
      // 获取内部内容容器的完整高度(不受父容器 overflow:hidden 影响)
      query.select('.content-body').boundingClientRect(rect => {
        if (rect) {
          const contentHeight = rect.height;
          const baseHeight = 280;
          fullHeight.current = Math.max(contentHeight, baseHeight);
          minHeight.current = baseHeight;
          setBoxHeight(baseHeight);
        } else {
          const baseHeight = 320 + dynamicTopHeight;
          minHeight.current = baseHeight;
          fullHeight.current = baseHeight;
          setBoxHeight(baseHeight);
          // 兜底逻辑
          minHeight.current = 280;
          fullHeight.current = 280;
          setBoxHeight(280);
        }
      });
      }).exec();
    }, 500);
  }
@@ -1036,14 +1017,6 @@
    }
  }
  const getShowDomFlag = () => {
    const showPrivacyBox = Taro.getStorageSync('has_show_privicy_Robotaxi') != 'true' && !isLogin;
    const showLocationBox = isLocationAuthDenied;
    const showMaintainBox = isMaintain;
    const showOperatingBox = !isOperatingArea;
    return !(showPrivacyBox || showLocationBox || showMaintainBox || showOperatingBox);
  }
  const toAgreementPage = async () => {
    const ok = await ensureNetwork();
    if (!ok) return;
@@ -1057,15 +1030,6 @@
    if (!ok) return;
    jumpTo({ url: '/pages/user/login?hideBack=1' });
  }
  const topSpacerHeight = useMemo(() => {
    const showPrivacyBox = Taro.getStorageSync('has_show_privicy_Robotaxi') != 'true' && !isLogin;
    const showLocationBox = isLocationAuthDenied;
    const showMaintainBox = isMaintain;
    const showOperatingBox = !isOperatingArea;
    const anyShown = showPrivacyBox || showLocationBox || showMaintainBox || showOperatingBox;
    return anyShown ? 0 : 32;
  }, [isLogin, isLocationAuthDenied, isMaintain, isOperatingArea]);
  return (
    <View className="home-container">
@@ -1088,6 +1052,33 @@
        {/* 定位图标 */}
        <View className="origin-box" style={{ opacity: originOpacity, transition: isDragging.current ? 'none' : 'opacity 0.2s ease-out' }}>
          <Image onClick={toOrigin} className="origin-icon" src={originIcon} />
        </View>
        {/* 地图浮层tip */}
        <View className="content-box-top">
          <View className="position-box">
            {/* 游客模式展示同意协议 */}
            {
              (Taro.getStorageSync('has_show_privicy_Robotaxi') != 'true' && !isLogin) && <View className="visitor-stste ml-32">
                <View className="visitor-stste-tip">同意隐私协议体验更多约车体验</View>
                <View onClick={() => setShowPrivacy(true)} className="visitor-stste-go">去同意</View>
              </View>
            }
            {/* 未开启位置权限 */}
            {
              isLocationAuthDenied && <View className="visitor-stste ml-32 mt-20">
                <View className="visitor-stste-tip">未开启位置权限,开启后即可发布行程</View>
                <View onClick={handleOpenSetting} className="visitor-stste-go">去开启</View>
              </View>
            }
            {/* 系统维护 */}
            {
              isMaintain && <View className={`is-maintain ml-32 ${maintainBounce ? 'maintain-bounce' : ''}`}>系统维护中,预计今日{hotfixEndText || '11:00'}恢复服务</View>
            }
            {/* 查看运营区域 */}
            {
              !isOperatingArea && <View onClick={handleViewOperatingArea} className="is-operating-area mt-20">查看运营区域</View>
            }
          </View>
        </View>
        {/* 地图浮层入口 */}
        <View className="map-entry">
@@ -1141,37 +1132,6 @@
        }}
      >
        <View className="content-body">
          <View className="content-box-top">
            <View className="position-box">
              {/* 占位 */}
              {
                getShowDomFlag() &&
                <View style={{ height: `${topSpacerHeight}px` }}></View>
              }
              {/* 游客模式展示同意协议 */}
              {
                (Taro.getStorageSync('has_show_privicy_Robotaxi') != 'true' && !isLogin) && <View className="visitor-stste ml-32">
                  <View className="visitor-stste-tip">同意隐私协议体验更多约车体验</View>
                  <View onClick={() => setShowPrivacy(true)} className="visitor-stste-go">去同意</View>
                </View>
              }
              {/* 未开启位置权限 */}
              {
                isLocationAuthDenied && <View className="visitor-stste ml-32 mt-20">
                  <View className="visitor-stste-tip">未开启位置权限,开启后即可发布行程</View>
                  <View onClick={handleOpenSetting} className="visitor-stste-go">去开启</View>
                </View>
              }
              {/* 系统维护 */}
              {
                isMaintain && <View className={`is-maintain ml-32 ${maintainBounce ? 'maintain-bounce' : ''}`}>系统维护中,预计今日{hotfixEndText || '11:00'}恢复服务</View>
              }
              {/* 查看运营区域 */}
              {
                !isOperatingArea && <View onClick={handleViewOperatingArea} className="is-operating-area mt-20">查看运营区域</View>
              }
            </View>
          </View>
          <View className="select-site">
            <Image className="site-top-bg" src='https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/cab0e5b2-0da0-4d2e-80e6-0fc2da8d2532.png' />
            <View className="site-boarding-point">
src/robotaxi/pages/begin-route/components/calling-car.tsx
@@ -431,7 +431,7 @@
            });
        }).catch(() => {
            Taro.showToast({
                title: '评价提交失败,请重试',
                title: '评价提交失败,请稍后重试',
                icon: 'none'
            });
        });
src/robotaxi/pages/begin-route/components/evaluate-popup.tsx
@@ -93,7 +93,7 @@
            const isFailure = res?.success === false || (typeof res?.code === 'number' && res.code !== 0);
            if (isFailure) {
                Taro.showToast({
                    title: '评价提交失败,请重试',
                    title: '评价提交失败,请稍后重试',
                    icon: 'none'
                });
                return;
@@ -106,7 +106,7 @@
            onConfirm?.();
        }).catch(() => {
            Taro.showToast({
                title: '评价提交失败,请重试',
                title: '评价提交失败,请稍后重试',
                icon: 'none'
            });
        }).finally(() => {
@@ -166,11 +166,11 @@
            try {
                if (typeof data === 'string') data = JSON.parse(data);
            } catch (e) { }
            const payload = data?.data ?? data?.result ?? data ?? {};
            const payload = data?.data;
            const serverObj = {
                id: String(payload?.id || payload?.fileId || ''),
                name: String(payload?.name || payload?.fileName || ''),
                url: String(payload?.url || payload?.fileUrl || ''),
                id: String(payload?.id),
                name: String(payload?.name),
                url: String(payload?.url),
            };
            if (!serverObj.id || !serverObj.url) {
                throw new Error('invalid');
@@ -230,7 +230,7 @@
        setFeedbackContent('');
        setPictures([]);
        getOrderCommentType().then((res: any) => {
            const list = res?.data ?? res?.result ?? res ?? [];
            const list = res;
            if (Array.isArray(list)) {
                setTypeOptions(list);
            } else {
src/robotaxi/pages/order/detail/index.tsx
@@ -138,7 +138,7 @@
        });
      })
      .catch(() => {
        Taro.showToast({ title: '评价提交失败,请重试', icon: 'none' });
        Taro.showToast({ title: '评价提交失败,请稍后重试', icon: 'none' });
      });
  }