fix: 菜单按1-6顺序重排(P→D→C→A→基础→系统)
This commit is contained in:
Vendored
-51
@@ -14,54 +14,6 @@ declare module 'vue' {
|
|||||||
BulletChart: typeof import('./src/components/charts/BulletChart.vue')['default']
|
BulletChart: typeof import('./src/components/charts/BulletChart.vue')['default']
|
||||||
ConnectionLines: typeof import('./src/components/strategy/ConnectionLines.vue')['default']
|
ConnectionLines: typeof import('./src/components/strategy/ConnectionLines.vue')['default']
|
||||||
DriverFactorBudget: typeof import('./src/components/DriverFactorBudget.vue')['default']
|
DriverFactorBudget: typeof import('./src/components/DriverFactorBudget.vue')['default']
|
||||||
ElAlert: typeof import('element-plus/es')['ElAlert']
|
|
||||||
ElAside: typeof import('element-plus/es')['ElAside']
|
|
||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
|
||||||
ElCard: typeof import('element-plus/es')['ElCard']
|
|
||||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
|
||||||
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
|
||||||
ElCol: typeof import('element-plus/es')['ElCol']
|
|
||||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
|
||||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
|
||||||
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
|
|
||||||
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
|
|
||||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
|
||||||
ElDivider: typeof import('element-plus/es')['ElDivider']
|
|
||||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
|
||||||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
|
||||||
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
|
|
||||||
ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
|
||||||
ElForm: typeof import('element-plus/es')['ElForm']
|
|
||||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
|
||||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
|
||||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
|
||||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
|
||||||
ElMain: typeof import('element-plus/es')['ElMain']
|
|
||||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
|
||||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
|
||||||
ElOption: typeof import('element-plus/es')['ElOption']
|
|
||||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
|
||||||
ElProgress: typeof import('element-plus/es')['ElProgress']
|
|
||||||
ElRadio: typeof import('element-plus/es')['ElRadio']
|
|
||||||
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
|
|
||||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
|
||||||
ElRow: typeof import('element-plus/es')['ElRow']
|
|
||||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
|
||||||
ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
|
|
||||||
ElSlider: typeof import('element-plus/es')['ElSlider']
|
|
||||||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
|
|
||||||
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
|
||||||
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']
|
|
||||||
ElTimeline: typeof import('element-plus/es')['ElTimeline']
|
|
||||||
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
|
|
||||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
|
||||||
ElTree: typeof import('element-plus/es')['ElTree']
|
|
||||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
|
||||||
GaugeChart: typeof import('./src/components/charts/GaugeChart.vue')['default']
|
GaugeChart: typeof import('./src/components/charts/GaugeChart.vue')['default']
|
||||||
GrowthQuality: typeof import('./src/components/GrowthQuality.vue')['default']
|
GrowthQuality: typeof import('./src/components/GrowthQuality.vue')['default']
|
||||||
KnowledgePanel: typeof import('./src/components/KnowledgePanel.vue')['default']
|
KnowledgePanel: typeof import('./src/components/KnowledgePanel.vue')['default']
|
||||||
@@ -79,7 +31,4 @@ declare module 'vue' {
|
|||||||
WaterfallChart: typeof import('./src/components/charts/WaterfallChart.vue')['default']
|
WaterfallChart: typeof import('./src/components/charts/WaterfallChart.vue')['default']
|
||||||
WelcomeGuide: typeof import('./src/components/WelcomeGuide.vue')['default']
|
WelcomeGuide: typeof import('./src/components/WelcomeGuide.vue')['default']
|
||||||
}
|
}
|
||||||
export interface GlobalDirectives {
|
|
||||||
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+92
-11
@@ -29,11 +29,6 @@ export interface MenuItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const MENU_ITEMS: MenuItem[] = [
|
export const MENU_ITEMS: MenuItem[] = [
|
||||||
// ── 基础数据 ──
|
|
||||||
{ path: '/kpis', label: 'KPI字典', icon: 'Document', roles: ['ceo', 'finance', 'business', 'it'], group: '基础数据与知识' },
|
|
||||||
{ path: '/data', label: '数据管理', icon: 'Connection', roles: ['ceo', 'finance', 'it'], group: '基础数据与知识' },
|
|
||||||
|
|
||||||
// ── 规划与目标 ──
|
|
||||||
{ path: '/my-dashboard', label: '我的工作台', icon: 'Monitor', roles: ['ceo', 'finance', 'business', 'it'], group: '🔵 P 规划与目标' },
|
{ path: '/my-dashboard', label: '我的工作台', icon: 'Monitor', roles: ['ceo', 'finance', 'business', 'it'], group: '🔵 P 规划与目标' },
|
||||||
{ path: '/maps', label: '战略地图', icon: 'DataBoard', roles: ['ceo', 'finance'], 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: '/budget', label: '预算管理', icon: 'Coin', roles: ['ceo', 'finance', 'business', 'it'], group: '🔵 P 规划与目标' },
|
||||||
@@ -42,31 +37,35 @@ export const MENU_ITEMS: MenuItem[] = [
|
|||||||
// ══════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════
|
||||||
// GROUP 2: 执行与控制(Do)
|
// GROUP 2: 执行与控制(Do)
|
||||||
// ══════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════
|
||||||
|
{ path: '/real-options', label: '实物期权计算器', icon: 'TrendCharts', roles: ['ceo', 'finance'], group: '🔵 P 规划与目标' },
|
||||||
{ path: '/cost', label: '成本分析', icon: 'Money', roles: ['ceo', 'finance', 'it'], group: '🟢 D 执行与控制' },
|
{ path: '/cost', label: '成本分析', icon: 'Money', roles: ['ceo', 'finance', 'it'], group: '🟢 D 执行与控制' },
|
||||||
{ path: '/deviations', label: '差异分析', icon: 'DataAnalysis', roles: ['ceo', 'finance', 'business', 'it'], group: '🟢 D 执行与控制' },
|
{ path: '/deviations', label: '差异分析', icon: 'DataAnalysis', roles: ['ceo', 'finance', 'business', 'it'], group: '🟢 D 执行与控制' },
|
||||||
{ path: '/action-plans', label: '改善行动', icon: 'Edit', roles: ['ceo', 'finance', 'business', 'it'], group: '🔴 A 复盘与改进' },
|
|
||||||
|
|
||||||
// ══════════════════════════════════════════════════════════════
|
|
||||||
// GROUP 3: 监控与评价(Check)
|
|
||||||
// ══════════════════════════════════════════════════════════════
|
|
||||||
{ path: '/dashboard', label: '经营看板', icon: 'DataBoard', roles: ['ceo', 'finance', 'business', 'it'], group: '🟡 C 监控与评价' },
|
{ path: '/dashboard', label: '经营看板', icon: 'DataBoard', roles: ['ceo', 'finance', 'business', 'it'], group: '🟡 C 监控与评价' },
|
||||||
{ path: '/reports', label: '管理报表', icon: 'DataAnalysis', roles: ['ceo', 'finance', 'business'], 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: '/dupont-analysis', label: '杜邦分析', icon: 'TrendCharts', roles: ['ceo', 'finance', 'it'], group: '🟡 C 监控与评价' },
|
||||||
{ path: '/customer', label: '客户维度', icon: 'User', roles: ['ceo', 'finance', 'business', '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: '/learning-dashboard', label: '学习成长看板', icon: 'Reading', roles: ['ceo', 'finance', 'it'], group: '🟡 C 监控与评价' },
|
||||||
{ path: '/alerts', label: '预警中心', icon: 'WarningFilled', roles: ['ceo', 'finance', 'business', '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 复盘与改进' },
|
{ path: '/data-quality', label: '数据质量', icon: 'WarningFilled', roles: ['ceo', 'finance', 'it'], group: '🔴 A 复盘与改进' },
|
||||||
// ══════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════
|
||||||
// GROUP 4: 复盘与改进(Act)
|
// GROUP 4: 复盘与改进(Act)
|
||||||
// ══════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════
|
||||||
{ path: '/maps-review', label: '战略回顾会', icon: 'TrendCharts', roles: ['ceo', 'finance'], 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: '/predict', label: '预测模拟', icon: 'DataLine', roles: ['ceo', 'finance', 'it'], group: '🔴 A 复盘与改进' },
|
||||||
{ path: '/real-options', label: '实物期权计算器', icon: 'TrendCharts', roles: ['ceo', 'finance'], group: '🔵 P 规划与目标' },
|
|
||||||
{ path: '/mpm-calculator', label: 'MPM计算器', icon: 'Money', roles: ['ceo', 'finance', 'business'], group: '🔴 A 复盘与改进' },
|
{ path: '/mpm-calculator', label: 'MPM计算器', icon: 'Money', roles: ['ceo', 'finance', 'business'], group: '🔴 A 复盘与改进' },
|
||||||
|
|
||||||
// ══════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════
|
||||||
// GROUP 5: 系统与支持(Infra)
|
// GROUP 5: 系统与支持(Infra)
|
||||||
// ══════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════
|
||||||
|
{ 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: '/knowledge', label: 'CMA知识库', icon: 'Document', roles: ['ceo', 'finance', 'business', 'it'], group: '基础数据与知识' },
|
||||||
{ path: '/okr-templates', label: 'OKR模板库', icon: 'Collection', roles: ['ceo', 'finance', 'it'], group: '基础数据与知识' },
|
{ path: '/okr-templates', label: 'OKR模板库', icon: 'Collection', roles: ['ceo', 'finance', 'it'], group: '基础数据与知识' },
|
||||||
{ path: '/org', label: '组织管理', icon: 'Collection', roles: ['ceo', 'it'], group: '系统管理' },
|
{ path: '/org', label: '组织管理', icon: 'Collection', roles: ['ceo', 'it'], group: '系统管理' },
|
||||||
@@ -100,3 +99,85 @@ export function hasAction(role: string, action: string): boolean {
|
|||||||
const actions = ROLE_ACTIONS[role]
|
const actions = ROLE_ACTIONS[role]
|
||||||
return actions ? actions.includes(action) : false
|
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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user