refactor(robotaxi): 迁移页面白名单校验至HOC封装
新增withRobotaxiWhitelist高阶组件统一处理页面的白名单权限校验,为所有相关页面添加该包装并移除全局应用层的白名单校验逻辑,改为在页面显示时自动触发校验。
| | |
| | | import { privicyShowManager } from './components/privacy-popup/utils'; |
| | | import { initPrivacyPopupState } from './reducers/privacyPopup'; |
| | | import { preloadLoginBgImageOnWx } from './utils/login-bg-utils'; |
| | | import { checkWhitelistAccess, redirectToWhitelistBlockPage } from './utils/whitelist'; |
| | | |
| | | const store = configStore(); |
| | | const ENV = process.env.TARO_ENV; |
| | |
| | | return; |
| | | } |
| | | |
| | | const whitelistAccessResult = await this.handleWhitelistGuard(); |
| | | if (whitelistAccessResult === 'deny') { |
| | | return; |
| | | } |
| | | |
| | | const { hasLogin } = router.query || {}; |
| | | |
| | | // 预加载登录背景图 |
| | |
| | | .catch(console.error); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 执行全局白名单守卫。 |
| | | */ |
| | | handleWhitelistGuard = async () => { |
| | | const whitelistAccessResult = await checkWhitelistAccess(); |
| | | if (whitelistAccessResult === 'deny') { |
| | | await redirectToWhitelistBlockPage(); |
| | | } |
| | | return whitelistAccessResult; |
| | | } |
| | | |
| | | componentDidHide() { |
| | |
| | | import { subscribeOperationCouponGroup } from '../../../utils/subscribe'; |
| | | import { checkOtp, toH5 } from '../../../utils/tools'; |
| | | import { getCityLocation, reportEvent } from '../../../utils/Robotaxi-public-method'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | import { |
| | | HOME_MAP_ID, |
| | | HOME_ORDER_STATUS, |
| | |
| | | /** |
| | | * Robotaxi 首页页面容器:仅负责组合领域 hook 与布局组件。 |
| | | */ |
| | | export default function Home() { |
| | | function Home() { |
| | | const [showPrivacy, setShowPrivacy] = useState(false); // 隐私协议弹窗是否显示 |
| | | const [showCustomerService, setShowCustomerService] = useState(false); // 客服弹窗是否显示 |
| | | const [tripStatus, setTripStatus] = useState<HomeTripStatus>(0); // 当前行程状态 |
| | |
| | | </View> |
| | | ); |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(Home); |
| | |
| | | import { View, Image } from '@tarojs/components'; |
| | | import './index.less'; |
| | | import { getNormalizedLoginAgreementList, type LoginAgreementItem } from '../../utils/login-agreement'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | export default function AgreementPage() { |
| | | function AgreementPage() { |
| | | const [agreementList, setAgreementList] = useState<LoginAgreementItem[]>([]); |
| | | |
| | | useEffect(() => { |
| | |
| | | </View> |
| | | ) |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(AgreementPage); |
| | |
| | | createWaitingForPickupReportPayload, |
| | | resetConfirmRideSelectionContext |
| | | } from './constants/confirm-ride-report'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | const ROUTE_SUMMARY_MARKER_ID = 999001; |
| | | const MODIFY_DESTINATION_PICKUP_STATUS_GUARD_MS = 5000; |
| | |
| | | reportEvent(params.eventId, createConfirmRideEventPayload(params)); |
| | | } |
| | | |
| | | export default function BeginRoute() { |
| | | function BeginRoute() { |
| | | const WAITING_TIMER_START_KEY = 'waitingTimerStartAt'; // 等待计时开始时间 |
| | | const WAITING_TIMER_ELAPSED_KEY = 'waitingTimerElapsed'; // 等待计时已过秒数 |
| | | const DEFAULT_QUEUE_POLLING_TIME = 10; // 排队位次默认轮询秒数 |
| | |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(BeginRoute); |
| | |
| | | CouponItem, |
| | | CouponDetail |
| | | } from "../../../robotaxi/api/coupon"; |
| | | import { withRobotaxiWhitelist } from "../../../utils/whitelist"; |
| | | |
| | | export default function CouponPage() { |
| | | function CouponPage() { |
| | | const [couponStatus] = useState([ |
| | | // { label: '全部', value: '' }, |
| | | // { label: "可领取", value: 0 }, |
| | |
| | | </View> |
| | | ); |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(CouponPage); |
| | |
| | | import DemoCom from '../../components/demo'; |
| | | import { checkOtp } from '../../../utils/tools'; |
| | | |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | // @ts-ignore |
| | | @createPage() |
| | | export default class Toolbox extends Component { |
| | | class ToolboxBase extends Component { |
| | | $app: any = Taro.getApp().$app; |
| | | |
| | | componentDidShow() { |
| | |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(ToolboxBase as any); |
| | |
| | | formatTripDurationFromSeconds |
| | | } from '../../../utils/Robotaxi-public-method'; |
| | | import EvaluatePopup from '../begin-route/components/evaluate-popup'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | import './index.less'; |
| | | |
| | | export default function OrderPage() { |
| | | function OrderPage() { |
| | | const router = useRouter(); |
| | | const [showAllFaq, setShowAllFaq] = useState(false); // 是否显示全部FAQ |
| | | const [expandedItems, setExpandedItems] = useState<string[]>([]); |
| | |
| | | </View> |
| | | ) |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(OrderPage); |
| | |
| | | formatTripDistance, |
| | | formatTripDurationFromSeconds |
| | | } from '../../../utils/Robotaxi-public-method'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | /** 城市缓存 key */ |
| | | const SELECTED_CITY_STORAGE_KEY = 'selectedCity'; |
| | |
| | | } |
| | | } |
| | | |
| | | export default function OrderPage() { |
| | | function OrderPage() { |
| | | const [pricingCard, setPricingCard] = useState<any>(null); |
| | | const [startSite, setStartSite] = useState<any>(null); |
| | | const [endSite, setEndSite] = useState<any>(null); |
| | |
| | | <Text className='look-rule-txt'>查看计价规则</Text> |
| | | <Image className='arrow-icon' src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/Subtract.png"></Image> |
| | | </View> |
| | | |
| | | |
| | | </View> |
| | | ) |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(OrderPage); |
| | |
| | | import { getOpenCity } from '../../api/select-city'; |
| | | import { getGeofence } from '../../api/home'; |
| | | import { extractPointsFromPolygons, findMatchedPolygon, getDistance } from '../../../utils/Robotaxi-public-method'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | export default function OperatingArea() { |
| | | function OperatingArea() { |
| | | const [longitude, setLongitude] = useState<number | null>(null); |
| | | const [latitude, setLatitude] = useState<number | null>(null); |
| | | const [polygons, setPolygons] = useState<any[]>([]); |
| | |
| | | </View> |
| | | ); |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(OperatingArea); |
| | |
| | | import { submitOrderComment } from '../../../api/begin-route'; |
| | | import { formatTripDistance, formatTripDurationFromSeconds, safeParse } from '../../../../utils/Robotaxi-public-method'; |
| | | import { getOrderId } from '../../../utils/order'; |
| | | import { withRobotaxiWhitelist } from '../../../../utils/whitelist'; |
| | | |
| | | export default function orderDetailPage() { |
| | | function OrderDetailPage() { |
| | | const router = useRouter(); |
| | | const { orderId } = router.params; |
| | | |
| | |
| | | </View> |
| | | ) |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(OrderDetailPage); |
| | |
| | | |
| | | const XP_INVOICE_APP_ID = 'xp_invoice'; |
| | | |
| | | export default function OrderPage() { |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | function OrderPage() { |
| | | const router = useRouter(); |
| | | const { filter } = router.params as { filter: OrderFilterKey }; |
| | | const [groups, setGroups] = useState<OrderHistoryGroup[]>([]) |
| | |
| | | </View> |
| | | ) |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(OrderPage); |
| | |
| | | import { useEffect, useState } from 'react'; |
| | | import './index.less' |
| | | import { getLoginAgreementContentInfo, getPrivacyContent } from '../../api/home'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | type AgreementItem = { |
| | | id: number | string; |
| | |
| | | version?: string | number; |
| | | }; |
| | | |
| | | export default function PassengerNotice() { |
| | | function PassengerNotice() { |
| | | const [content, setContent] = useState(''); |
| | | const [title, setTitle] = useState('乘车须知'); |
| | | const RIDE_NOTICE_TYPE = 5; // 乘车须知协议类型 |
| | |
| | | </View> |
| | | ) |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(PassengerNotice); |
| | |
| | | import { View, Text, Image } from '@tarojs/components'; |
| | | import { useCallback, useState } from 'react'; |
| | | import { getPayPwd, RobotaxiPaySettingStatus, setPayPwd } from '../../api/payment'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | import './index.less'; |
| | | |
| | | export default function PaymentSettingDetail() { |
| | | function PaymentSettingDetail() { |
| | | const [isPayEnabled, setIsPayEnabled] = useState(true); // 当前免密支付状态 |
| | | const [isOperating, setIsOperating] = useState(false); // 当前是否正在关闭 |
| | | |
| | |
| | | </View> |
| | | ); |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(PaymentSettingDetail); |
| | |
| | | import { View, Text, Image } from '@tarojs/components'; |
| | | import { useCallback, useEffect, useRef, useState } from 'react'; |
| | | import { getPayPwd, RobotaxiPaySettingStatus, setPayPwd } from '../../api/payment'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | import './index.less'; |
| | | |
| | |
| | | /** AppShow 监听函数类型。 */ |
| | | type AppShowHandler = (payload: any) => void; |
| | | |
| | | export default function PaymentSetting() { |
| | | function PaymentSetting() { |
| | | const [isPayEnabled, setIsPayEnabled] = useState(false); // 当前是否已开通支付分 |
| | | const [isOperating, setIsOperating] = useState(false); // 当前是否正在执行操作 |
| | | const appShowListenerRef = useRef<AppShowHandler | null>(null); // 支付分回跳监听器 |
| | |
| | | </View> |
| | | ); |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(PaymentSetting); |
| | |
| | | { key: "favorite", label: "收藏站点" } |
| | | ]; |
| | | |
| | | export default function PersonalCenter() { |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | function PersonalCenter() { |
| | | const nickname = useSelector((state: any) => state.user?.userInfo?.nickName) || "小鹏艺术家"; |
| | | |
| | | const [showFavoritePopup, setShowFavoritePopup] = useState(false); |
| | |
| | | </View> |
| | | ); |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(PersonalCenter); |
| | |
| | | import { useState, useEffect } from 'react'; |
| | | import { View, Text } from '@tarojs/components'; |
| | | import { getPricingRules } from '../../api/pricing'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | import './index.less'; |
| | | |
| | | type AnyRecord = Record<string, any>; |
| | |
| | | return val !== null && val !== undefined && val !== ''; |
| | | } |
| | | |
| | | export default function PricingRulesPage() { |
| | | function PricingRulesPage() { |
| | | const [loading, setLoading] = useState(true); |
| | | const [mockJson, setMockJson] = useState<AnyRecord>({}); |
| | | |
| | |
| | | ); |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(PricingRulesPage); |
| | | |
| | |
| | | import { useEffect, useState } from 'react'; |
| | | import './index.less' |
| | | import { getRideGuideList } from '../../api/home'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | /** 默认图片地址 */ |
| | | const DEFAULT_IMAGE_URL = ''; |
| | |
| | | } |
| | | } |
| | | |
| | | export default function PassengerNotice() { |
| | | function PassengerNotice() { |
| | | const [content, setContent] = useState(''); |
| | | |
| | | useEffect(() => { |
| | |
| | | </View> |
| | | ) |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(PassengerNotice); |
| | |
| | | import { View, Image, Input, ScrollView } from '@tarojs/components'; |
| | | import './index.less'; |
| | | import { getOpenCity, getCityList } from '../../api/select-city'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | |
| | | |
| | | export default function SelectCityPage() { |
| | | function SelectCityPage() { |
| | | const [scrollIntoView, setScrollIntoView] = useState(''); // 滚动到的城市字母 |
| | | const [searchValue, setSearchValue] = useState(''); // 搜索值 |
| | | const [selectedCity, setSelectedCity] = useState<any>({}); // 选中的城市 |
| | |
| | | </View> |
| | | ) |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(SelectCityPage); |
| | |
| | | MAP_SELECT_DROPOFF_PAGE_VIEW_EVENT_ID, |
| | | PIN_PICKUP_LOCATION_PAGE_VIEW_EVENT_ID |
| | | } from '../begin-route/constants/report-events'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | /** |
| | | * 地图选点页入口:负责 hook 编排与视图组装。 |
| | | */ |
| | | export default function SelectMapSite() { |
| | | function SelectMapSite() { |
| | | const selectMapSite = useSelectMapSite(); |
| | | const hasReportedPickupPageViewRef = useRef(false); |
| | | const hasReportedDropoffPageViewRef = useRef(false); |
| | |
| | | /> |
| | | ); |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(SelectMapSite); |
| | |
| | | import { checkOtp } from '../../../utils/tools'; |
| | | import { jumpToHome } from '../../../utils/jump'; |
| | | import { safeMakePhoneCall } from '../../../utils/Robotaxi-public-method'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | type StatusRule = { |
| | | showPickup: boolean; |
| | |
| | | translateCar: boolean; |
| | | }; |
| | | |
| | | export default function ShareTrip() { |
| | | function ShareTrip() { |
| | | const router = useRouter(); |
| | | const { orderId = '' } = router.params || {}; // 分享订单 ID |
| | | const [tripData, setTripData] = useState<any>(null); // 行程详情数据 |
| | |
| | | /> |
| | | ); |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(ShareTrip); |
| | |
| | | completeConfirmRideSelectionSession, |
| | | writeConfirmRideSiteSourceType |
| | | } from '../begin-route/constants/confirm-ride-report'; |
| | | import { withRobotaxiWhitelist } from '../../../utils/whitelist'; |
| | | |
| | | /** |
| | | * 安全解析路由关键字,兼容已编码和未编码两种入参。 |
| | |
| | | } |
| | | }; |
| | | |
| | | export default function SiteSearchPage() { |
| | | function SiteSearchPage() { |
| | | const [searchValue, setSearchValue] = useState('') //搜索值 |
| | | const [showAllHistory, setShowAllHistory] = useState(false) // 是否展示全部历史记录 |
| | | const [showAllRecommend, setShowAllRecommend] = useState(false) // 是否展示全部推荐站点 |
| | |
| | | </View> |
| | | ) |
| | | } |
| | | |
| | | export default withRobotaxiWhitelist(SiteSearchPage); |
| | |
| | | import Taro from '@tarojs/taro'; |
| | | import Taro, { useDidShow } from '@tarojs/taro'; |
| | | import { isWhiteList } from '../robotaxi/api/home'; |
| | | import { checkOtp } from './tools'; |
| | | |
| | | import React, { ComponentType } from 'react'; |
| | | |
| | | /** 白名单拦截页路由。 */ |
| | | export const WHITELIST_BLOCK_PAGE_URL = '/pages/not-on-whitelist/index'; |
| | |
| | | } |
| | | return whitelistAccessResult; |
| | | } |
| | | |
| | | /** |
| | | * Robotaxi 页面专用白名单拦截高阶组件 (HOC)。 |
| | | * 包装页面组件,在页面的 useDidShow 阶段自动检查。 |
| | | */ |
| | | export function withRobotaxiWhitelist<P extends object>(WrappedComponent: ComponentType<P>): ComponentType<P> { |
| | | return function WithRobotaxiWhitelist(props: P) { |
| | | useDidShow(() => { |
| | | checkWhitelistAccess().then((whitelistAccessResult) => { |
| | | if (whitelistAccessResult === 'deny') { |
| | | redirectToWhitelistBlockPage(); |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | return React.createElement(WrappedComponent, props); |
| | | }; |
| | | } |
| | | |