305 lines
7.1 KiB
JavaScript
305 lines
7.1 KiB
JavaScript
/**
|
|
* 路由权限拦截器
|
|
* 自动拦截配置好的路径,未登录时自动弹出登录弹窗
|
|
*
|
|
* 使用方式:在 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/memberCard',
|
|
'/pages/memberInfo/purchaseCard',
|
|
'/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]
|
|
}
|