perf: 顶栏复用登录菜单,瘦身 userInfo 持久化

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zzh 2026-07-18 23:39:29 +08:00
parent d3e1c62043
commit 00285ac6a8
3 changed files with 41 additions and 17 deletions

View File

@ -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;

View File

@ -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

View File

@ -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)