完善状态验证
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<view class="layout-root">
|
||||
<view v-if="!isAuthReady" class="auth-loading-overlay" style="flex: 1; display: flex; align-items: center; justify-content: center; height: 100vh; background-color: #f5f5f5;">
|
||||
<text style="color: #666; font-size: 16px;">身份鉴权中...</text>
|
||||
@@ -79,7 +79,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
||||
import AdminAside from '@/layouts/admin/components/AdminAside.uvue'
|
||||
import AdminSubSider from '@/layouts/admin/components/AdminSubSider.uvue'
|
||||
import AdminHeader from '@/layouts/admin/components/AdminHeader.uvue'
|
||||
@@ -121,7 +121,8 @@ import {
|
||||
import type { TabItem } from '@/layouts/admin/store/adminNavStore.uts'
|
||||
|
||||
import { getComponent } from '@/layouts/admin/router/adminComponentMap.uts'
|
||||
import { hasAdminModuleAccess, refreshAdminRole } from '@/layouts/admin/utils/role.uts'
|
||||
import { hasAdminModuleAccess } from '@/layouts/admin/utils/role.uts'
|
||||
import { ensureAdminSession, handleSessionExpired } from '@/layouts/admin/utils/adminAuth.uts'
|
||||
|
||||
const props = defineProps({
|
||||
currentPage: {
|
||||
@@ -396,7 +397,26 @@ function onNotify(): void {
|
||||
let resizeTid: any = null
|
||||
|
||||
onMounted(async () => {
|
||||
await refreshAdminRole()
|
||||
// 挂载鉴权相关的事件监听器,并在首次进入时阻断认证
|
||||
try {
|
||||
const isOk = await ensureAdminSession()
|
||||
if (!isOk) {
|
||||
return // 鉴权失败内部已处理跳转,终止后续挂载
|
||||
}
|
||||
} catch (e) {
|
||||
handleSessionExpired()
|
||||
return
|
||||
}
|
||||
|
||||
uni.$on('AUTH_SESSION_EXPIRED', () => { handleSessionExpired() })
|
||||
|
||||
// 增加 visibilitychange 监听:在用户电脑休眠或者长时间放置重新激活时,核验会话
|
||||
// #ifdef H5
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('visibilitychange', handleVisibilityChange)
|
||||
}
|
||||
// #endif
|
||||
|
||||
isAuthReady.value = true
|
||||
initNavState()
|
||||
if (props.currentPage != '') {
|
||||
@@ -431,6 +451,34 @@ onMounted(async () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// ===== Auth State Handlers =====
|
||||
let _lastVisibilityCheck = 0
|
||||
const handleVisibilityChange = async () => {
|
||||
// #ifdef H5
|
||||
if (document.visibilityState === 'visible') {
|
||||
const now = Date.now()
|
||||
// 节流机制,防止频繁切换标签页产生过多校验
|
||||
if (now - _lastVisibilityCheck < 10000) return
|
||||
_lastVisibilityCheck = now
|
||||
|
||||
// 简易验证即可,如果底层 token 已经失效而 fetch 拿不到,就会报出 401 触发全局 AUTH_SESSION_EXPIRED
|
||||
try {
|
||||
await ensureAdminSession()
|
||||
} catch(e) {}
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
uni.$off('AUTH_SESSION_EXPIRED')
|
||||
// #ifdef H5
|
||||
if (typeof window !== 'undefined') {
|
||||
window.removeEventListener('visibilitychange', handleVisibilityChange)
|
||||
}
|
||||
// #endif
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
Reference in New Issue
Block a user