修复bug
This commit is contained in:
@@ -6,6 +6,10 @@
|
||||
* if (!requireLogin()) return
|
||||
*
|
||||
* 页面级调用即可,全局 navigateTo 拦截器(App.vue onLaunch 中注册)作为兜底。
|
||||
*
|
||||
* 防重复机制:
|
||||
* _loginPending — requireLogin 立即设置,阻止在 setTimeout 等待期内重复调度
|
||||
* _loginNavigating — navigateToLogin 设置,阻止实际跳转重复
|
||||
*/
|
||||
|
||||
/** 无需登录即可访问的页面路径白名单(全局拦截器使用) */
|
||||
@@ -18,6 +22,73 @@ export const PUBLIC_PATHS = [
|
||||
'/pages/navigation/navigation'
|
||||
]
|
||||
|
||||
// ==================== 登录页跳转防重复锁 ====================
|
||||
// 使用 getApp().globalData 存储,避免模块被分包/异步 chunk 多次实例化导致锁失效
|
||||
|
||||
function getLock() {
|
||||
const app = getApp()
|
||||
if (!app.globalData) app.globalData = {}
|
||||
return app.globalData
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前是否已在登录页
|
||||
*/
|
||||
function isOnLoginPage() {
|
||||
const pages = getCurrentPages()
|
||||
if (!pages || pages.length === 0) return false
|
||||
const route = pages[pages.length - 1].route || ''
|
||||
return route.includes('loginSub/login')
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到登录页(统一入口,带防重复锁)
|
||||
* 所有需要跳转登录页的地方都应调用此函数,不要直接调用 uni.navigateTo / uni.reLaunch
|
||||
*
|
||||
* @param {object} [options]
|
||||
* @param {string} [options.method='navigateTo'] - 跳转方式:'navigateTo' | 'reLaunch' | 'redirectTo'
|
||||
* @param {string} [options.url='/pageSubPack/loginSub/login?mode=pwd'] - 目标 url
|
||||
*/
|
||||
export function navigateToLogin(options = {}) {
|
||||
const {
|
||||
method = 'navigateTo',
|
||||
url = '/pageSubPack/loginSub/login?mode=pwd'
|
||||
} = options
|
||||
|
||||
// 已经在登录页,跳过
|
||||
if (isOnLoginPage()) return
|
||||
|
||||
const lock = getLock()
|
||||
|
||||
// reLaunch 优先级最高,强制放行(用于 token 过期、退出登录等场景)
|
||||
if (method !== 'reLaunch' && lock._loginNavigating) return
|
||||
|
||||
lock._loginNavigating = true
|
||||
|
||||
const navFn = uni[method]
|
||||
if (!navFn) {
|
||||
lock._loginNavigating = false
|
||||
return
|
||||
}
|
||||
|
||||
navFn({
|
||||
url,
|
||||
fail() {
|
||||
// 跳转失败时重置锁,允许后续重试
|
||||
lock._loginNavigating = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置登录跳转锁(登录页 onLoad 时调用)
|
||||
*/
|
||||
export function resetLoginLock() {
|
||||
const lock = getLock()
|
||||
lock._loginPending = false
|
||||
lock._loginNavigating = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断指定路径是否为公开页面(无需登录)
|
||||
* @param {string} url - navigateTo 的目标 url
|
||||
@@ -40,15 +111,21 @@ export function isPublicPath(url) {
|
||||
export function requireLogin(options = {}) {
|
||||
const {
|
||||
message = '请先登录',
|
||||
redirect = true
|
||||
redirect = true
|
||||
} = options
|
||||
const token = uni.getStorageSync('token')
|
||||
if (token) return true
|
||||
|
||||
uni.showToast({ title: message, icon: 'none' })
|
||||
if (redirect) {
|
||||
// 立即加锁,防止在 setTimeout 等待期内重复调度
|
||||
const lock = getLock()
|
||||
if (lock._loginPending) return false
|
||||
lock._loginPending = true
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({ url: '/pageSubPack/loginSub/login?mode=pwd' })
|
||||
lock._loginPending = false
|
||||
navigateToLogin({ method: 'navigateTo' })
|
||||
}, 1000)
|
||||
}
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user