From af08f469fb7e695248cf4f8789d03cfd2fb4b67f Mon Sep 17 00:00:00 2001 From: zhoutc <1305666981@qq.com> Date: Mon, 9 Mar 2026 02:19:11 +0800 Subject: [PATCH] 1 --- src/App.vue | 29 +++++++++++++++++++---------- src/router/index.ts | 8 ++++++++ src/types/mitt.d.ts | 1 + 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/App.vue b/src/App.vue index 386244a..2ce16bb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -82,6 +82,19 @@ async function validateCachedRoleId(): Promise { } } +/** 有 token 时执行角色校验:缓存 roleId 无效则清缓存并弹框,缺角色信息则弹框(与 onMounted 内逻辑一致) */ +async function runRoleValidationAndOpenDialogIfNeeded() { + if (!Session.getToken()) return; + const needOpenByInvalidRole = await validateCachedRoleId(); + if (needOpenByInvalidRole && !isRoleDialogTriggered()) { + setRoleDialogTriggered(true); + mittBus.emit('openRoleSelectDialog'); + } else if (!needOpenByInvalidRole && needRoleSelection() && !isRoleDialogTriggered()) { + setRoleDialogTriggered(true); + mittBus.emit('openRoleSelectDialog'); + } +} + onMounted(() => { // 唯一入口:只通过事件打开,且只打开一次;延迟打开以等待异步组件挂载 mittBus.on('openRoleSelectDialog', () => { @@ -99,6 +112,10 @@ onMounted(() => { }; tryOpen(); }); + // token 来自 URL 时由路由 afterEach 发出,此时 App 已挂载但 onMounted 时可能尚无 token,需在此补跑一次校验 + mittBus.on('validateRoleFromUrl', () => { + runRoleValidationAndOpenDialogIfNeeded(); + }); nextTick(async () => { // 监听布局配置弹窗点击打开 mittBus.on('openSettingsDrawer', () => { @@ -114,22 +131,14 @@ onMounted(() => { stores.setCurrenFullscreen(Session.get('isTagsViewCurrenFull')); } // 有 token 时:先校验缓存 roleId 是否仍有效,无效则清缓存并弹框选角色 - if (Session.getToken()) { - const needOpenByInvalidRole = await validateCachedRoleId(); - if (needOpenByInvalidRole && !isRoleDialogTriggered()) { - setRoleDialogTriggered(true); - mittBus.emit('openRoleSelectDialog'); - } else if (!needOpenByInvalidRole && needRoleSelection() && !isRoleDialogTriggered()) { - setRoleDialogTriggered(true); - mittBus.emit('openRoleSelectDialog'); - } - } + await runRoleValidationAndOpenDialogIfNeeded(); }); }); // 页面销毁时,关闭监听 onUnmounted(() => { mittBus.off('openSettingsDrawer', () => {}); mittBus.off('openRoleSelectDialog'); + mittBus.off('validateRoleFromUrl'); }); // 监听路由的变化,设置网站标题 watch( diff --git a/src/router/index.ts b/src/router/index.ts index 53dfb37..d28d90f 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -7,6 +7,7 @@ import { useKeepALiveNames } from '/@/stores/keepAliveNames'; import { useRoutesList } from '/@/stores/routesList'; import { useUserInfo } from '/@/stores/userInfo'; import { Session } from '/@/utils/storage'; +import mittBus from '/@/utils/mitt'; import { staticRoutes, notFoundAndNoPower } from '/@/router/route'; import { initBackEndControlRoutes } from '/@/router/backEnd'; import { flowConfig } from '/@/flow/designer/config/flow-config'; @@ -98,6 +99,8 @@ router.beforeEach(async (to, from, next) => { const urlToken = to.query?.token as string | undefined; if (urlToken) { useUserInfo().setTokenCache(urlToken, to.query?.refresh_token as string | undefined); + // 标记「本次 token 来自 URL」,供 afterEach 触发角色校验;因 setTokenCache 在 beforeEach 执行,可能晚于 App.onMounted,需单独触发校验以清除无效 roleId + Session.set('tokenFromUrl', 1); } // 若上面刚写了 token,后续用去掉 token 的 query 做一次 replace(在 init 之后统一做,保证只一次导航、tagsView 能正确加 tag) const stripTokenQuery = @@ -148,6 +151,11 @@ router.beforeEach(async (to, from, next) => { router.afterEach(() => { NProgress.done(); NextLoading.done(); + // token 来自 URL 时,App.onMounted 可能已先执行且当时无 token,需在导航完成后触发一次角色校验(清无效 roleId + 弹框) + if (Session.get('tokenFromUrl')) { + Session.remove('tokenFromUrl'); + mittBus.emit('validateRoleFromUrl'); + } }); // 导出路由 diff --git a/src/types/mitt.d.ts b/src/types/mitt.d.ts index 8dc82a4..b19ce20 100644 --- a/src/types/mitt.d.ts +++ b/src/types/mitt.d.ts @@ -24,6 +24,7 @@ declare type MittType = { onTagsViewRefreshRouterView?: T; onCurrentContextmenuClick?: T; openRoleSelectDialog?: string; + validateRoleFromUrl?: string; }; // mitt 参数类型定义