This commit is contained in:
zlwu committed 2026-07-13 20:26:43 +08:00
1 parent 3520f9ce90
commit 0e60b88cba
104 files changed
+344311 -250708

No files matched your search

+40 -7
View File
@@ -72,13 +72,37 @@ export class MenuProcessor {
})
}
/**
* 解析 Web 端角色(优先使用后端 current-user/login 的 role 字段)。
* 避免 Pinia 持久化的旧 roles(模板/demo 遗留)覆盖真实 role 导致菜单被滤空。
*/
private resolveWebRoles(info: Api.Auth.UserInfo | Record<string, any> | undefined): string[] | undefined {
const webRole = String(info?.role ?? '').trim()
if (webRole) {
return [webRole]
}
if (info?.roles?.length) {
return info.roles
}
return undefined
}
/**
* 是否超级管理员(跳过后端 menuCodes 过滤)
*/
private isSuperAdminRole(info: Api.Auth.UserInfo | Record<string, any> | undefined): boolean {
const webRole = String(info?.role ?? '').trim()
if (webRole === 'super_admin') return true
return Array.isArray(info?.roles) && info.roles.includes('super_admin')
}
/**
* 处理前端控制模式的菜单
*/
private async processFrontendMenu(): Promise<AppRouteRecord[]> {
const userStore = useUserStore()
const info = userStore.info
const roles = info?.roles?.length ? info.roles : info?.role ? [info.role] : undefined
const roles = this.resolveWebRoles(info)
let menuList = [...asyncRoutes]
@@ -90,14 +114,23 @@ export class MenuProcessor {
}
}
// 静态菜单模式下,admin 按后端返回的 menuCodes 过滤菜单
if (info?.role === 'admin') {
// 静态菜单模式下,非 super_admin 按后端返回的 menuCodes 过滤菜单
if (!this.isSuperAdminRole(info)) {
const perm = await fetchGetMenuCodes()
const codeSet = new Set(
(perm?.menuCodes || []).map((x) => this.normalizeMenuCode(x)).filter(Boolean)
)
if (!perm?.all) {
menuList = this.filterMenuByCodes(menuList, codeSet)
const filtered = this.filterMenuByCodes(menuList, codeSet)
// 有 menuCodes 但过滤后为空,多为 roles/menuCode 配置异常,保留角色过滤结果便于排查
if (filtered.length > 0 || codeSet.size === 0) {
menuList = filtered
} else {
console.warn(
'[MenuProcessor] menuCodes 非空但过滤后菜单为空,保留角色过滤后的菜单树',
codeSet.size
)
}
}
}
@@ -179,9 +212,9 @@ export class MenuProcessor {
return item
})
.filter((item) => {
// 如果定义了 children 属性(即使是空数组),说明这是一个目录菜单,应该保留
if ('children' in item) {
return true
// 仅当 children 为数组时视为目录;勿用 `'children' in item`(spread 后叶子常为 children: undefined)
if (Array.isArray(item.children)) {
return item.children.length > 0
}
// 如果有外链或 iframe,保留