From 00285ac6a86abbf74e62c2aebcbf1743b1157ef8 Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Sat, 18 Jul 2026 23:39:29 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E9=A1=B6=E6=A0=8F=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E8=8F=9C=E5=8D=95=EF=BC=8C=E7=98=A6=E8=BA=AB?= =?UTF-8?q?=20userInfo=20=E6=8C=81=E4=B9=85=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- src/components/top-nav/index.vue | 21 ++++++++++++--------- src/store/modules/auth/index.ts | 12 ++++++++++-- src/store/modules/rbac-user.ts | 25 +++++++++++++++++++------ 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/components/top-nav/index.vue b/src/components/top-nav/index.vue index 130528c..b4781ab 100644 --- a/src/components/top-nav/index.vue +++ b/src/components/top-nav/index.vue @@ -344,7 +344,7 @@ const menuData = computed(() => { return convertMenuTreeToNavMenu(userMenus); }); -// 加载菜单树和用户菜单权限 +// 加载菜单:优先复用登录带回的 user menus,避免再打全量 get-menu-tree async function loadMenuTree() { menuLoading.value = true; try { @@ -354,22 +354,25 @@ async function loadMenuTree() { return; } - const currentUserMenus = rbacUserStore.menus; - if (currentUserMenus && currentUserMenus.length > 0) { - menuDataReady.value = true; - } - + let currentUserMenus = rbacUserStore.menus; if (!currentUserMenus || currentUserMenus.length === 0) { try { await rbacUserStore.getCurrentUser(); - if (rbacUserStore.menus?.length) { - menuDataReady.value = true; - } + currentUserMenus = rbacUserStore.menus; } catch (userError) { console.error('获取用户信息失败:', userError); } } + if (currentUserMenus && currentUserMenus.length > 0) { + allMenuTreeData.value = []; + await nextTick(); + menuDataReady.value = true; + tabBarStore.refreshTagTitles(); + return; + } + + // 兜底:用户 menus 仍为空时再拉全量树(管理页等特殊场景) try { const allMenus = await MenuService.getRbacMenuGetMenuTree() || []; allMenuTreeData.value = allMenus; diff --git a/src/store/modules/auth/index.ts b/src/store/modules/auth/index.ts index 38d0e6f..8a219d4 100644 --- a/src/store/modules/auth/index.ts +++ b/src/store/modules/auth/index.ts @@ -80,8 +80,16 @@ export const useAuthStore = defineStore({ return; } - // 优先使用 get-current-user 已返回的菜单,减少重复请求 - const cachedMenus = rbacUserStore.menus; + // 优先使用内存中的登录菜单;若 localStorage 瘦身后无 menus,则拉 get-current-user + let cachedMenus = rbacUserStore.menus; + if (!cachedMenus || cachedMenus.length === 0) { + try { + await rbacUserStore.getCurrentUser(); + cachedMenus = rbacUserStore.menus; + } catch { + // 继续走 get-user-menus 兜底 + } + } const menuTree = cachedMenus && cachedMenus.length > 0 ? cachedMenus diff --git a/src/store/modules/rbac-user.ts b/src/store/modules/rbac-user.ts index 0d2e1c1..9a43cd5 100644 --- a/src/store/modules/rbac-user.ts +++ b/src/store/modules/rbac-user.ts @@ -59,6 +59,22 @@ export const useRbacUserStore = defineStore('rbacUser', () => { // 兼容旧代码 const token = computed(() => accessToken.value) + /** 持久化瘦身:menus 仅留内存,避免 localStorage 写入过大 JSON */ + function persistUserInfo(info: UserInfoDto | null) { + if (!info) { + getAuthStorage().removeItem(USER_INFO_KEY) + return + } + const slim: UserInfoDto = { ...info } + delete slim.menus + getAuthStorage().setItem(USER_INFO_KEY, JSON.stringify(slim)) + } + + function setUserInfo(info: UserInfoDto) { + userInfo.value = info + persistUserInfo(info) + } + function readStoredLoginType(): OmsLoginType { const raw = getAuthStorage().getItem(LOGIN_TYPE_KEY) ?? localStorage.getItem(LOGIN_TYPE_KEY) if (raw === String(OmsLoginType.Customer)) return OmsLoginType.Customer @@ -247,8 +263,7 @@ export const useRbacUserStore = defineStore('rbacUser', () => { async function hydrateUserAfterLogin(result: LoginResultDto) { const embedded = result.userInfo if (embedded?.id) { - userInfo.value = embedded - getAuthStorage().setItem(USER_INFO_KEY, JSON.stringify(embedded)) + setUserInfo(embedded) return embedded } return getCurrentUser() @@ -262,8 +277,7 @@ export const useRbacUserStore = defineStore('rbacUser', () => { } const data = await AuthService.getRbacAuthGetCurrentUser() - userInfo.value = data - getAuthStorage().setItem(USER_INFO_KEY, JSON.stringify(data)) + setUserInfo(data) return data } catch (error) { logout() @@ -275,8 +289,7 @@ export const useRbacUserStore = defineStore('rbacUser', () => { async function refreshUserInfo() { try { const data = await AuthService.getRbacAuthGetCurrentUser() - userInfo.value = data - getAuthStorage().setItem(USER_INFO_KEY, JSON.stringify(data)) + setUserInfo(data) return data } catch (error) { handleApiError(error)