87 lines
3.7 KiB
Markdown
87 lines
3.7 KiB
Markdown
# 03 账号与权限页面
|
|
|
|
## 模块职责
|
|
|
|
覆盖首批账号与权限页面:用户管理、菜单管理、数据权限分组。负责列表、筛选、分页、编辑/新增入口、菜单树展示和分组管理入口,但权限粒度仍只到页面菜单。
|
|
|
|
## 依赖关系
|
|
|
|
上游:`02-session-menu-permission.md` 的用户和菜单状态;Java `AdminUserController`、`PermissionMenuController`、分组相关管理接口。
|
|
|
|
下游:`AdminLayout` 路由;后续业务页面使用用户选择器、分组数据。
|
|
|
|
旧页面来源:
|
|
|
|
- `admin.html#panel-users`
|
|
- `admin.html#panel-columns`
|
|
- `admin.html#panel-group-manage`
|
|
- `admin.js:loadUsers`、`bindUserActions`
|
|
- `admin.js:loadColumns`、`bindColumnActions`
|
|
- `admin.js:loadShopManageGroups`、`initShopManageGroupPanel`
|
|
|
|
## 核心接口:原实现 → 目标实现
|
|
|
|
| 功能 | 原实现 | 目标实现 |
|
|
|---|---|---|
|
|
| 用户列表 | Flask `list_users` / Java `AdminUserController.listUsers` | `UsersPage.vue` 调用 `GET /api/admin/users` |
|
|
| 新建用户 | `create_user` / `AdminUserController.createUser` | `UsersPage` 的 Element Plus Dialog + `POST /api/admin/user` |
|
|
| 编辑用户 | `update_user` / `AdminUserController.updateUser` | Dialog 表单 + `PUT /api/admin/user/{uid}` |
|
|
| 删除用户 | `delete_user` / `AdminUserController.deleteUser` | `ElMessageBox` 确认 + `DELETE /api/admin/user/{uid}` |
|
|
| 菜单列表 | `admin.js:loadColumns` | `MenusPage.vue` + `GET /api/admin/permission-menus?menuType=admin` |
|
|
| 菜单新增/编辑/删除 | Flask/Java 菜单 CRUD | Element Plus Dialog/Tree + 对应 `permission-menus` API |
|
|
| 菜单排序 | `bindColumnDragSort`、`persistColumnOrder` | 菜单树同级排序组件 + `POST /api/admin/column/reorder` |
|
|
| 用户菜单授权 | 旧用户编辑中的权限树 | 用户编辑时调用 `GET/PUT /api/admin/permission-users/{uid}/column-permissions` |
|
|
| 分组列表 | `loadShopManageGroups` | `GroupsPage.vue` + `/api/admin/shop-manage-groups` |
|
|
|
|
## 内部结构
|
|
|
|
```text
|
|
AccountPageGroup
|
|
├── UsersPage
|
|
│ ├── UserFilterBar
|
|
│ ├── UserTable
|
|
│ ├── UserEditorDialog
|
|
│ └── UserPermissionTree
|
|
├── MenusPage
|
|
│ ├── MenuTreeTable
|
|
│ ├── MenuEditorDialog
|
|
│ └── SameLevelSortInteraction
|
|
└── GroupsPage
|
|
├── GroupFilter/summary
|
|
├── GroupTable
|
|
└── GroupEditorDialog
|
|
```
|
|
|
|
页面级状态必须局部化:
|
|
|
|
- 当前页数据。
|
|
- 筛选条件。
|
|
- 分页。
|
|
- Dialog/Drawer 可见状态。
|
|
- 表单草稿。
|
|
- 保存中的 loading。
|
|
|
|
Pinia 不保存这些业务表格状态。
|
|
|
|
## 类型映射
|
|
|
|
| 原字段/概念 | 目标类型 |
|
|
|---|---|
|
|
| `userListBody` | `AdminUser[]` |
|
|
| `userPagination` | `PaginationState` |
|
|
| `columnTree` | `AdminMenuNode[]` / `PermissionMenuItem[]` |
|
|
| `column_id` | `number` |
|
|
| `created_by_id` | `number | null` |
|
|
| `role` | 联合字面量或后端枚举映射 |
|
|
| `grant_menu_routes` | `number[]` 的菜单 ID 授权请求 |
|
|
|
|
## 迁移/实现注意事项
|
|
|
|
1. 用户接口分页字段要按 Java 实际 VO 归一化,不能直接假设 Flask 字段命名。
|
|
2. 删除、创建、编辑继续保留后端权限校验;前端不添加按钮级权限体系。
|
|
3. 菜单管理必须区分 admin 菜单和 app 菜单,默认只操作 `menuType=admin`。
|
|
4. 菜单分组节点不应被当作可进入页面;叶子页面才产生 Router route。
|
|
5. 用户授权更新必须提交菜单 ID,而不是前端路由字符串,除非后端 API 明确支持 route。
|
|
6. 菜单迁移后 `column_key` 保持稳定,页面 URL 通过 `route_path` 变化。
|
|
7. 数据权限分组的业务 API 若仍以旧字段返回,必须在 `api/groups.ts` 适配为稳定的前端 DTO,禁止把兼容逻辑散落在表格模板中。
|