重构页面目录与 RBAC:扁平配置入口并对齐管理/运营页映射。
下线运营总览幽灵页,补 ExpandKeysForScope / PlatformToMonitor,同步导航与角色配置 UI。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -29,6 +29,18 @@ const SCOPE_KEY = 'simple.auth.scope'
|
||||
const RUN_MODE_KEY = 'simple.auth.runMode'
|
||||
const PERM_KEY = 'simple.auth.perm'
|
||||
|
||||
/** 管理页 ↔ 运营页:权限勾选任一端,菜单都认。 */
|
||||
const PAGE_TWINS: Record<string, string> = {
|
||||
'admin-ops-log': 'monitor-ops',
|
||||
'admin-notes': 'monitor-notes',
|
||||
'admin-map-monitor': 'monitor-map',
|
||||
'admin-vehicle-hub': 'monitor-vehicle-hub',
|
||||
'monitor-ops': 'admin-ops-log',
|
||||
'monitor-notes': 'admin-notes',
|
||||
'monitor-map': 'admin-map-monitor',
|
||||
'monitor-vehicle-hub': 'admin-vehicle-hub'
|
||||
}
|
||||
|
||||
// 会话 45 HC-2:每个字段独立 try/catch,避免一个 corrupt 字段把整个 state 干净化。
|
||||
function safeJsonParse<T>(key: string): T | null {
|
||||
try {
|
||||
@@ -96,14 +108,16 @@ export const useAuthStore = defineStore('auth', {
|
||||
return ops.includes('*') ? 'interactive' : 'readonly'
|
||||
},
|
||||
/**
|
||||
* 当前用户在当前 scope 下是否可访问指定页面(route.name)。
|
||||
* '*' 视为全部页面(兜底兼容)。菜单过滤与路由守卫共用此判断。
|
||||
* 当前用户是否可访问指定页面(route.name)。
|
||||
* '*' 视为全部页面。管理页与对应运营页互认(勾了 monitor-ops 也能进 admin-ops-log)。
|
||||
*/
|
||||
hasPage:
|
||||
(s) =>
|
||||
(key: string): boolean => {
|
||||
const pages = s.effectivePermissions?.allowedPages ?? []
|
||||
return pages.includes('*') || pages.includes(key)
|
||||
if (pages.includes('*') || pages.includes(key)) return true
|
||||
const twin = PAGE_TWINS[key]
|
||||
return !!twin && pages.includes(twin)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@@ -142,6 +156,10 @@ export const useAuthStore = defineStore('auth', {
|
||||
}
|
||||
try {
|
||||
const me = await apiGetMe()
|
||||
if (me.token) {
|
||||
this.token = me.token
|
||||
localStorage.setItem(TOKEN_KEY, me.token)
|
||||
}
|
||||
this.user = me.user
|
||||
this.scope = me.scope
|
||||
this.runMode = me.runMode
|
||||
|
||||
Reference in New Issue
Block a user