hejianhao
2026-03-26 d69e2b41d441249693811c5211da95d8f0333509
fix(robotaxi): 修复温度调节逻辑、WebSocket重连及订单状态处理

- 修复温度调节组件在边界值附近的错误拦截逻辑
- 将WebSocket重连策略改为固定间隔加随机抖动,移除最大重连次数限制
- 修复订单状态处理中车辆信息拉取的条件判断和订单ID匹配问题
- 调整行程状态7的地图显示配置,修复路线绘制逻辑
4个文件已修改
52 ■■■■■ 已修改文件
src/robotaxi/api/begin-route.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/calling-car.tsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/websocket.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/api/begin-route.ts
@@ -148,6 +148,7 @@
    }, true);
}
// 订单查询轨迹
export const queryOrderTrajectory = async (payload) => {
    return request({
        url: _ROBOTAXI_HOST + `/order/api/v1/mini-program/order/queryOrderTrajectory`,
src/robotaxi/pages/begin-route/components/calling-car.tsx
@@ -423,11 +423,13 @@
                return prev;
            }
            const next = prev + delta;
            if (next < TEMP_MIN) {
            // 只有在继续调低,且低于最低温度时才拦截;如果是从异常低温往回升温,则放行
            if (delta < 0 && next < TEMP_MIN) {
                Taro.showToast({ title: `温度最低${TEMP_MIN}℃`, icon: 'none' });
                return prev;
            }
            if (next > TEMP_MAX) {
            // 只有在继续调高,且高于最高温度时才拦截;如果是从异常高温往回降温,则放行
            if (delta > 0 && next > TEMP_MAX) {
                Taro.showToast({ title: `温度最高${TEMP_MAX}℃`, icon: 'none' });
                return prev;
            }
src/robotaxi/pages/begin-route/index.tsx
@@ -125,7 +125,7 @@
    4: { showPickup: true, showDropoff: false, showCar: true, showRoute: true, showWalking: false, viewport: 'route', translateCar: true },
    5: { showPickup: true, showDropoff: false, showCar: true, showRoute: false, showWalking: false, viewport: 'car_user', translateCar: true },
    6: { showPickup: false, showDropoff: true, showCar: true, showRoute: true, showWalking: false, viewport: 'route', translateCar: true },
    7: { showPickup: false, showDropoff: true, showCar: false, showRoute: false, showWalking: false, viewport: 'dropoff', translateCar: false },
    7: { showPickup: false, showDropoff: true, showCar: true, showRoute: false, showWalking: false, viewport: 'dropoff', translateCar: false },
    8: { showPickup: true, showDropoff: true, showCar: false, showRoute: true, showWalking: false, viewport: 'order_detail', translateCar: false },
    9: { showPickup: true, showDropoff: true, showCar: false, showRoute: true, showWalking: false, viewport: 'order_detail', translateCar: false },
    10: { showPickup: true, showDropoff: false, showCar: false, showRoute: false, showWalking: false, viewport: 'pickup', translateCar: false },
@@ -181,7 +181,7 @@
  useEffect(() => {
    const wasHold = [4, 6].includes(lastTripStatusRef.current);
    const isHold = [4, 6].includes(tripStatus);
    if (tripStatus == 6) {
    if ([6, 7].includes(tripStatus)) {
      setShowLocationFlag(false);
    } else {
      setShowLocationFlag(true);
@@ -528,7 +528,7 @@
      if (dist > bestDistance * 3 && bestDistance < 100) break;
    }
    if (bestMatchIndex > startIndex && bestDistance < 500) {
    if (bestMatchIndex >= startIndex && bestDistance < 500) {
      const mapCtx = Taro.createMapContext('map');
      const eraseIndex = Math.max(0, bestMatchIndex - 1);
@@ -553,8 +553,6 @@
      });
      lastErasedIndexRef.current = bestMatchIndex;
    } else if (bestMatchIndex === startIndex && bestDistance < 500) {
      // 新路线起点与旧路线起点一致,无需擦除
    } else {
      // 路线发生较大变化,回退为全量重绘
      currentFullRouteRef.current = [...newPoints];
@@ -794,7 +792,6 @@
  // 认证成功处理函数
  useEffect(() => {
    authSuccessHandlerRef.current = () => {
      setTripStatus(2);
      if (!messageBound.current && messageHandlerRef.current) {
        wsManager.on('message', messageHandlerRef.current);
        messageBound.current = true;
@@ -820,6 +817,11 @@
    // 优化订单状态回调中的车辆信息拉取逻辑
    orderStatusHandlerRef.current = (payload) => {
      const changeStatusOld = tripStatusRef.current;
      const incomingOrderId = payload?.content?.orderId || payload?.orderId;
      const currentOrderId = orderId || Taro.getStorageSync('orderId');
      if (incomingOrderId && currentOrderId && String(incomingOrderId) !== String(currentOrderId)) {
        return;
      }
      const mappedTripStatus = payload?.tripStatus;
      if (typeof mappedTripStatus === 'number') {
        const currentLocalStatus = Number(Taro.getStorageSync('tripStatus'));
@@ -832,20 +834,20 @@
        Taro.setStorageSync('tripStatus', mappedTripStatus);
      }
      // 车辆信息拉取:当收到有效的订单号时,在首次达到呼叫及后续阶段拉取车辆信息
      const incomingOrderId = payload?.content?.orderId || Taro.getStorageSync('orderId');
      const effectiveOrderId = incomingOrderId || currentOrderId || Taro.getStorageSync('orderId');
      const vehicleInfoEmpty =
        !vehicleInfo ||
        (!vehicleInfo.plateNumber && !vehicleInfo.vehicleCode && !vehicleInfo.vehicleColor && !vehicleInfo.vehiclePictures);
      const shouldFetchVehicle =
        !!incomingOrderId &&
        (lastFetchedVehicleOrderIdRef.current !== incomingOrderId) &&
        (vehicleInfoEmpty || orderId !== incomingOrderId);
      if (incomingOrderId && orderId !== incomingOrderId) {
        setOrderId(incomingOrderId);
        !!effectiveOrderId &&
        (lastFetchedVehicleOrderIdRef.current !== effectiveOrderId) &&
        (vehicleInfoEmpty || orderId !== effectiveOrderId);
      if (effectiveOrderId && orderId !== effectiveOrderId) {
        setOrderId(effectiveOrderId);
      }
      if (shouldFetchVehicle) {
        lastFetchedVehicleOrderIdRef.current = incomingOrderId;
        queryVehicleByOrderId({ orderId: incomingOrderId })
        lastFetchedVehicleOrderIdRef.current = effectiveOrderId;
        queryVehicleByOrderId({ orderId: effectiveOrderId })
          .then((res: any) => {
            setVehicleInfo(res);
          })
@@ -1293,7 +1295,9 @@
      setPolyline(lines);
      lastPolylineUpdateAtRef.current = now;
    } else {
      if (![8, 9].includes(tripStatus)) {
      setPolyline([]);
      }
      lastPolylineUpdateAtRef.current = 0;
    }
  }, [tripStatus, shouldShowRoute, routePoints, walkingPoints, statusRule.showWalking, isAndroid]);
src/utils/websocket.ts
@@ -228,18 +228,17 @@
   * 处理重连
   */
  private handleReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('达到最大重连次数,停止重连。');
      return;
    }
    if (this.reconnectTimer) return;
    const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000); // 指数退避
    console.log(`正在尝试重连,延迟 ${delay}ms... (第 ${this.reconnectAttempts + 1}/${this.maxReconnectAttempts} 次尝试)`);
    // 固定约 3 秒重连一次,并加上 0~1 秒的随机抖动
    const delay = 3000 + Math.floor(Math.random() * 1000);
    console.log(`正在尝试重连,延迟 ${delay}ms... (第 ${this.reconnectAttempts + 1} 次尝试)`);
    this.reconnectTimer = setTimeout(() => {
      // 防止数字溢出(无限重试时)
      if (this.reconnectAttempts < 9999) {
      this.reconnectAttempts++;
      }
      this.reconnectTimer = null;
      this.connect(this.url);
    }, delay);