127 lines
5.9 KiB
Markdown
127 lines
5.9 KiB
Markdown
# menu-management 重构任务
|
||
|
||
## 任务目标
|
||
|
||
重构 `fms-vue/src/views/module/menu-management/index.vue`,在不改变现有功能和交互行为的前提下,降低入口文件复杂度,建立清晰的页面编排层和业务面板边界。
|
||
|
||
当前入口文件约 2,000 行,同时包含菜单树、菜单表单、权限点、权限库、多语言、保存流程、确认弹窗和页面样式。重构后入口组件应主要负责页面编排和跨区域业务流程。
|
||
|
||
## 目标目录结构
|
||
|
||
优先采用以下结构,面板组件直接放在 `menu-management` 根目录,和 `index.vue` 同级:
|
||
|
||
```text
|
||
src/views/module/menu-management/
|
||
├── index.vue
|
||
├── MenuTreePanel.vue
|
||
├── MenuBasicPanel.vue
|
||
├── MenuPowersPanel.vue
|
||
└── utils.js
|
||
```
|
||
|
||
只有当某个面板内部确实出现多个独立子组件时,才增加更深层目录,例如:
|
||
|
||
```text
|
||
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 或已有公共事件名称。
|
||
|
||
## 重构约束
|
||
|
||
1. 先完整阅读现有 `index.vue`、相关测试、`utils/tree`、`utils/dataChanges` 和被使用的公共组件,再开始修改。
|
||
2. 保留现有功能:菜单树加载/刷新/搜索/拖拽/右键操作,菜单新增/删除,菜单类型联动,未保存切换确认,多语言编辑,权限点维护,权限库导入,保存 diff 和保存后重载。
|
||
3. 父子组件通信优先使用 `v-model` 和语义明确的事件,不写 `onMenuUpdate(section, data)` 这类按 section 中转的通用回调。
|
||
4. 不复制状态源,不在子面板中重复请求同一份菜单数据,不把保存主流程拆散到多个组件。
|
||
5. 移动模板和样式时同步移动对应 CSS,避免保留失效样式;页面布局样式可以继续放在 `index.vue`。
|
||
6. 注意当前工作区可能存在其他未提交改动;不得回滚、覆盖或顺手清理与本任务无关的改动。
|
||
7. 删除或移动代码后,全局搜索旧导入、旧组件路径、旧方法名和旧事件名,确认没有残留。
|
||
8. 不要求一次性重命名整个项目;只处理本次重构涉及的引用。
|
||
|
||
## 验收标准
|
||
|
||
- `index.vue` 只保留页面编排、核心状态、加载保存流程和跨面板联动;
|
||
- `MenuTreePanel.vue`、`MenuBasicPanel.vue`、`MenuPowersPanel.vue` 均有清晰单一职责;
|
||
- 页面视觉和交互行为与重构前一致;
|
||
- 菜单新增、编辑、删除、拖拽、刷新、切换未保存确认、多语言编辑、权限新增/删除/导入、保存和重载均可正常工作;
|
||
- 没有 `maintableorg` 等单词拼接命名,没有新增无意义的兼容转发层;
|
||
- 至少运行受影响的单元测试;条件允许时运行:
|
||
|
||
```powershell
|
||
cd fms-vue
|
||
pnpm test -- tests/views/menu-unsaved-node-switch.spec.js
|
||
pnpm lint
|
||
pnpm build
|
||
```
|
||
|
||
- 若测试、lint 或构建被重构前已有的问题阻断,明确记录原因,不修改无关代码来掩盖问题。
|