docs: 补充规格文档(specs 01-15)

This commit is contained in:
2026-09-08 13:39:10 +08:00
parent 4ac8f8b472
commit b12acf7793
16 changed files with 1462 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
# 08 Java 菜单树与 Flyway 权限迁移
## 模块职责
将 Java 权限模型作为后台菜单唯一来源,继续使用 `columns``user_column_permission`,把现有扁平有效菜单转换为后端维护的树形菜单,并通过 Flyway 把旧 route_path 迁移到新版 History 路由。
本模块不引入按钮级权限,不新增 action 表。
## 依赖关系
上游:现有数据库 `columns``user_column_permission``users``PermissionMenuService`
下游:`AdminConsoleController.currentUserMenus`、Vue `fetchAdminMenuTree``MenusPage`
相关文件和符号:
- `backend-java/.../permission/service/PermissionMenuService.java:getUserColumnPermissions`
- `backend-java/.../permission/controller/PermissionMenuController.java:listMenus/createMenu/updateMenu/deleteMenu/reorderColumns`
- `backend-java/.../permission/model/entity/PermissionMenuEntity.java`
- `backend-java/.../permission/model/entity/UserColumnPermissionEntity.java`
- `backend-java/.../admin/controller/AdminConsoleController.java:currentUserMenus`
- `backend-java/src/main/resources/db/V100__admin_menu_frontend_routes.sql`(目标迁移文件)
## 核心接口:原实现 → 目标实现
| 内容 | 原实现 | 目标实现 |
|---|---|---|
| 当前用户菜单 | `List<PermissionMenuItemVo>` 扁平列表 | 树形 `items`,页面节点含 `key/name/route` |
| 有效权限展开 | `PermissionMenuService.getUserColumnPermissions` | 保留,作为树输入;不在 Controller 重新实现授权规则 |
| 菜单存储 | `columns.column_key` + `route_path` | `column_key` 保持稳定;`route_path` 改为 Vue path |
| 用户授权 | `user_column_permission` | 保持不变 |
| 菜单迁移 | 运行时 initializer 的默认菜单补齐 | Flyway 正式更新既有 admin route_path |
| 权限菜单 CRUD | 旧 API 字段 | API 路径保持;页面使用树/表格适配器 |
## 内部结构\n\n`PermissionMenuService` 负责有效权限集合,`AdminConsoleController` 负责 DTO 树组装,Flyway 负责 route_path 数据迁移,`PermissionMenuController` 负责菜单管理 CRUD。\n\n## 目标树组装规则
1. 先由 `PermissionMenuService` 得到当前用户有效菜单集合。
2.`id` 建立节点索引。
3.`parent_id` 将子节点挂到父节点。
4.`sort_order`、再按稳定 key 排序。
5. 分组节点可以无 route;页面节点带 route。
6. 只返回当前用户有效节点,禁止返回全量菜单后由前端过滤。
## 类型映射
| 数据库/旧 DTO | 目标菜单 DTO |
|---|---|
| `column_key` | `key` |
| `name` | `name` |
| `route_path` | `route` |
| `parent_id` | `children` 关系 |
| `sort_order` | 后端排序值 |
| `menu_type=admin` | 后台菜单域 |
## Flyway 迁移内容
目标迁移按 `column_key` 更新 `route_path`,示例:
- `admin_users``account/users`
- `admin_columns``account/menus`
- `admin_group_manage``account/groups`
- `admin_dedupe_total_data``asin-center/registry`
- `admin_shop_manage``shop-center/shops`
- `admin_history``records/history`
- `admin_version``records/software-version`
迁移必须:
- 可重复执行或由 Flyway 保证版本只执行一次。
- 不删除 `user_column_permission`
- 不修改既有 `column_key`,避免 Java 业务鉴权常量失效。
- 迁移前后对比每个用户的有效菜单 key 集合。
- 检查 `(menu_type, route_path)` 唯一约束。
## 迁移/实现注意事项
1. `PermissionMenuSchemaInitializer` 仍可负责缺失基础表/默认数据兜底,但不能取代一次性数据迁移。
2. Controller 不得根据当前请求头、User-Agent 或查询参数返回不同菜单结构。
3. 树构造不能把同一个节点挂到多个父节点;发现脏数据应记录错误并阻止上线。
4. 菜单分组虚拟 route 不能被当作页面路由。
5. 新版前端不再兼容旧 route/hash,但权限 key 保持稳定,这两件事必须区分。
6. 菜单 CRUD 新增页面时必须同时提供稳定 `column_key` 和 Vue `route_path`