hejianhao
2026-02-04 a7244cf0a2cf0f65c13ec95aa490d85f7698ba57
feat(robotaxi): 添加位置权限状态提示和弹窗时隐藏底部导航栏

- 在隐私弹窗显示/隐藏时调用 Taro.hideTabBar/showTabBar 避免视觉重叠
- 新增位置权限检测,未授权时显示引导开启权限的提示条
- 新增游客模式、系统维护和运营区域的状态提示组件
- 优化位置获取逻辑,先检查授权状态再决定是否调用 getLocation
3个文件已修改
155 ■■■■■ 已修改文件
src/pages/robotaxi/components/customer-service/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/index.less 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/home/index.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/robotaxi/components/customer-service/index.tsx
@@ -14,6 +14,7 @@
  useEffect(() => {
    if (show && !visible) {
      Taro.hideTabBar({ animation: true });
      setVisible(true);
      const animation = Taro.createAnimation({
        duration: 300,
@@ -30,6 +31,7 @@
      setAnimationData(animation.export());
      setTimeout(() => {
        Taro.showTabBar({ animation: true });
        setVisible(false);
      }, 300);
    }
src/pages/robotaxi/home/index.less
@@ -148,6 +148,75 @@
      height: 88px;
    }
  }
  .position-box {
    position: absolute;
    bottom: 68px;
    left: 32px;
    z-index: 101;
    width: calc(100% - 64px);
    .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: 1px 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;
    }
    .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;
      }
    }
  }
}
.content-box {
@@ -157,7 +226,7 @@
  overflow: hidden;
  margin-top: -52px;
  border-radius: 32px 32px 0 0;
  .select-site {
    position: relative;
    padding: 32px;
src/pages/robotaxi/home/index.tsx
@@ -17,12 +17,15 @@
export default function Home() {
  const [showPrivacy, setShowPrivacy] = useState(false);
  const [showPrivacy, setShowPrivacy] = useState(false); //
  const [showCustomerService, setShowCustomerService] = useState(false);
  const [longitude, setLongitude] = useState<number | null>(null);
  const [latitude, setLatitude] = useState<number | null>(null);
  const [showToolTip, setShowToolTip] = useState(true);
  const [bounce, setBounce] = useState(false);
  const [isLocationAuthDenied, setIsLocationAuthDenied] = useState(false);
  const [isMaintain, setIsMaintain] = useState(false);
  const [isOperatingArea, setIsOperatingArea] = useState(false);
  const [boxHeight, setBoxHeight] = useState<number | string>('auto');
  const startY = useRef(0);
@@ -30,6 +33,23 @@
  const fullHeight = useRef(0);
  const minHeight = useRef(0);
  const isDragging = useRef(false);
  const getLocationInfo = () => {
    Taro.getLocation({ type: 'gcj02' })
      .then(res => {
        setLatitude(res.latitude);
        setLongitude(res.longitude);
        const myAmapFun = new amapFile.AMapWX({ key: AMAP_KEY });
        myAmapFun.getPoiAround({
          location: `${res.latitude},${res.longitude}`,
          success: () => { },
          fail: () => { }
        });
      })
      .catch(() => {
        setIsLocationAuthDenied(true);
      });
  }
  useEffect(() => {
    setShowPrivacy(Taro.getStorageSync('has_show_privicy_Robotaxi') != 'true');
@@ -58,18 +78,19 @@
      }).exec();
    }, 500);
    Taro.getLocation({ type: 'gcj02' })
      .then(res => {
        setLatitude(res.latitude);
        setLongitude(res.longitude);
        const myAmapFun = new amapFile.AMapWX({ key: AMAP_KEY });
        myAmapFun.getPoiAround({
          location: `${res.latitude},${res.longitude}`,
          success: () => { },
          fail: () => { }
        });
      })
      .catch(() => { });
    Taro.getSetting({
      success: (res) => {
        const auth = res.authSetting['scope.userLocation'];
        if (auth === false) {
          setIsLocationAuthDenied(true);
        } else {
          getLocationInfo();
        }
      },
      fail: (err) => {
        console.error('获取位置授权信息失败', err);
      }
    });
  }, []);
  const handleClosePrivacy = () => {
@@ -134,6 +155,17 @@
    setShowCustomerService(true);
  }
  const handleOpenSetting = () => {
    Taro.openSetting({
      success: (res) => {
        if (res.authSetting['scope.userLocation']) {
          setIsLocationAuthDenied(false);
          getLocationInfo();
        }
      }
    })
  }
  return (
    <View className="home-container">
      <Map
@@ -177,6 +209,30 @@
        <View className="origin-box">
          <Image onClick={toOrigin} className="origin-icon" src={originIcon} />
        </View>
        <View className="position-box">
          {/* 游客模式展示同意协议 */}
          {
            Taro.getStorageSync('has_show_privicy_Robotaxi') != 'true' && <View className="visitor-stste">
              <View className="visitor-stste-tip">同意隐私协议体验更多约车体验</View>
              <View onClick={() => setShowPrivacy(true)} className="visitor-stste-go">去同意</View>
            </View>
          }
          {/* 未开启位置权限 */}
          {
            isLocationAuthDenied && <View className="visitor-stste">
              <View className="visitor-stste-tip">未开启位置权限,开启后即可发布行程</View>
              <View onClick={handleOpenSetting} className="visitor-stste-go">去开启</View>
            </View>
          }
          {/* 系统维护 */}
          {
            isMaintain && <View className="is-maintain">系统维护中,预计今日11:00恢复服务</View>
          }
          {/* 查看运营区域 */}
          {
            isOperatingArea && <View className="is-operating-area">查看运营区域</View>
          }
        </View>
      </Map>
      {/* 选择站点 */}
      <View