| src/app.config.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/app.tsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/not-on-whitelist/index.config.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/not-on-whitelist/index.less | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/not-on-whitelist/index.tsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/utils/whitelist.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/app.config.ts
@@ -7,6 +7,7 @@ if (process.env.TARO_ENV === 'weapp') { pages = [ 'pages/not-on-whitelist/index', // 'pages/home/index', 'pages/robotaxi/home/index', 'pages/xpeng/index', src/app.tsx
@@ -23,6 +23,7 @@ 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; @@ -93,7 +94,7 @@ this.xpReportSend({ pageId: 'P10107', buttonId: 'B001' }); } componentDidShow() { async componentDidShow() { wsManager.onAppShow(); if (ENV === 'weapp' && Taro.canIUse('onBeforePageUnload') && Taro.canIUse('offBeforePageUnload')) { // @ts-ignore @@ -106,6 +107,11 @@ this.scene = router.scene; } if (router.scene === 1154) { return; } const whitelistAccessResult = await this.handleWhitelistGuard(); if (whitelistAccessResult === 'deny') { return; } @@ -127,6 +133,17 @@ } /** * 执行全局白名单守卫。 */ handleWhitelistGuard = async () => { const whitelistAccessResult = await checkWhitelistAccess(); if (whitelistAccessResult === 'deny') { await redirectToWhitelistBlockPage(); } return whitelistAccessResult; } componentDidHide() { wsManager.onAppHide(); if (ENV === 'weapp' && Taro.canIUse('offBeforePageUnload')) { src/pages/not-on-whitelist/index.config.ts
New file @@ -0,0 +1,4 @@ export default { navigationStyle: 'custom', disableScroll: true, }; src/pages/not-on-whitelist/index.less
New file @@ -0,0 +1,12 @@ .not-on-whitelist-page { width: 100vw; height: 100vh; overflow: hidden; background: #ffffff; } .not-on-whitelist-image { width: 100%; height: 100%; display: block; } src/pages/not-on-whitelist/index.tsx
New file @@ -0,0 +1,29 @@ import Taro, { useDidShow } from '@tarojs/taro'; import { Image, View } from '@tarojs/components'; import { syncWhitelistBlockPageAccess } from '../../utils/whitelist'; import './index.less'; /** 白名单拦截图 CDN 地址。 */ const NOT_ON_WHITELIST_IMAGE_URL = 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/not-on-whitelist.png'; /** * 非白名单拦截页。 */ export default function NotOnWhitelist() { useDidShow(() => { if (typeof Taro.hideHomeButton === 'function') { Taro.hideHomeButton(); } void syncWhitelistBlockPageAccess(); }); return ( <View className="not-on-whitelist-page"> <Image className="not-on-whitelist-image" src={NOT_ON_WHITELIST_IMAGE_URL} mode="aspectFill" /> </View> ); } src/utils/whitelist.ts
New file @@ -0,0 +1,134 @@ import Taro from '@tarojs/taro'; import { isWhiteList } from '../robotaxi/api/home'; import { checkOtp } from './tools'; /** 白名单拦截页路由。 */ export const WHITELIST_BLOCK_PAGE_URL = '/pages/not-on-whitelist/index'; /** Robotaxi 首页路由。 */ export const ROBOTAXI_HOME_PAGE_URL = '/pages/robotaxi/home/index'; /** 白名单守卫结果。 */ export type WhitelistAccessResult = 'pass' | 'guest' | 'deny' | 'skip'; /** 白名单守卫豁免路由。 */ const WHITELIST_EXEMPT_ROUTES = [ 'pages/not-on-whitelist/index', 'pages/user/login', ]; /** 白名单请求并发锁。 */ let whitelistCheckTask: Promise<WhitelistAccessResult> | null = null; /** 白名单拦截跳转锁。 */ let isRedirectingToWhitelistBlockPage = false; /** * 判断当前页面是否跳过白名单守卫。 */ export function isWhitelistExemptPage(route: string) { return WHITELIST_EXEMPT_ROUTES.includes(route); } /** * 获取白名单拦截页地址。 */ export function getWhitelistBlockPageUrl() { return WHITELIST_BLOCK_PAGE_URL; } /** * 获取 Robotaxi 首页地址。 */ export function getRobotaxiHomePageUrl() { return ROBOTAXI_HOME_PAGE_URL; } /** * 获取当前页面路由。 */ export function getCurrentRoute() { const pages = Taro.getCurrentPages(); const currentPage = pages[pages.length - 1]; return currentPage?.route || ''; } /** * 校验当前访问是否允许进入 Robotaxi 业务页。 */ export async function checkWhitelistAccess(options?: { ignoreRouteExempt?: boolean }): Promise<WhitelistAccessResult> { const currentRoute = getCurrentRoute(); if (!options?.ignoreRouteExempt && isWhitelistExemptPage(currentRoute)) { return 'skip'; } if (whitelistCheckTask) { return whitelistCheckTask; } whitelistCheckTask = (async () => { const otp = await checkOtp(false); if (!otp) { return 'guest'; } try { const whitelistResult = await isWhiteList(); return whitelistResult ? 'pass' : 'deny'; } catch (error) { console.error('白名单校验失败', error); return 'pass'; } })(); return whitelistCheckTask.finally(() => { whitelistCheckTask = null; }); } /** * 跳转到白名单拦截页。 */ export async function redirectToWhitelistBlockPage() { const currentRoute = getCurrentRoute(); if (isRedirectingToWhitelistBlockPage || currentRoute === WHITELIST_BLOCK_PAGE_URL.replace(/^\//, '')) { return; } isRedirectingToWhitelistBlockPage = true; try { await Taro.reLaunch({ url: WHITELIST_BLOCK_PAGE_URL, }); } finally { setTimeout(() => { isRedirectingToWhitelistBlockPage = false; }, 300); } } /** * 跳回 Robotaxi 首页。 */ export async function redirectToRobotaxiHomePage() { const currentRoute = getCurrentRoute(); if (currentRoute === ROBOTAXI_HOME_PAGE_URL.replace(/^\//, '')) { return; } await Taro.reLaunch({ url: ROBOTAXI_HOME_PAGE_URL, }); } /** * 白名单拦截页自恢复:白名单命中后自动返回首页。 */ export async function syncWhitelistBlockPageAccess() { const whitelistAccessResult = await checkWhitelistAccess({ ignoreRouteExempt: true }); // 白名单页不允许未登录用户停留,游客态或白名单恢复后都回首页。 if (whitelistAccessResult === 'guest' || whitelistAccessResult === 'pass') { await redirectToRobotaxiHomePage(); } return whitelistAccessResult; }