import type { Component } from 'vue'; import { markRaw, shallowRef } from 'vue'; export type WorkbenchModuleKey = // 保留:现有 key 沿用(避免影响线上用户布局存储) | 'myTodo' // A1 · 我的待办 | 'myProject' // B7 · 我参与的项目 | 'shortcut' // E19 · 快捷入口 | 'projectHealth' // C15 · 产品 / 项目健康度 // 新增(蓝图 2026-05-22,原 A3 myTicket、A4 mentions、A5 approval、A6 worklogReminder、B10 personalItem、F23 projectSnapshot、C11 teamTodo、E21 favorite 已废弃,F23 已并入 B7 myProject "我负责的" tab) | 'myExecution' // B8 · 我负责的执行 | 'productSnapshot' // F24 · 产品深度快照(对象快照 / 当前对象切换) | 'teamLoad' // C13 · 团队负载(管理者) | 'myWeekWorklog' // D16 · 工时(含「我的工时 / 团队工时」两 tab,原 C12 teamWorklog 已并入) | 'noticeNotification'; // E22 · 公告 + 通知摘要 // 扩展:action(动作型 widget)、snapshot(对象快照型 widget,需指定一个对象) export type WorkbenchModuleCategory = 'personal' | 'manager' | 'tool' | 'action' | 'snapshot'; export type WorkbenchColumnId = 'left' | 'right'; export interface WorkbenchModuleMeta { key: WorkbenchModuleKey; component: Component; displayName: string; icon: string; category: WorkbenchModuleCategory; defaultVisible: boolean; defaultColumn: WorkbenchColumnId; defaultOrder: number; } const placeholder = markRaw({ render: () => null }); // 默认布局(2026-05-27 调整,对应 WORKBENCH_LAYOUT_VERSION=3): // left: myTodo(1) → myExecution(2) // right: shortcut(1) → myProject(2) → myWeekWorklog(3) → teamLoad(4) // hidden: projectHealth, noticeNotification, productSnapshot // (noticeNotification 隐藏原因:公告搬到 banner、通知归全局头部铃铛) const registry: WorkbenchModuleMeta[] = [ { key: 'myTodo', component: placeholder, displayName: '我的待办', icon: 'mdi:clipboard-text-clock-outline', category: 'personal', defaultVisible: true, defaultColumn: 'left', defaultOrder: 1 }, { key: 'myExecution', component: placeholder, displayName: '我负责的执行', icon: 'mdi:flag-checkered', category: 'personal', defaultVisible: true, defaultColumn: 'left', defaultOrder: 2 }, { key: 'shortcut', component: placeholder, displayName: '快捷入口', icon: 'mdi:rocket-launch-outline', category: 'tool', defaultVisible: true, defaultColumn: 'right', defaultOrder: 1 }, { key: 'myProject', component: placeholder, displayName: '我的项目', icon: 'mdi:briefcase-outline', category: 'personal', defaultVisible: true, defaultColumn: 'right', defaultOrder: 2 }, { key: 'myWeekWorklog', component: placeholder, displayName: '工时', icon: 'mdi:timer-outline', category: 'personal', defaultVisible: true, defaultColumn: 'right', defaultOrder: 3 }, { key: 'teamLoad', component: placeholder, displayName: '团队负载', icon: 'mdi:scale-balance', category: 'manager', defaultVisible: true, defaultColumn: 'right', defaultOrder: 4 }, // === 默认隐藏(用户可从 widget 库拖回) === { key: 'projectHealth', component: placeholder, displayName: '产品 / 项目健康度', icon: 'mdi:heart-pulse', category: 'manager', defaultVisible: false, defaultColumn: 'right', defaultOrder: 10 }, { key: 'noticeNotification', component: placeholder, displayName: '公告 + 通知', icon: 'mdi:bullhorn-outline', category: 'tool', defaultVisible: false, defaultColumn: 'right', defaultOrder: 11 }, { key: 'productSnapshot', component: placeholder, displayName: '产品深度快照', icon: 'mdi:image-area-close', category: 'snapshot', defaultVisible: false, defaultColumn: 'left', defaultOrder: 41 } ]; const registryRef = shallowRef(registry); export function useWorkbenchModules() { function getAllModules() { return registryRef.value; } function getModuleMeta(key: WorkbenchModuleKey) { return registryRef.value.find(m => m.key === key); } function registerModuleComponent(key: WorkbenchModuleKey, component: Component) { const target = registryRef.value.find(m => m.key === key); if (target) target.component = markRaw(component); } return { getAllModules, getModuleMeta, registerModuleComponent }; }