/** * 路由权限拦截器 * 自动拦截配置好的路径,未登录时自动弹出登录弹窗 * * 使用方式:在 App.vue 中 import 并调用 init() 即可 * 无需在每个页面单独配置 */ import { getToken } from '@/utils/request.js' /** * 白名单 - 不需要登录即可访问的页面 */ const WHITE_LIST = [ '/pages/index/index', '/pages/course/course', '/pages/memberInfo/login', '/pages/memberInfo/register', '/pages/memberInfo/forgetPassword', '/pages/about/about', '/pages/help/help', '/pages/notice/notice', '/pages/product/product', '/pages/store/store', '/pages/article/article', '/pages/search/search' ] /** * 需要登录的页面路径前缀 * 匹配以下前缀的页面都需要登录 */ const LOGIN_REQUIRED_PREFIXES = [ '/pages/memberInfo/checkIn', '/pages/memberInfo/booking', '/pages/memberInfo/coupons', '/pages/memberInfo/points', '/pages/memberInfo/userInfo', '/pages/memberInfo/order', '/pages/memberInfo/settings', '/pages/memberInfo/feedback', '/pages/memberInfo/invite', '/pages/memberInfo/recharge' ] /** * 需要登录的具体页面路径 */ const LOGIN_REQUIRED_PATHS = [ '/pages/memberInfo/memberInfo' ] /** * 检查当前路径是否需要登录 * @param {String} url - 页面路径(可能包含query参数) * @returns {Boolean} */ function isNeedLogin(url) { // 去掉query参数 const path = url.split('?')[0] // 检查白名单 if (WHITE_LIST.includes(path)) { return false } // 检查具体路径 if (LOGIN_REQUIRED_PATHS.includes(path)) { return true } // 检查路径前缀 if (LOGIN_REQUIRED_PREFIXES.some(prefix => path.startsWith(prefix))) { return true } return false } /** * 检查用户是否已登录 * @returns {Boolean} */ function isLoggedIn() { const token = getToken() const isLoginStorage = uni.getStorageSync('isLogin') return !!(token || isLoginStorage) } /** * 登录弹窗组件引用(需要在App.vue中注册) */ let loginModalRef = null /** * 注册登录弹窗组件 * @param {Object} modalRef - LoginModal组件的ref */ export function registerLoginModal(modalRef) { loginModalRef = modalRef } /** * 显示登录弹窗 */ function showLoginModal() { if (loginModalRef) { loginModalRef.show() } else { // 如果没有注册弹窗,跳转到登录页 uni.navigateTo({ url: '/pages/memberInfo/login' }) } } /** * 记录用户原本要访问的页面 * @param {String} url - 页面路径 */ function saveRedirectUrl(url) { uni.setStorageSync('redirectUrl', url) } /** * 获取用户原本要访问的页面 * @returns {String|null} */ export function getRedirectUrl() { const url = uni.getStorageSync('redirectUrl') uni.removeStorageSync('redirectUrl') return url } /** * 跳转到用户原本要访问的页面 */ export function redirectToSavedUrl() { const url = getRedirectUrl() if (url) { uni.navigateTo({ url: url, fail: () => { uni.switchTab({ url: '/pages/index/index' }) } }) } } /** * 初始化路由拦截器 */ export function initPermissionInterceptor() { console.log('[PermissionInterceptor] 初始化路由拦截器') // 拦截 navigateTo uni.addInterceptor('navigateTo', { invoke(args) { const url = args.url if (isNeedLogin(url) && !isLoggedIn()) { console.log('[PermissionInterceptor] 拦截 navigateTo:', url) saveRedirectUrl(url) showLoginModal() return false } return true }, success() { // 跳转成功 }, fail(err) { console.error('[PermissionInterceptor] navigateTo 失败:', err) } }) // 拦截 redirectTo uni.addInterceptor('redirectTo', { invoke(args) { const url = args.url if (isNeedLogin(url) && !isLoggedIn()) { console.log('[PermissionInterceptor] 拦截 redirectTo:', url) saveRedirectUrl(url) showLoginModal() return false } return true }, success() {}, fail(err) { console.error('[PermissionInterceptor] redirectTo 失败:', err) } }) // 拦截 reLaunch uni.addInterceptor('reLaunch', { invoke(args) { const url = args.url if (isNeedLogin(url) && !isLoggedIn()) { console.log('[PermissionInterceptor] 拦截 reLaunch:', url) saveRedirectUrl(url) showLoginModal() return false } return true }, success() {}, fail(err) { console.error('[PermissionInterceptor] reLaunch 失败:', err) } }) // 拦截 switchTab uni.addInterceptor('switchTab', { invoke(args) { const url = args.url if (isNeedLogin(url) && !isLoggedIn()) { console.log('[PermissionInterceptor] 拦截 switchTab:', url) saveRedirectUrl(url) showLoginModal() return false } return true }, success() {}, fail(err) { console.error('[PermissionInterceptor] switchTab 失败:', err) } }) // 拦截 navigateBack uni.addInterceptor('navigateBack', { invoke() { return true }, success() {}, fail() {} }) console.log('[PermissionInterceptor] 路由拦截器初始化完成') } /** * 添加需要登录的页面路径 * @param {String|Array} paths - 页面路径或路径数组 */ export function addLoginRequiredPaths(paths) { if (Array.isArray(paths)) { LOGIN_REQUIRED_PATHS.push(...paths) } else { LOGIN_REQUIRED_PATHS.push(paths) } } /** * 添加需要登录的页面路径前缀 * @param {String|Array} prefixes - 路径前缀或前缀数组 */ export function addLoginRequiredPrefixes(prefixes) { if (Array.isArray(prefixes)) { LOGIN_REQUIRED_PREFIXES.push(...prefixes) } else { LOGIN_REQUIRED_PREFIXES.push(prefixes) } } /** * 添加到白名单 * @param {String|Array} paths - 页面路径或路径数组 */ export function addWhiteList(paths) { if (Array.isArray(paths)) { WHITE_LIST.push(...paths) } else { WHITE_LIST.push(paths) } } /** * 获取当前配置的白名单 * @returns {Array} */ export function getWhiteList() { return [...WHITE_LIST] } /** * 获取当前配置的需要登录的路径 * @returns {Array} */ export function getLoginRequiredPaths() { return [...LOGIN_REQUIRED_PATHS] } /** * 获取当前配置的需要登录的路径前缀 * @returns {Array} */ export function getLoginRequiredPrefixes() { return [...LOGIN_REQUIRED_PREFIXES] }