hejianhao
2026-04-16 409661ce572b76152ff5d5bc360bfae2b5831019
Merge branch 'feature_mvp_fix' into feature_v1.0
11个文件已修改
314 ■■■■■ 已修改文件
src/robotaxi/pages/begin-route/components/calling-car-modules/door-trunk-control.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-map-markers.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-map-viewport.ts 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-page-restore.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-route-manager.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-vehicle-tracking.ts 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/use-web-socket-events.ts 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.tsx 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.ts 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/websocket.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/components/calling-car-modules/door-trunk-control.tsx
@@ -67,7 +67,7 @@
            doorType,
            ...locationPayload
        }).then((res: any) => {
            console.log(res,'***********');
            console.log('解锁结果:', res);
            
            if (!res) {
                Taro.showToast({ title: '解锁失败,请重试或联系客服', icon: 'none' });
@@ -75,22 +75,34 @@
            }
            if (doorType === 'trunk') {
                const loadingText = trunkStatus ? '正在关闭后备箱' : '正在开启后备箱';
                const isCloseAction = !!trunkStatus;
                const loadingText = isCloseAction ? '正在关闭后备箱' : '正在开启后备箱';
                Taro.showLoading({ title: loadingText, mask: true });
                let pollCount = 0;
                const maxPolls = 3;
                const maxPolls = 5;
                const pollInterval = 2000;
                const expectedTrunkState = trunkStatus ? '0' : '1';
                const expectedTrunkState = isCloseAction ? 0 : 1;
                const successToastText = isCloseAction ? '关闭后备箱成功' : '打开后备箱成功';
                const failToastText = isCloseAction ? '关闭后备箱失败' : '开启后备箱失败';
                const stopPolling = () => {
                    if (trunkPollTimerRef.current) {
                        clearTimeout(trunkPollTimerRef.current);
                        trunkPollTimerRef.current = null;
                    }
                };
                const handlePollFail = (reason: string, actualValue?: any) => {
                    pollCount++;
                    if (pollCount < maxPolls) {
                        stopPolling();
                        trunkPollTimerRef.current = setTimeout(doPoll, pollInterval);
                    } else {
                        stopPolling();
                        Taro.hideLoading();
                        Taro.showToast({
                            title: trunkStatus ? '关闭后备箱失败' : '开启后备箱失败',
                            title: failToastText,
                            icon: 'none'
                        });
                    }
@@ -98,19 +110,31 @@
                const doPoll = () => {
                    queryVehicleTrunkOpenStatus({ orderId: targetOrderId }).then((pollRes: any) => {
                        const data = pollRes;
                        const rawValue = data?.stateMap?.trunkAjarCloseSt?.value;
                        if (!data || rawValue === undefined || rawValue === null || rawValue === '') {
                        console.log('第', pollCount, '次查询后备箱状态:', pollRes);
                        const rawValue = typeof pollRes === 'number'
                            ? pollRes
                            : (
                                pollRes?.data ??
                                pollRes?.stateMap?.trunkAjarCloseSt?.value ??
                                pollRes?.value
                            );
                        if (rawValue === undefined || rawValue === null || rawValue === '') {
                            handlePollFail('empty_data_or_value', rawValue);
                            return;
                        }
                        const value = String(rawValue);
                        const value = Number(rawValue);
                        if (Number.isNaN(value)) {
                            handlePollFail('invalid_value', rawValue);
                            return;
                        }
                        if (value === expectedTrunkState) {
                            const isOpen = value === '1';
                            stopPolling();
                            const isOpen = !isCloseAction;
                            setTrunkStatus(isOpen);
                            Taro.hideLoading();
                            Taro.showToast({
                                title: isOpen ? '打开成功' : '关闭成功',
                                title: successToastText,
                                icon: 'none'
                            });
                            onSuccess?.();
@@ -132,8 +156,6 @@
                }
            }
        }).catch(() => {
            console.log(res,'***********');
            Taro.showToast({ title: '解锁失败,请重试或联系客服', icon: 'none' });
        });
    };
@@ -141,7 +163,7 @@
    if (tripStatus === 5) {
        return (
            <View className="car-card-arrive">
                <View className={`car-card-arrive-item ${trunkStatus && 'close-btn-item'}`} onClick={() => handleUnlock('trunk')}>
                <View className={`car-card-arrive-item ${trunkStatus && 'close-btn-item'}`} onClick={() => handleUnlock('trunk', () => setTrunkStatus(!trunkStatus))}>
                    <Image className="car-card-arrive-item-img" src={trunkStatus ? require('../../../../assets/trunk-open.png') : require('../../../../assets/trunk-close.png')} />
                    <View className="car-card-arrive-item-text">{trunkStatus ? '关闭后备箱' : '打开后备箱'}</View>
                </View>
@@ -159,7 +181,7 @@
                <View className="car-card-reach-text">点击按钮开车门</View>
                <Image className='car-card-reach-img' src='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/door-anim.webp' />
                <View className="car-card-reach-btn">
                    <View className={`car-card-reach-btn-item ${trunkStatus && 'close-btn-item'}`} onClick={() => handleUnlock('trunk')}>
                    <View className={`car-card-reach-btn-item ${trunkStatus && 'close-btn-item'}`} onClick={() => handleUnlock('trunk', () => setTrunkStatus(!trunkStatus))}>
                        <Image className="car-card-reach-btn-item-img" src={trunkStatus ? require('../../../../assets/trunk-open.png') : require('../../../../assets/trunk-close.png')} />
                        <View className="car-card-reach-btn-item-text">{trunkStatus ? '关闭后备箱' : '打开后备箱'}</View>
                    </View>
@@ -173,4 +195,4 @@
    }
    return null;
}
}
src/robotaxi/pages/begin-route/hooks/use-map-markers.ts
@@ -154,7 +154,8 @@
      .join(';');
    const hasDropoffMarker = markersRef.current.some((m: any) => m.id === 2);
    const shouldHoldMarkerByTranslate = [4, 6].includes(deps.tripStatus) && carMarkerInitialized.current && deps.statusRule.showCar && (!deps.statusRule.showDropoff || hasDropoffMarker);
    const shouldSkipUpdate = shouldHoldMarkerByTranslate && (deps.isAndroid || tripStatus6MarkerRefreshedRef.current);
    const shouldHoldMarkerWhenArrived = deps.tripStatus === 7 && carMarkerInitialized.current && deps.statusRule.showCar && (!deps.statusRule.showDropoff || hasDropoffMarker);
    const shouldSkipUpdate = (shouldHoldMarkerByTranslate && (deps.isAndroid || tripStatus6MarkerRefreshedRef.current)) || shouldHoldMarkerWhenArrived;
    applyMarkerState(nextMarkers, nextMarkersSignature, shouldSkipUpdate, carMarker);
  }, [deps.tripStatus, deps.startSite?.name, deps.startSite?.latitude, deps.startSite?.longitude, deps.endSite?.name, deps.endSite?.latitude, deps.endSite?.longitude, deps.vehicleLocation, deps.vehicleDirection, deps.vehicleMarkerId, deps.isAndroid, deps.statusRule.showPickup, deps.statusRule.showCar, deps.statusRule.showDropoff]);
src/robotaxi/pages/begin-route/hooks/use-map-viewport.ts
@@ -30,6 +30,8 @@
    setLatitude: () => { }
};
const DROPOFF_MAX_SCALE = 20;
export default function useMapViewport(rawDeps?: Partial<Deps>) {
    const deps = { ...defaultDeps, ...(rawDeps || {}) } as Deps;
    // 地图底部留白
@@ -190,11 +192,17 @@
            ? [topPadding, 50, bottomPadding, 50]
            : [topPadding, 100, bottomPadding, 100];
        Taro.nextTick(() => {
            mapCtx.includePoints({ points, padding });
            if (viewportType === 'dropoff') {
                mapCtx.moveToLocation({
                    latitude: points[0].latitude,
                    longitude: points[0].longitude
                });
                setTimeout(() => {
                    setMapScale(13);
                    setMapScale(DROPOFF_MAX_SCALE);
                }, 50);
                return;
            } else {
                mapCtx.includePoints({ points, padding });
            }
        });
    };
@@ -217,6 +225,9 @@
    const getLocationInfo = () => {
        Taro.getLocation({ type: 'gcj02' })
            .then((res) => {
                if (deps.tripStatus === 7) {
                    return;
                }
                deps.setLongitude(res.longitude);
                deps.setLatitude(res.latitude);
                if (deps.tripStatus === 6 && deps.routePoints.length > 0) {
@@ -246,8 +257,21 @@
    }, [deps.tripStatus]);
    useEffect(() => {
        const viewportType = deps.statusRule.viewport;
        if (viewportType !== 'dropoff') return;
        const { pickupSite, dropoffSite } = resolveViewportSites();
        const { points, keyParts } = buildViewportPayload(viewportType, pickupSite, dropoffSite);
        if (points.length === 0) return;
        const nextKey = keyParts.join('|');
        if (nextKey === viewportKeyRef.current) return;
        viewportKeyRef.current = nextKey;
        updateViewportByPayload(viewportType, points);
    }, [deps.tripStatus, deps.statusRule?.viewport, deps.endSite?.latitude, deps.endSite?.longitude]);
    useEffect(() => {
        const { pickupSite, dropoffSite } = resolveViewportSites();
        const viewportType = deps.statusRule.viewport;
        if (viewportType === 'dropoff') return;
        const { points, keyParts } = buildViewportPayload(viewportType, pickupSite, dropoffSite);
        if (points.length === 0) return;
        if (deps.tripStatus === 6 && viewportType === 'route' && tripStatus6ViewportLockedRef.current) return;
src/robotaxi/pages/begin-route/hooks/use-page-restore.ts
@@ -85,7 +85,15 @@
   * 同步地图定位并按状态初始化路线。
   */
  const syncLocationAndInitRoute = (s: any, e: any, cachedTripStatus: number) => {
    if (s && s.latitude && s.longitude) {
    // 状态 7 直接以下车点为中心,避免 getLocationInfo 抢占视口中心
    if (cachedTripStatus === 7) {
      const dropoffLat = Number(e?.latitude);
      const dropoffLng = Number(e?.longitude);
      if (Number.isFinite(dropoffLat) && Number.isFinite(dropoffLng)) {
        deps.setLatitude(dropoffLat);
        deps.setLongitude(dropoffLng);
      }
    } else if (s && s.latitude && s.longitude) {
      deps.setLatitude(s.latitude);
      deps.setLongitude(s.longitude);
    } else {
src/robotaxi/pages/begin-route/hooks/use-route-manager.ts
@@ -123,19 +123,11 @@
    orderRouteInitializedRef.current = false;
  };
  // 擦除已行驶路段
  const erasePassedRouteSegments = (newPoints: any[], servedPoints: any[] = []) => {
  // 擦除已行驶路段(仅基于前后两次路线点差分,不依赖后端 served)
  const erasePassedRouteSegments = (newPoints: any[], _servedPoints: any[] = []) => {
    const oldPoints = currentFullRouteRef.current;
    if (!oldPoints?.length || !newPoints?.length) return;
    const servedLast = Array.isArray(servedPoints) && servedPoints.length > 0
      ? servedPoints[servedPoints.length - 1]
      : null;
    const hasServedBoundary = !!(
      servedLast &&
      typeof servedLast.latitude === 'number' &&
      typeof servedLast.longitude === 'number'
    );
    const boundaryPoint = hasServedBoundary ? servedLast : newPoints[0];
    const boundaryPoint = newPoints[0];
    if (
      !boundaryPoint ||
      typeof boundaryPoint.latitude !== 'number' ||
@@ -157,7 +149,7 @@
      }
      if (dist > bestDistance * 3 && bestDistance < 100) break;
    }
    if (bestMatchIndex >= startIndex && bestDistance < 500) {
    if (bestMatchIndex >= startIndex && bestDistance < 120) {
      Taro.createMapContext('map').eraseLines({
        lines: [{
          id: 2001,
@@ -169,19 +161,15 @@
          clear: true
        }]
      });
      if (hasServedBoundary) {
        currentFullRouteRef.current = [...newPoints];
        lastErasedIndexRef.current = 0;
      } else {
        lastErasedIndexRef.current = bestMatchIndex;
      }
      // 同步 React 路由状态,避免仅原生擦线导致线和车不同步
      currentFullRouteRef.current = [...newPoints];
      lastErasedIndexRef.current = 0;
      applyRoutePoints([...newPoints]);
      return;
    }
    currentFullRouteRef.current = [...newPoints];
    lastErasedIndexRef.current = 0;
    lastRoutePointRef.current = null;
    lastRouteUpdateAtRef.current = 0;
    setRoutePoints([...newPoints]);
    applyRoutePoints([...newPoints]);
  };
  // 确保路线请求可用城市信息
@@ -441,7 +429,7 @@
  // 请求订单实时路线/轨迹
  const requestOrderRoute = (targetOrderId: string, status: number) => {
    const routeType = status <= 5 ? 1 : 2;
    const requestRoute = [7, 8, 9].includes(status) ? queryOrderTrajectory : queryOrderRoute;
    const requestRoute = [8, 9].includes(status) ? queryOrderTrajectory : queryOrderRoute;
    requestRoute({ orderId: targetOrderId, routeType })
      .then((res: any) => {
        const rawPoints = Array.isArray(res?.polyline) ? res.polyline : [];
@@ -457,14 +445,23 @@
            deps.updateVehicleLocationThrottled(last.latitude, last.longitude, true);
          } else {
            applyRoutePoints(points);
            const first = points[0];
            deps.updateVehicleLocationThrottled(first.latitude, first.longitude, true);
            const targetPoint = status === 7
              ? points[points.length - 1]
              : points[0];
            deps.updateVehicleLocationThrottled(targetPoint.latitude, targetPoint.longitude, true);
            if ([4, 6].includes(status)) {
              currentFullRouteRef.current = [...points];
              lastErasedIndexRef.current = 0;
              orderRouteInitializedRef.current = true;
            }
          }
        } else if (status === 7) {
          const cachedEndSite = Taro.getStorageSync('endSite') || {};
          const fallbackLat = Number(cachedEndSite?.latitude);
          const fallbackLng = Number(cachedEndSite?.longitude);
          if (Number.isFinite(fallbackLat) && Number.isFinite(fallbackLng)) {
            deps.updateVehicleLocationThrottled(fallbackLat, fallbackLng, true);
          }
        }
        const distanceKm = normalizeDistanceKm(Number(res?.distance));
        if (distanceKm !== null) {
src/robotaxi/pages/begin-route/hooks/use-vehicle-tracking.ts
@@ -22,17 +22,11 @@
  const [trunkStatus, setTrunkStatus] = useState(false);
  const lastVehiclePointRef = useRef<{ latitude: number; longitude: number } | null>(null);
  const lastVehicleUpdateAtRef = useRef<number>(0);
  const translateDurationRef = useRef<number>(900);
  const TRANSLATE_DURATION_MS = 100;
  // 更新车辆位置并维护最近位置引用
  const updateVehicleLocationThrottled = (lat: number, lng: number, force = false) => {
    const now = Date.now();
    const prevUpdateAt = lastVehicleUpdateAtRef.current;
    if (prevUpdateAt > 0) {
      // 基于推送间隔动态调整平移时长,适配 1-2 秒频率的轨迹推送
      const interval = now - prevUpdateAt;
      translateDurationRef.current = Math.max(350, Math.min(1600, Math.floor(interval * 0.85)));
    }
    if (Number.isFinite(lat) && Number.isFinite(lng)) {
      lastVehiclePointRef.current = { latitude: lat, longitude: lng };
      lastVehicleUpdateAtRef.current = now;
@@ -44,20 +38,17 @@
    if (!statusRule.translateCar) return;
    if (!vehicleLocation) return;
    const mapCtx = Taro.createMapContext('map');
    const timer = setTimeout(() => {
      mapCtx.translateMarker({
        markerId: vehicleMarkerId,
        destination: {
          latitude: vehicleLocation.latitude,
          longitude: vehicleLocation.longitude,
        },
        autoRotate: false,
        moveWithRotate: true,
        rotate: typeof vehicleDirection === 'number' ? ((vehicleDirection % 360) + 360) % 360 : 0,
        duration: translateDurationRef.current
      });
    }, 100);
    return () => clearTimeout(timer);
    mapCtx.translateMarker({
      markerId: vehicleMarkerId,
      destination: {
        latitude: vehicleLocation.latitude,
        longitude: vehicleLocation.longitude,
      },
      autoRotate: false,
      moveWithRotate: true,
      rotate: typeof vehicleDirection === 'number' ? ((vehicleDirection % 360) + 360) % 360 : 0,
      duration: TRANSLATE_DURATION_MS
    });
  }, [statusRule.translateCar, vehicleLocation, vehicleDirection, vehicleMarkerId]);
  return {
src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx
@@ -10,6 +10,8 @@
  isAndroid: boolean;
  /** 行程状态 */
  tripStatus: number;
  /** 地图缩放等级 */
  mapScale: number;
  /** 地图 markers */
  markers: any[];
  /** 是否显示等待雷达 */
@@ -138,7 +140,7 @@
          </CoverView>
        </CoverView>
      )}
      {(item.id === 2 && [7].includes(deps.tripStatus) && !deps.isAndroid) && (
      {(item.id === 2 && [7].includes(deps.tripStatus) && !deps.isAndroid && deps.mapScale >= 20) && (
        <CoverView className='custom-callout-content'>
          已到达
        </CoverView>
src/robotaxi/pages/begin-route/hooks/use-web-socket-events.ts
@@ -67,8 +67,12 @@
        return null;
    }
    const currentTripStatus = Number(deps.tripStatusRef.current);
    if (currentTripStatus > mappedTripStatus && currentTripStatus !== 10) {
        return null;
    // 行程进行关键态不允许被回退,避免 4/6 被延迟状态覆盖导致路线链路重置
    if ([4, 6].includes(currentTripStatus) && mappedTripStatus < currentTripStatus) {
        return currentTripStatus;
    }
    if (currentTripStatus === mappedTripStatus) {
        return mappedTripStatus;
    }
    deps.setTripStatus(mappedTripStatus);
    deps.tripStatusRef.current = mappedTripStatus;
@@ -182,18 +186,41 @@
    return null;
};
const resolveVehiclePointForErase = (points: any[], servedPoints: any[] = []) => {
    const firstPoint = points?.[0];
    if (firstPoint && typeof firstPoint.latitude === 'number' && typeof firstPoint.longitude === 'number') {
        return firstPoint;
    }
    return resolveVehiclePoint(points, servedPoints);
};
const syncVehiclePointWithRoute = (points: any[], deps: UseWebSocketEventsDeps, servedPoints: any[] = []) => {
    const targetPoint = resolveVehiclePoint(points, servedPoints);
    if (!targetPoint) {
        return;
    }
    const currentTripStatus = Number(deps.tripStatusRef.current);
    if (currentTripStatus === 7) {
        const lastPoint = deps.lastVehiclePointRef.current;
        const lastUpdateAt = Number(deps.lastVehicleUpdateAtRef.current || 0);
        const now = Date.now();
        const latDiff = Math.abs(Number(lastPoint?.latitude || 0) - targetPoint.latitude);
        const lngDiff = Math.abs(Number(lastPoint?.longitude || 0) - targetPoint.longitude);
        const almostSamePoint = latDiff < 0.000003 && lngDiff < 0.000003;
        if (almostSamePoint || (now - lastUpdateAt < 1200)) {
            return;
        }
    }
    deps.updateVehicleLocationThrottled(targetPoint.latitude, targetPoint.longitude, true);
};
const handleEraseRouteStatus = (points: any[], servedPoints: any[], deps: UseWebSocketEventsDeps) => {
    const targetPoint = resolveVehiclePoint(points, servedPoints);
    const targetPoint = resolveVehiclePointForErase(points, servedPoints);
    if (targetPoint) {
        deps.updateVehicleLocationThrottled(targetPoint.latitude, targetPoint.longitude, true);
    }
    if (deps.orderRouteInitializedRef.current && deps.currentFullRouteRef.current.length > 0) {
        deps.erasePassedRouteSegments(points, servedPoints);
        deps.erasePassedRouteSegments(points);
    } else {
        deps.orderRouteInitializedRef.current = true;
        deps.currentFullRouteRef.current = [...points];
@@ -202,18 +229,13 @@
            deps.applyRoutePoints(points);
        });
    }
    if (targetPoint) {
        setTimeout(() => {
            deps.updateVehicleLocationThrottled(targetPoint.latitude, targetPoint.longitude, true);
        }, 50);
    }
};
const handleNormalRouteStatus = (points: any[], deps: UseWebSocketEventsDeps, servedPoints: any[] = []) => {
    Taro.nextTick(() => {
        const updated = deps.applyRoutePoints(points);
        if (!updated) return;
        if (![4, 5, 6].includes(deps.tripStatusRef.current)) return;
        if (![4, 5, 6, 7].includes(deps.tripStatusRef.current)) return;
        syncVehiclePointWithRoute(points, deps, servedPoints);
    });
};
@@ -230,28 +252,30 @@
    deps.lastRouteUpdateAtRef.current = 0;
    Taro.nextTick(() => {
        deps.orderRouteInitializedRef.current = true;
        deps.orderRouteInitializedRef.current = points.length > 0;
        deps.currentFullRouteRef.current = [...points];
        deps.lastErasedIndexRef.current = 0;
        deps.applyRoutePoints(points);
        syncVehiclePointWithRoute(points, deps, servedPoints);
        if (points.length > 0) {
            syncVehiclePointWithRoute(points, deps, servedPoints);
        }
    });
};
const handleOrderRoutePayload = (payload: any, deps: UseWebSocketEventsDeps) => {
    if (deps.tripStatusRef.current === 5) return;
    const points = payload?.points || [];
    const servedPoints = Array.isArray(payload?.servedPoints) ? payload.servedPoints : [];
    const forceFullRedraw = payload?.forceFullRedraw === true;
    const currentTripStatus = Number(deps.tripStatusRef.current);
    updateRouteSummary(payload, deps);
    if ([4, 6].includes(deps.tripStatusRef.current)) {
    if ([4, 6].includes(currentTripStatus)) {
        deps.setVehicleMoveAlongPoints(servedPoints);
    }
    if (forceFullRedraw) {
        handleForceFullRouteRedraw(points, deps, servedPoints);
        return;
    }
    const isEraseStatus = [4, 6].includes(deps.tripStatusRef.current);
    const isEraseStatus = ![7, 8, 9].includes(currentTripStatus);
    if (isEraseStatus) {
        handleEraseRouteStatus(points, servedPoints, deps);
        return;
@@ -332,6 +356,10 @@
        orderRouteHandlerRef.current = (payload) => {
            handleOrderRoutePayload(payload, depsRef.current);
        };
        // 处理重进页面时 useDidShow 先于 handler 初始化的场景,确保已连接状态下也能完成监听绑定
        if (wsManager.isConnectedStatus()) {
            bindSocketListeners();
        }
        return () => {
            if (authSuccessBound.current && authSuccessHandlerRef.current) {
src/robotaxi/pages/begin-route/index.tsx
@@ -467,6 +467,7 @@
  const { renderMapOverlays, renderTripCard } = useViewDelegates({
    isAndroid,
    tripStatus,
    mapScale,
    markers,
    isRouteSelectExpanded,
    onToggleRouteSelect: setIsRouteSelectExpanded,
src/utils/request.ts
@@ -10,11 +10,10 @@
  getStorage,
  objectSort,
} from '../utils/tools';
import { _ROBOTAXI_HOST, _XP_SECRET, _UID } from '../constants/api';
import { _XP_SECRET, _UID } from '../constants/api';
import { jumpTo } from './jump';
const CODE_SUCCESS = 200
const MINI_LOG_UPLOAD_PATH = '/operation/base/v1/mini-program/miniLog/uploadLog';
const CODE_AUTH_EXPIRED_ARRAY = [12010301, 12010302, 12010303, 12010304, 12010305, 12010306, 12010320, 12010002];
// 12010301, "登录状态已过期,请重新登录", "otp缓存已过期"),
// 12010302, "登录状态已过期,请重新登录", "otp已过期"),
@@ -53,19 +52,6 @@
    header
  })
    .then(async (res) => {
      if (!isMiniLogUploadUrl(url)) {
        uploadMiniLog(
          {
            data: JSON.stringify({
              type: 'http_error',
              url,
              request: payload,
              response: res?.data,
              timestamp: Date.now()
            })
          }
        );
      }
      // res为包含cookies、header的经过小程序封装的数据
      // 第一层data为接口返回数据,包含接口状态码
      // 第二层data一般为业务数据
@@ -100,19 +86,6 @@
      return data
    })
    .catch((err) => {
      if (!isMiniLogUploadUrl(url)) {
        uploadMiniLog(
          {
            data: JSON.stringify({
              type: 'http_error',
              url,
              request: payload,
              response: err,
              timestamp: Date.now()
            })
          }
        );
      }
      console.log('request err:', url);
      console.log(err);
@@ -142,28 +115,6 @@
      return Promise.reject(errData)
    });
}
const isMiniLogUploadUrl = (url: string = '') => {
  return typeof url === 'string' && url.includes(MINI_LOG_UPLOAD_PATH);
};
export const uploadMiniLog = async (logContent: any) => {
  if (!logContent) return;
  try {
    const header = await buildHeader({ method: 'POST', payload: logContent }, false);
    if (!header) return;
    const uploadUrl = `${_ROBOTAXI_HOST}${MINI_LOG_UPLOAD_PATH}`;
    Taro.request({
      url: uploadUrl,
      method: 'POST',
      data: logContent,
      header: {
        ...header,
        'Content-Type': 'application/json'
      }
    }).catch(() => { });
  } catch (_) { }
};
async function buildHeader(options, needLogin) {
  const { method = 'POST', payload, extraHeader = {} } = options;
src/utils/websocket.ts
@@ -2,7 +2,6 @@
import { getStorage } from './tools';
import { _UID } from '../constants/api';
import { safeParse } from './Robotaxi-public-method';
import { uploadMiniLog } from './request';
type MessageCallback = (data: any) => void;
@@ -117,10 +116,6 @@
        try {
          data = safeParse(res.data as string, {});
          console.log('收到 WebSocket 消息:', res.data);
          if (!this.isHeartbeatMessage(data)) {
            const messageContent = typeof res.data === 'string' ? res.data : JSON.stringify(res.data);
            uploadMiniLog({ data: messageContent });
          }
        } catch (e) {
          console.warn('解析 WebSocket data 失败:', res.data);
          this.notifyListeners('message', res.data);
@@ -187,10 +182,6 @@
      try {
        data = safeParse(res.data as string, {});
        console.log('收到 WebSocket 消息:', res.data);
        if (!this.isHeartbeatMessage(data)) {
          const messageContent = typeof res.data === 'string' ? res.data : JSON.stringify(res.data);
          uploadMiniLog(messageContent);
        }
      } catch (e) {
        console.warn('解析 WebSocket data 失败:', res.data);
        this.notifyListeners('message', res.data);
@@ -467,16 +458,16 @@
          cached.latest = points;
        }
        Taro.setStorageSync('orderRoutePoints', cached);
        this.notifyListeners('order_route', {
          routeType,
          direction,
          points,
          servedPoints,
          data,
          content,
          forceFullRedraw: data?.type === 'ORDER_UPDATE_LINE'
        });
      }
      this.notifyListeners('order_route', {
        routeType,
        direction,
        points,
        servedPoints,
        data,
        content,
        forceFullRedraw: data?.type === 'ORDER_UPDATE_LINE'
      });
    }
    if (data?.type === 'ORDER_UPDATE_PRICE') {
      const orderId = content?.orderId ?? data?.orderId;