5.9 KiB
5.9 KiB
menu-management 重构任务
任务目标
重构 fms-vue/src/views/module/menu-management/index.vue,在不改变现有功能和交互行为的前提下,降低入口文件复杂度,建立清晰的页面编排层和业务面板边界。
当前入口文件约 2,000 行,同时包含菜单树、菜单表单、权限点、权限库、多语言、保存流程、确认弹窗和页面样式。重构后入口组件应主要负责页面编排和跨区域业务流程。
目标目录结构
优先采用以下结构,面板组件直接放在 menu-management 根目录,和 index.vue 同级:
src/views/module/menu-management/
├── index.vue
├── MenuTreePanel.vue
├── MenuBasicPanel.vue
├── MenuPowersPanel.vue
└── utils.js
只有当某个面板内部确实出现多个独立子组件时,才增加更深层目录,例如:
components/powers/PowerTable.vue
components/powers/PowerLibrary.vue
不要为了目录整齐而预先创建大量空组件或 composable。
职责边界
index.vue 编排层
保留以下职责:
- 持有核心业务数据和基线:
maindata、maindata_org、i18n_values、i18n_values_org、i18n_org、powers、powers_org; - 菜单树和菜单配置的加载入口;
handleSave → beforeSave → buildSaveData → 保存 → afterSave主流程;- 未保存切换确认、刷新确认和统一确认弹窗;
- 跨区域联动,例如菜单类型影响权限面板、菜单编码影响多语言键;
- 将数据和业务回调传给子面板。
不要把同一份数据同时复制到父子组件,也不要让子面板自行加载或保存同一份菜单配置。
MenuTreePanel.vue
负责:
- 菜单搜索框和树展示;
- 展开、选中、拖拽、右键菜单的 UI 交互;
- 菜单节点启用/停用的操作入口;
- 通过事件通知父级新增、删除、移动、刷新和选择。
树数据加载、保存以及涉及其他区域的业务处理仍由 index.vue 决定。可将搜索关键字、展开键等纯 UI 状态放在本组件;如果父级需要控制它们,则使用 v-model。
MenuBasicPanel.vue
负责:
- 菜单名称、编码、类型、路由、绑定模块、图标、排序号等表单字段;
- 表单展示和字段级交互;
- 多语言名称编辑入口;
- 通过
v-model直接读写maindata,通过事件通知类型变化或需要打开多语言弹窗。
保存校验和最终请求数据构建仍由父级统一处理,除非是纯字段级校验。
MenuPowersPanel.vue
负责:
- 当前菜单权限点表格;
- 权限点新增、删除和编辑;
- 权限来源库加载和导入;
- 权限相关的表格选择状态和加载状态。
通过 v-model 读写 powers。如果权限库和当前权限点的实现确实需要独立复用,再继续拆分 components/powers/,否则保持在一个面板中。
utils.js
只放纯函数或无 Vue 状态依赖的逻辑,例如:
- 树节点位置计算;
- 兄弟节点排序号重排;
- 目录节点非叶子标记;
- 可独立测试的菜单数据转换。
只有一个简单调用点且放在入口中更易读的逻辑,不要为了拆文件强行抽取。
命名要求
- 页面状态、局部变量、computed、方法使用
camelCase,例如menuTreeLoading、selectedMenu、loadMenuConfig(); - 与后端表结构对应的业务数据使用
snake_case,例如maindata、maindata_org、i18n_values、i18n_values_org; - 数据和原始基线必须成对命名,使用
_org分隔;禁止maintableorg、subtablereceiveorg等单词直接拼接; - 方法使用明确动词,例如
loadMenuConfig()、handleSave()、buildSaveData(),不要使用loadMod()、dealData()等不明确名称; - 组件文件名和组件名使用 PascalCase;模板中的 props、事件和具名
v-model使用 kebab-case; - 不要因为重构而修改后端字段、接口字段、路由 meta、第三方组件 API 或已有公共事件名称。
重构约束
- 先完整阅读现有
index.vue、相关测试、utils/tree、utils/dataChanges和被使用的公共组件,再开始修改。 - 保留现有功能:菜单树加载/刷新/搜索/拖拽/右键操作,菜单新增/删除,菜单类型联动,未保存切换确认,多语言编辑,权限点维护,权限库导入,保存 diff 和保存后重载。
- 父子组件通信优先使用
v-model和语义明确的事件,不写onMenuUpdate(section, data)这类按 section 中转的通用回调。 - 不复制状态源,不在子面板中重复请求同一份菜单数据,不把保存主流程拆散到多个组件。
- 移动模板和样式时同步移动对应 CSS,避免保留失效样式;页面布局样式可以继续放在
index.vue。 - 注意当前工作区可能存在其他未提交改动;不得回滚、覆盖或顺手清理与本任务无关的改动。
- 删除或移动代码后,全局搜索旧导入、旧组件路径、旧方法名和旧事件名,确认没有残留。
- 不要求一次性重命名整个项目;只处理本次重构涉及的引用。
验收标准
index.vue只保留页面编排、核心状态、加载保存流程和跨面板联动;MenuTreePanel.vue、MenuBasicPanel.vue、MenuPowersPanel.vue均有清晰单一职责;- 页面视觉和交互行为与重构前一致;
- 菜单新增、编辑、删除、拖拽、刷新、切换未保存确认、多语言编辑、权限新增/删除/导入、保存和重载均可正常工作;
- 没有
maintableorg等单词拼接命名,没有新增无意义的兼容转发层; - 至少运行受影响的单元测试;条件允许时运行:
cd fms-vue
pnpm test -- tests/views/menu-unsaved-node-switch.spec.js
pnpm lint
pnpm build
- 若测试、lint 或构建被重构前已有的问题阻断,明确记录原因,不修改无关代码来掩盖问题。