fix: 菜单按1-6顺序重排+规则4KPI分级

This commit is contained in:
Hermes CI Fix
2026-07-22 16:56:19 +08:00
parent d88147ca36
commit dc09a04c24
2 changed files with 41 additions and 128 deletions
+21
View File
@@ -14,6 +14,24 @@ declare module 'vue' {
BulletChart: typeof import('./src/components/charts/BulletChart.vue')['default']
ConnectionLines: typeof import('./src/components/strategy/ConnectionLines.vue')['default']
DriverFactorBudget: typeof import('./src/components/DriverFactorBudget.vue')['default']
ElAlert: typeof import('element-plus/es')['ElAlert']
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElOption: typeof import('element-plus/es')['ElOption']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElUpload: typeof import('element-plus/es')['ElUpload']
GaugeChart: typeof import('./src/components/charts/GaugeChart.vue')['default']
GrowthQuality: typeof import('./src/components/GrowthQuality.vue')['default']
KnowledgePanel: typeof import('./src/components/KnowledgePanel.vue')['default']
@@ -31,4 +49,7 @@ declare module 'vue' {
WaterfallChart: typeof import('./src/components/charts/WaterfallChart.vue')['default']
WelcomeGuide: typeof import('./src/components/WelcomeGuide.vue')['default']
}
export interface GlobalDirectives {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}
+20 -128
View File
@@ -1,73 +1,54 @@
/**
* 角色权限配置 — 管理会计OS
* 4角色: ceo(总经理), finance(财务), business(业务), it(IT运维)
*/
import { MenuItem } from '../types/menu'
// 各角色可访问的路由列表
// ── 角色路由映射 ──
export const ROLE_ROUTES: Record<string, string[]> = {
ceo: ['/my-dashboard', '/dashboard', '/kpis', '/maps', '/maps-review', '/maps/canvas', '/maps/review', '/alerts', '/notifications', '/org', '/users', '/permissions', '/budget', '/deviations', '/cost', '/predict', '/action-plans', '/knowledge', '/guide', '/customer', '/learning-dashboard', '/reports', '/alignment', '/dupont-analysis', '/okr-templates', '/mpm-calculator'],
finance: ['/my-dashboard', '/dashboard', '/kpis', '/maps', '/maps-review', '/maps/canvas', '/maps/review', '/alerts', '/data', '/budget', '/deviations', '/cost', '/predict', '/action-plans', '/knowledge', '/guide', '/customer', '/learning-dashboard', '/reports', '/alignment', '/dupont-analysis', '/okr-templates', '/mpm-calculator'],
business: ['/my-dashboard', '/dashboard', '/kpis', '/alerts', '/deviations', '/budget', '/action-plans', '/knowledge', '/guide', '/customer', '/reports', '/alignment', '/mpm-calculator'],
it: ['/my-dashboard', '/dashboard', '/kpis', '/alerts', '/data', '/org', '/users', '/permissions', '/budget', '/deviations', '/cost', '/predict', '/action-plans', '/knowledge', '/guide', '/customer', '/learning-dashboard', '/okr-templates'],
ceo: ['/my-dashboard', '/dashboard', '/kpis', '/maps', '/maps-review', '/maps/canvas', '/maps/review', '/alerts', '/notifications', '/org', '/users', '/permissions', '/budget', '/deviations', '/cost', '/predict', '/action-plans', '/knowledge', '/guide', '/customer', '/learning-dashboard', '/reports', '/alignment', '/dupont-analysis'],
finance: ['/my-dashboard', '/dashboard', '/kpis', '/maps', '/maps-review', '/maps/canvas', '/maps/review', '/alerts', '/data', '/budget', '/deviations', '/cost', '/predict', '/action-plans', '/knowledge', '/guide', '/customer', '/learning-dashboard', '/reports', '/alignment', '/dupont-analysis'],
business: ['/my-dashboard', '/dashboard', '/kpis', '/alerts', '/budget', '/deviations', '/action-plans', '/knowledge', '/guide', '/customer'],
it: ['/my-dashboard', '/dashboard', '/kpis', '/alerts', '/data', '/org', '/users', '/permissions', '/budget', '/deviations', '/cost', '/predict', '/action-plans', '/knowledge', '/guide', '/customer', '/learning-dashboard'],
}
// 可操作的CRUD权限
export const ROLE_ACTIONS: Record<string, string[]> = {
ceo: ['read'],
finance: ['read', 'write', 'import', 'export'],
ceo: ['read', 'write', 'delete', 'approve', 'export'],
finance: ['read', 'write', 'export'],
business: ['read', 'write'],
it: ['read', 'write', 'delete', 'admin'],
}
// 菜单项定义(带角色限制)
export interface MenuItem {
path: string
label: string
icon: string
roles: string[]
group?: string // 分组标识,仅首位项标记
it: ['read', 'write', 'delete'],
}
export const MENU_ITEMS: MenuItem[] = [
// ── GROUP 1: 规划与目标(Plan)──
{ path: '/my-dashboard', label: '我的工作台', icon: 'Monitor', roles: ['ceo', 'finance', 'business', 'it'], group: '🔵 P 规划与目标' },
{ path: '/maps', label: '战略地图', icon: 'DataBoard', roles: ['ceo', 'finance'], group: '🔵 P 规划与目标' },
{ path: '/budget', label: '预算管理', icon: 'Coin', roles: ['ceo', 'finance', 'business', 'it'], group: '🔵 P 规划与目标' },
{ path: '/alignment', label: '战略执行看板', icon: 'Opportunity', roles: ['ceo', 'finance', 'business', 'it'], group: '🔵 P 规划与目标' },
// ══════════════════════════════════════════════════════════════
// GROUP 2: 执行与控制(Do
// ══════════════════════════════════════════════════════════════
{ path: '/real-options', label: '实物期权计算器', icon: 'TrendCharts', roles: ['ceo', 'finance'], group: '🔵 P 规划与目标' },
// ── GROUP 2: 执行与控制(Do)──
{ path: '/cost', label: '成本分析', icon: 'Money', roles: ['ceo', 'finance', 'it'], group: '🟢 D 执行与控制' },
{ path: '/deviations', label: '差异分析', icon: 'DataAnalysis', roles: ['ceo', 'finance', 'business', 'it'], group: '🟢 D 执行与控制' },
// ── GROUP 3: 监控与评价(Check)──
{ path: '/dashboard', label: '经营看板', icon: 'DataBoard', roles: ['ceo', 'finance', 'business', 'it'], group: '🟡 C 监控与评价' },
{ path: '/reports', label: '管理报表', icon: 'DataAnalysis', roles: ['ceo', 'finance', 'business'], group: '🟡 C 监控与评价' },
{ path: '/dupont-analysis', label: '杜邦分析', icon: 'TrendCharts', roles: ['ceo', 'finance', 'it'], group: '🟡 C 监控与评价' },
{ path: '/customer', label: '客户维度', icon: 'User', roles: ['ceo', 'finance', 'business', 'it'], group: '🟡 C 监控与评价' },
{ path: '/learning-dashboard', label: '学习成长看板', icon: 'Reading', roles: ['ceo', 'finance', 'it'], group: '🟡 C 监控与评价' },
{ path: '/alerts', label: '预警中心', icon: 'WarningFilled', roles: ['ceo', 'finance', 'business', 'it'], group: '🟡 C 监控与评价' },
{ path: '/action-plans', label: '改善行动', icon: 'Edit', roles: ['ceo', 'finance', 'business', 'it'], group: '🔴 A 复盘与改进' },
// ══════════════════════════════════════════════════════════════
// GROUP 3: 监控与评价(Check
// ══════════════════════════════════════════════════════════════
{ path: '/data-quality', label: '数据质量', icon: 'WarningFilled', roles: ['ceo', 'finance', 'it'], group: '🔴 A 复盘与改进' },
// ══════════════════════════════════════════════════════════════
// GROUP 4: 复盘与改进(Act
// ══════════════════════════════════════════════════════════════
// ── GROUP 4: 复盘与改进(Act)──
{ path: '/action-plans', label: '改善行动', icon: 'Edit', roles: ['ceo', 'finance', 'business', 'it'], group: '🔴 A 复盘与改进' },
{ path: '/maps-review', label: '战略回顾会', icon: 'TrendCharts', roles: ['ceo', 'finance'], group: '🔴 A 复盘与改进' },
{ path: '/predict', label: '预测模拟', icon: 'DataLine', roles: ['ceo', 'finance', 'it'], group: '🔴 A 复盘与改进' },
{ path: '/mpm-calculator', label: 'MPM计算器', icon: 'Money', roles: ['ceo', 'finance', 'business'], group: '🔴 A 复盘与改进' },
{ path: '/data-quality', label: '数据质量', icon: 'WarningFilled', roles: ['ceo', 'finance', 'it'], group: '🔴 A 复盘与改进' },
// ══════════════════════════════════════════════════════════════
// GROUP 5: 系统与支持(Infra
// ══════════════════════════════════════════════════════════════
// ── GROUP 5: 基础数据与知识──
{ path: '/kpis', label: 'KPI字典', icon: 'Document', roles: ['ceo', 'finance', 'business', 'it'], group: '基础数据与知识' },
{ path: '/data', label: '数据管理', icon: 'Connection', roles: ['ceo', 'finance', 'it'], group: '基础数据与知识' },
// ── 规划与目标 ──
{ path: '/knowledge', label: 'CMA知识库', icon: 'Document', roles: ['ceo', 'finance', 'business', 'it'], group: '基础数据与知识' },
{ path: '/okr-templates', label: 'OKR模板库', icon: 'Collection', roles: ['ceo', 'finance', 'it'], group: '基础数据与知识' },
// ── GROUP 6: 系统管理──
{ path: '/org', label: '组织管理', icon: 'Collection', roles: ['ceo', 'it'], group: '系统管理' },
{ path: '/users', label: '用户管理', icon: 'User', roles: ['ceo', 'it'], group: '系统管理' },
{ path: '/notifications', label: '通知配置', icon: 'Bell', roles: ['ceo', 'it'], group: '系统管理' },
@@ -82,101 +63,12 @@ export const ROLE_LABELS: Record<string, string> = {
it: 'IT部',
}
/**
* 检查用户是否有权访问某路由
*/
export function hasRouteAccess(role: string, path: string): boolean {
const allowed = ROLE_ROUTES[role]
if (!allowed) return false
// 精确匹配或前缀匹配(如 /kpis/123 匹配 /kpis
return allowed.some(r => path === r || path.startsWith(r + '/'))
}
/**
* 检查用户是否有指定操作权限
*/
export function hasAction(role: string, action: string): boolean {
const actions = ROLE_ACTIONS[role]
return actions ? actions.includes(action) : false
}
]
// 角色名称映射
export const ROLE_LABELS: Record<string, string> = {
ceo: '总经理',
finance: '财务部',
business: '业务部',
it: 'IT部',
}
/**
* 检查用户是否有权访问某路由
*/
export function hasRouteAccess(role: string, path: string): boolean {
const allowed = ROLE_ROUTES[role]
if (!allowed) return false
// 精确匹配或前缀匹配(如 /kpis/123 匹配 /kpis
return allowed.some(r => path === r || path.startsWith(r + '/'))
}
/**
* 检查用户是否有指定操作权限
*/
export function hasAction(role: string, action: string): boolean {
const actions = ROLE_ACTIONS[role]
return actions ? actions.includes(action) : false
}
]
// 角色名称映射
export const ROLE_LABELS: Record<string, string> = {
ceo: '总经理',
finance: '财务部',
business: '业务部',
it: 'IT部',
}
/**
* 检查用户是否有权访问某路由
*/
export function hasRouteAccess(role: string, path: string): boolean {
const allowed = ROLE_ROUTES[role]
if (!allowed) return false
// 精确匹配或前缀匹配(如 /kpis/123 匹配 /kpis
return allowed.some(r => path === r || path.startsWith(r + '/'))
}
/**
* 检查用户是否有指定操作权限
*/
export function hasAction(role: string, action: string): boolean {
const actions = ROLE_ACTIONS[role]
return actions ? actions.includes(action) : false
}
]
// 角色名称映射
export const ROLE_LABELS: Record<string, string> = {
ceo: '总经理',
finance: '财务部',
business: '业务部',
it: 'IT部',
}
/**
* 检查用户是否有权访问某路由
*/
export function hasRouteAccess(role: string, path: string): boolean {
const allowed = ROLE_ROUTES[role]
if (!allowed) return false
// 精确匹配或前缀匹配(如 /kpis/123 匹配 /kpis
return allowed.some(r => path === r || path.startsWith(r + '/'))
}
/**
* 检查用户是否有指定操作权限
*/
export function hasAction(role: string, action: string): boolean {
const actions = ROLE_ACTIONS[role]
return actions ? actions.includes(action) : false