82 lines
2.5 KiB
Plaintext
82 lines
2.5 KiB
Plaintext
import { state, getCurrentUser } from '@/utils/store.uts'
|
||
import { clearAdminRoleCache, refreshAdminRole } from './role.uts'
|
||
import supa, { supaReady } from '@/components/supadb/aksupainstance.uts'
|
||
|
||
let __isHandlingExpired = false
|
||
|
||
/**
|
||
* 统一“登录过期”闭环处理
|
||
* - 防止重复弹窗
|
||
* - 清理所有认证、用户相关缓存
|
||
* - 重置状态树
|
||
* - 统一跳转回登录页
|
||
*/
|
||
export function handleSessionExpired(reason?: string) {
|
||
if (__isHandlingExpired) return
|
||
__isHandlingExpired = true
|
||
|
||
console.warn('[AdminAuth] 执行会话过期统一闭环:', reason ?? '未知原因')
|
||
|
||
// 1. 弹出提示 (确保只弹一次)
|
||
uni.showToast({
|
||
title: '登录已过期,请重新登录',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
|
||
// 2. 清除本地相关存储
|
||
try {
|
||
supa.signOut()
|
||
} catch(e){}
|
||
clearAdminRoleCache()
|
||
|
||
// 3. 重置全局业务状态树,防止其他组件看到旧内存残影
|
||
state.isLoggedIn = false
|
||
state.authUser = null
|
||
state.userProfile = { username: '', email: '' }
|
||
|
||
// 4. 跳转登录页
|
||
setTimeout(() => {
|
||
uni.reLaunch({
|
||
url: '/pages/user/login'
|
||
})
|
||
setTimeout(() => { __isHandlingExpired = false }, 1000)
|
||
}, 1000)
|
||
}
|
||
|
||
|
||
/**
|
||
* 统一的后台启动恢复授权流程
|
||
* 返回是否恢复/保持有效的登录态
|
||
*/
|
||
export async function ensureAdminSession(): Promise<boolean> {
|
||
try {
|
||
// ① 等待 hydrateSessionFromStorage() 完成(从storage恢复token→异步网络请求)
|
||
// 必须在 getSession() 之前 await,否则刷新后 this.session 仍为 null,
|
||
// 会被误判为未登录并触发 handleSessionExpired。
|
||
try { await supaReady } catch (_) {}
|
||
|
||
const sessionInfo = supa.getSession()
|
||
if (sessionInfo.session == null) {
|
||
console.warn('[AdminAuth] 没有发现凭证,要求重新登录')
|
||
handleSessionExpired('No credentials found')
|
||
return false
|
||
}
|
||
|
||
// 主动检查并补齐
|
||
const role = await refreshAdminRole()
|
||
if (role === 'unknown' || (state.userProfile != null && state.userProfile!.id == null)) {
|
||
// 等等,如果是断网状态呢?其实 store 里已经用 status <= 0 判断过断网了。
|
||
// 上一步在 store/getCurrentUser 时,如果返回 401 才会真正导致清空。
|
||
console.warn('[AdminAuth] Session被认为无效或用户确权失败')
|
||
handleSessionExpired('Role verification failed')
|
||
return false
|
||
}
|
||
return true
|
||
} catch (e) {
|
||
console.error('[AdminAuth] 鉴权启动异常:', e)
|
||
handleSessionExpired('Auth exception')
|
||
return false
|
||
}
|
||
}
|