hejianhao
2026-03-04 67a2484722faa35bf1dad104ae8cbec294ea14b0
feat(robotaxi): 添加登录检查与搜索界面优化

- 在呼叫、查看优惠券和订单前检查用户登录状态,未登录则跳转登录页
- 优化站点搜索页面,添加搜索框清空按钮并调整距离显示格式
- 改进运营区域查看逻辑,动态获取并格式化电子围栏数据
- 修复游客模式下隐私协议提示的显示条件
- 移除未使用的图片导入以优化代码结构
5个文件已修改
205 ■■■■■ 已修改文件
src/pages/robotaxi/home/index.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.tsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/select-map-site/index.tsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/site-search/index.less 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/site-search/index.tsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/index.tsx
@@ -803,6 +803,10 @@
  }
  const toCoupon = () => {
    if (isLogin) {
      jumpTo({ url: '/pages/user/login?hideBack=1' });
      return
    }
    if (Taro.getStorageSync('has_show_privicy_Robotaxi') !== 'true') {
      setShowPrivacy(true);
      return;
@@ -813,6 +817,10 @@
  }
  const toOrder = () => {
    if (isLogin) {
      jumpTo({ url: '/pages/user/login?hideBack=1' });
      return
    }
    if (Taro.getStorageSync('has_show_privicy_Robotaxi') !== 'true') {
      setShowPrivacy(true);
      return;
@@ -827,8 +835,30 @@
  }
  // 查看运营区域
  const handleViewOperatingArea = () => {
    if (!polygons || polygons.length === 0) {
  const handleViewOperatingArea = async () => {
    if (!selectedCity?.code) {
      Taro.showToast({
        title: '此城市暂未开通运营区域',
        icon: 'none'
      });
      return;
    }
    let nextPolygons = polygons;
    try {
      const res: any = await getGeofence({ cityCode: selectedCity.code });
      if (res && Array.isArray(res)) {
        nextPolygons = formatGeofencePolygons(res);
        setPolygons(nextPolygons);
      } else {
        nextPolygons = [];
        setPolygons([]);
      }
    } catch (err) {
      nextPolygons = [];
      setPolygons([]);
    }
    if (!nextPolygons || nextPolygons.length === 0) {
      Taro.showToast({
        title: '此城市暂未开通运营区域',
        icon: 'none'
@@ -836,8 +866,7 @@
      return;
    }
    const points = extractPointsFromPolygons(polygons);
    const points = extractPointsFromPolygons(nextPolygons);
    if (points.length > 0) {
      const mapCtx = Taro.createMapContext('map');
      mapCtx.includePoints({
@@ -916,7 +945,7 @@
        <View className="position-box">
          {/* 游客模式展示同意协议 */}
          {
            Taro.getStorageSync('has_show_privicy_Robotaxi') != 'true' && <View className="visitor-stste">
            (Taro.getStorageSync('has_show_privicy_Robotaxi') != 'true' && !isLogin) && <View className="visitor-stste">
              <View className="visitor-stste-tip">同意隐私协议体验更多约车体验</View>
              <View onClick={() => setShowPrivacy(true)} className="visitor-stste-go">去同意</View>
            </View>
src/robotaxi/pages/begin-route/index.tsx
@@ -20,7 +20,6 @@
import originIcon from '../../../robotaxi/assets/origin-icon.png'
import wsManager from '../../../utils/websocket';
import { getWalkingRoute, formatDurationToClock, formatDateTime, getStoredRoutePoints, clearOrderTripStorage } from '../../../utils/Robotaxi-public-method';
import lineRight from '../../../robotaxi/assets/line-right.png';
import {
  saveOrder,
  queryRouteAndFare,
@@ -30,6 +29,8 @@
  queryOrderRoute,
} from '../../../robotaxi/api/begin-route';
import { getOrderDetail } from '../../../robotaxi/api/order';
import { checkOtp } from '../../../utils/tools';
import { jumpTo } from '../../../utils/jump';
export default function SelectMapSite() {
  const WAITING_TIMER_START_KEY = 'waitingTimerStartAt';
@@ -877,6 +878,11 @@
  // 立即呼叫
  const callImmediately = async () => {
    const otp = await checkOtp(false);
    if (!otp) {
      jumpTo({ url: '/pages/user/login?hideBack=1' });
      return
    }
    if (!endSite.name) {
      Taro.showToast({
        title: '请选择站点',
src/robotaxi/pages/select-map-site/index.tsx
@@ -22,6 +22,8 @@
} from '../../../utils/Robotaxi-public-method';
import { getGeofence } from '../../api/home';
import { getOrderDistance } from '../../api/select-map-site';
import { checkOtp } from '../../../utils/tools';
import { jumpTo } from '../../../utils/jump';
export default function SelectMapSite() {
@@ -73,7 +75,8 @@
      cachedSite = Taro.getStorageSync('endSite');
    }
    // 有缓存,优先使用缓存回显;否则使用当前定位
    const hasCachedSite = !!(cachedSite && cachedSite.latitude && cachedSite.longitude);
    // 有缓存,优先使用缓存回显
    if (cachedSite && cachedSite.latitude && cachedSite.longitude) {
      setLatitude(cachedSite.latitude);
      setLongitude(cachedSite.longitude);
@@ -81,8 +84,6 @@
      updateMapData(cachedSite.latitude, cachedSite.longitude).then(({ isInside }) => {
        setOutOfServiceRange(getOutOfServiceRange(isInside, cachedSite));
      });
    } else {
      getLocationInfo();
    }
    fetchUserLocation();
@@ -106,13 +107,38 @@
        if (res && Array.isArray(res)) {
          const newPolygons = formatGeofencePolygons(res);
          setPolygons(newPolygons);
          if (!hasCachedSite && res.length > 0 && res[0]?.points?.length > 0) {
            const firstPoint = res[0].points[0];
            const lat = Number(firstPoint.lat);
            const lng = Number(firstPoint.lng);
            setLatitude(lat);
            setLongitude(lng);
            updateMapData(lat, lng).then(({ isInside }) => {
              setOutOfServiceRange(getOutOfServiceRange(isInside, {}));
            });
            const mapCtx = Taro.createMapContext('map');
            mapCtx.moveToLocation({
              latitude: lat,
              longitude: lng,
            });
          } else if (!hasCachedSite) {
            getLocationInfo();
          }
        } else {
          setPolygons([]);
          if (!hasCachedSite) {
            getLocationInfo();
          }
        }
      }).catch(err => {
        console.error('获取电子围栏失败', err);
        setPolygons([]);
        if (!hasCachedSite) {
          getLocationInfo();
        }
      });
    } else if (!hasCachedSite) {
      getLocationInfo();
    }
  }, []);
@@ -336,22 +362,23 @@
    });
  }, [pageType, userLatitude, userLongitude, latitude, longitude, selectedSite?.latitude, selectedSite?.longitude]);
  // useEffect(() => {
  //   if (!polyline.length || !polyline[0]?.points?.length) return;
  //   const mapCtx = Taro.createMapContext('map');
  //   mapCtx.includePoints({
  //     points: polyline[0].points,
  //     padding: [80, 80, 200, 80]
  //   });
  // }, [polyline]);
  const toCoupon = () => {
  const toCoupon = async () => {
    const otp = await checkOtp(false);
    if (!otp) {
      jumpTo({ url: '/pages/user/login?hideBack=1' });
      return
    }
    Taro.navigateTo({
      url: '/robotaxi/pages/coupon/index',
    })
  }
  const toOrder = () => {
  const toOrder = async () => {
    const otp = await checkOtp(false);
    if (!otp) {
      jumpTo({ url: '/pages/user/login?hideBack=1' });
      return
    }
    Taro.navigateTo({
      url: '/robotaxi/pages/order/index',
    })
src/robotaxi/pages/site-search/index.less
@@ -26,6 +26,24 @@
      margin-right: 16px;
    }
    .search-input-box {
      flex: 1;
      display: flex;
      align-items: center;
      .cancel-icon-box {
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 10px;
        .cancel-icon {
          width: 32px;
          height: 32px;
        }
      }
    }
    .end-icon {
      background: #8BB654;
    }
src/robotaxi/pages/site-search/index.tsx
@@ -9,6 +9,7 @@
import { formatDistance, debounce } from '../../../utils/Robotaxi-public-method';
import { AMAP_KEY } from '../../../constants/api';
import amapFile from '../../../libs/amap-wx.130.js';
import { checkOtp } from '../../../utils/tools';
@@ -41,7 +42,7 @@
      if (Array.isArray(availablePoints)) {
        const list = availablePoints.map(item => ({
          ...item,
          distance: formatDistance(item.distance)
          distance: item.distance
        }));
        setNearbySiteList(list);
      } else {
@@ -56,36 +57,41 @@
  useEffect(() => {
    const { pageType: type, latitude: lat, longitude: lon, electronicAreaId } = router.params;
    checkOtp(false).then(otp => {
      if (otp) {
        if (lat && lon) {
          fetchNearbySites(Number(lat), Number(lon), electronicAreaId);
          const payload = {
            lat: Number(lat),
            lon: Number(lon)
          };
          const handleSuccess = (res) => {
            if (Array.isArray(res)) {
              const list = res.map(item => ({
                ...item,
                distance: item.distance
              }));
              setHistorySite(list);
            }
          };
          if (type === 'start') {
            getStartPoints(payload).then(handleSuccess);
          } else if (type === 'end') {
            getEndPoints(payload).then(handleSuccess);
          }
        }
      }
    });
    if (type) {
      setPageType(type);
    }
    if (lat && lon) {
      fetchNearbySites(Number(lat), Number(lon), electronicAreaId);
      const payload = {
        lat: Number(lat),
        lon: Number(lon)
      };
      const handleSuccess = (res) => {
        if (Array.isArray(res)) {
          const list = res.map(item => ({
            ...item,
            distance: formatDistance(item.distance)
          }));
          setHistorySite(list);
        }
      };
      if (type === 'start') {
        getStartPoints(payload).then(handleSuccess);
      } else if (type === 'end') {
        getEndPoints(payload).then(handleSuccess);
      }
    }
  }, [])
  const searchSite = async (val?: string) => {
    setNonOperationalSite([]);
    const queryVal = val !== undefined ? val : searchValue;
    if (!queryVal) return;
@@ -107,7 +113,7 @@
      if (Array.isArray(availablePoints)) {
        const list = availablePoints.map(item => ({
          ...item,
          distance: formatDistance(item.distance)
          distance: item.distance
        }));
        setSiteList(list);
      } else {
@@ -209,6 +215,11 @@
    }
  }
  const clearSearchValue = () => {
    setSearchValue('');
    searchSite('');
  }
  const recommendList = siteList.length > 0 ? siteList : nearbySiteList;
@@ -217,12 +228,20 @@
      {/* 搜索区域 */}
      <View className='search-card'>
        <View className={`search-icon ${pageType == 'end' ? 'end-icon' : ''}`}></View>
        <Input className='search-input' placeholder={pageType == 'start' ? '请输入上车点' : '请输入目的地'} value={searchValue}
          onInput={(e) => changeSearchValue(e)}
          onBlur={() => searchSite()}
          onConfirm={() => searchSite()}
          autoFocus
        ></Input>
        <View className='search-input-box'>
          <Input className='search-input' placeholder={pageType == 'start' ? '请输入上车点' : '请输入目的地'} value={searchValue}
            onInput={(e) => changeSearchValue(e)}
            onBlur={() => searchSite()}
            onConfirm={() => searchSite()}
            autoFocus
          />
          {
            searchValue &&
            <View onClick={clearSearchValue} className='cancel-icon-box'>
              <Image className='cancel-icon' src={require('../../assets/close-icon.png')} />
            </View>
          }
        </View>
        <Image onClick={toSelectSite} className='clear-icon' src={map}></Image>
      </View>
      {/* 历史记录 */}
@@ -239,7 +258,7 @@
                    <View className='history-name'>{item.name || '_'}</View>
                    <View className='history-address-box'>
                      <View className='history-address'>{item.address || '-'}</View>
                      <View className='history-distance'>{item.distance}</View>
                      <View className='history-distance'>{item.distance}km</View>
                    </View>
                  </View>
                </View>