Files
effekt-interface/.plan/YCGiVLWod2rghU8nT3fEv.md
2026-05-07 19:21:19 +08:00

857 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 角色/用户/菜单管理详细设计文档
## 1. 目标
基于当前项目已有的分层框架model / dao / service / controller / views新增以下能力
1. 角色管理
- 角色表
- 权限表
- 用户角色关联表
- 角色权限关联能力
2. 用户管理
- 用户表
- 用户与角色分配
3. 菜单管理
- 菜单表
- 角色分配菜单
本次仅输出详细设计,不直接改业务代码。
---
## 2. 当前项目框架观察
### 2.1 现有分层风格
当前项目采用如下结构:
- `app/api/model/*.py`
- `app/api/dao/*.py`
- `app/api/service/*.py`
- `app/api/controller/*.py`
- `app/api/views.py`
### 2.2 当前职责边界
#### model
- 定义 SQLAlchemy 表模型
- 每个领域通常独立一个 model 文件
#### dao
- 负责数据库增删改查
- 已有通用风格:
- `create`
- `update_by_id`
- `get_by_id`
- `list_by_filters`
- `delete_by_id`
#### service
- 作为 controller 与 dao 之间的业务入口
- 目前多数是对 dao 的薄封装
- 适合放跨表组合查询、业务校验、聚合逻辑
#### controller
- 负责参数获取、必填校验、字段映射、返回结构拼装
- 不应直接 `session.query(...)`
#### views
- Flask 路由层
- 负责 request 参数读取、ApiResponse 包装、session 生命周期控制
### 2.3 当前接口命名风格
已有接口风格:
- `/project/list`
- `/project/detail`
- `/project/create`
- `/project/update`
- `/project/delete`
- `/product/list`
- `/product/detail`
- `/product/create`
- `/product/update`
- `/product/delete`
建议新增模块保持一致:
- `/role/list`
- `/role/detail`
- `/role/create`
- `/role/update`
- `/role/delete`
- `/user/list`
- `/user/detail`
- `/user/create`
- `/user/update`
- `/user/delete`
- `/menu/tree`
- `/menu/create`
- `/menu/update`
- `/menu/delete`
- `/role/permission/*`
- `/role/menu/*`
- `/user/role/*`
---
## 3. 总体设计原则
1. 严格按当前框架分层
2. controller 不直接查数据库
3. 跨表聚合通过 service + dao 实现
4. 保持与现有字段风格一致:
- 主键 `id`
- 软删字段 `is_delete`
- 时间字段 `created_time` / `updated_time`
5. 优先支持后台管理能力,不先引入复杂 RBAC 继承体系
6. 菜单、权限、角色、用户四个域解耦,但通过关联表关联
---
## 4. 业务对象与关系
### 4.1 核心对象
1. 用户 `user`
2. 角色 `role`
3. 权限 `permission`
4. 菜单 `menu`
### 4.2 关联对象
1. 用户角色关联 `user_role`
2. 角色权限关联 `role_permission`
3. 角色菜单关联 `role_menu`
### 4.3 关系说明
- 用户 : 角色 = 多对多
- 角色 : 权限 = 多对多
- 角色 : 菜单 = 多对多
- 菜单自身 = 树形父子关系
### 4.4 推荐鉴权思路
后续登录后:
- 用户拥有多个角色
- 角色聚合出权限集合
- 角色聚合出菜单集合
- 前端基于菜单渲染导航
- 后端基于权限点做接口校验
---
## 5. 数据库表结构设计
以下采用 PostgreSQL 风格,保持与现有模型一致。
---
## 5.1 用户表 `user`
### 用途
存储后台系统用户基础信息。
### 建表字段
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGSERIAL | PK | 主键 |
| username | VARCHAR(64) | UNIQUE NOT NULL | 登录用户名 |
| real_name | VARCHAR(64) | | 真实姓名 |
| password_hash | VARCHAR(255) | NOT NULL | 密码哈希 |
| mobile | VARCHAR(32) | | 手机号 |
| email | VARCHAR(128) | | 邮箱 |
| avatar | VARCHAR(255) | | 头像地址 |
| status | SMALLINT | DEFAULT 1 | 1启用 0禁用 |
| last_login_time | TIMESTAMP | | 最后登录时间 |
| created_by | BIGINT | | 创建人 |
| is_delete | INTEGER | DEFAULT 0 | 软删标识 |
| created_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
| updated_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 更新时间 |
### 索引建议
- unique(username)
- index(status)
- index(is_delete)
---
## 5.2 角色表 `role`
### 用途
定义系统角色。
### 建表字段
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGSERIAL | PK | 主键 |
| code | VARCHAR(64) | UNIQUE NOT NULL | 角色编码,如 admin/test_manager |
| name | VARCHAR(64) | NOT NULL | 角色名称 |
| description | TEXT | | 角色描述 |
| status | SMALLINT | DEFAULT 1 | 1启用 0禁用 |
| is_system | SMALLINT | DEFAULT 0 | 是否系统内置角色 |
| created_by | BIGINT | | 创建人 |
| is_delete | INTEGER | DEFAULT 0 | 软删标识 |
| created_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
| updated_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 更新时间 |
### 索引建议
- unique(code)
- index(status)
- index(is_delete)
---
## 5.3 权限表 `permission`
### 用途
定义后端权限点。
### 建表字段
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGSERIAL | PK | 主键 |
| code | VARCHAR(128) | UNIQUE NOT NULL | 权限编码,如 project:create |
| name | VARCHAR(128) | NOT NULL | 权限名称 |
| module | VARCHAR(64) | | 所属模块,如 project/user/menu |
| action | VARCHAR(64) | | 动作,如 list/create/update/delete |
| description | TEXT | | 描述 |
| status | SMALLINT | DEFAULT 1 | 1启用 0禁用 |
| is_delete | INTEGER | DEFAULT 0 | 软删标识 |
| created_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
| updated_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 更新时间 |
### 索引建议
- unique(code)
- index(module)
- index(status)
---
## 5.4 菜单表 `menu`
### 用途
定义前端菜单树。
### 建表字段
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGSERIAL | PK | 主键 |
| parent_id | BIGINT | DEFAULT 0 | 父菜单ID0表示根节点 |
| name | VARCHAR(64) | NOT NULL | 菜单名称 |
| code | VARCHAR(64) | UNIQUE | 菜单编码 |
| type | SMALLINT | DEFAULT 1 | 1目录 2菜单 3按钮 |
| path | VARCHAR(255) | | 路由路径 |
| component | VARCHAR(255) | | 前端组件路径 |
| icon | VARCHAR(64) | | 图标 |
| permission_code | VARCHAR(128) | | 对应权限编码,可选 |
| sort | INTEGER | DEFAULT 0 | 排序 |
| visible | SMALLINT | DEFAULT 1 | 1显示 0隐藏 |
| status | SMALLINT | DEFAULT 1 | 1启用 0禁用 |
| is_delete | INTEGER | DEFAULT 0 | 软删标识 |
| created_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
| updated_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 更新时间 |
### 索引建议
- index(parent_id)
- unique(code)
- index(sort)
---
## 5.5 用户角色关联表 `user_role`
### 用途
维护用户与角色多对多关系。
### 建表字段
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGSERIAL | PK | 主键 |
| user_id | BIGINT | NOT NULL | 用户ID |
| role_id | BIGINT | NOT NULL | 角色ID |
| is_delete | INTEGER | DEFAULT 0 | 软删标识 |
| created_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
### 约束建议
- unique(user_id, role_id)
- index(user_id)
- index(role_id)
---
## 5.6 角色权限关联表 `role_permission`
### 用途
维护角色与权限多对多关系。
### 建表字段
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGSERIAL | PK | 主键 |
| role_id | BIGINT | NOT NULL | 角色ID |
| permission_id | BIGINT | NOT NULL | 权限ID |
| is_delete | INTEGER | DEFAULT 0 | 软删标识 |
| created_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
### 约束建议
- unique(role_id, permission_id)
- index(role_id)
- index(permission_id)
---
## 5.7 角色菜单关联表 `role_menu`
### 用途
维护角色与菜单多对多关系。
### 建表字段
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGSERIAL | PK | 主键 |
| role_id | BIGINT | NOT NULL | 角色ID |
| menu_id | BIGINT | NOT NULL | 菜单ID |
| is_delete | INTEGER | DEFAULT 0 | 软删标识 |
| created_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
### 约束建议
- unique(role_id, menu_id)
- index(role_id)
- index(menu_id)
---
## 6. Model 设计
建议新增单独 model 文件:
### 6.1 `app/api/model/userModel.py`
包含:
- `User`
- `UserRole`
### 6.2 `app/api/model/rbacModel.py`
包含:
- `Role`
- `Permission`
- `RolePermission`
- `Menu`
- `RoleMenu`
> 也可以拆成 `roleModel.py` / `menuModel.py`,但按当前项目规模,两个文件足够。
### 6.3 Model 设计原则
- 继承与现有一致:`declarative_base()` + `to_dict`
- 字段命名与数据库列一致
- 关联关系不强制写 SQLAlchemy relationship保持当前项目风格简洁
---
## 7. DAO 设计
---
## 7.1 `app/api/dao/userDao.py`
### 基础方法
- `create(session, model_cls, add_info)`
- `update_by_id(session, model_cls, obj_id, update_info, soft_delete=True)`
- `get_by_id(session, model_cls, obj_id, soft_delete=True)`
- `list_by_filters(session, model_cls, filter_list, page=1, limit=20, order_column=None)`
- `delete_by_id(session, model_cls, obj_id)`
### 用户专项方法
- `get_user_role_ids(session, user_id)`
- `replace_user_roles(session, user_id, role_ids)`
- `get_user_roles(session, user_ids)`
---
## 7.2 `app/api/dao/rbacDao.py`
### 基础方法
同现有通用 DAO 风格。
### 角色/权限/菜单专项方法
- `get_role_permission_ids(session, role_id)`
- `replace_role_permissions(session, role_id, permission_ids)`
- `get_role_menu_ids(session, role_id)`
- `replace_role_menus(session, role_id, menu_ids)`
- `get_role_names_map(session, role_ids)`
- `get_menu_tree_items(session, filter_list)`
- `get_permission_list(session, filter_list, page, limit)`
---
## 8. Service 设计
---
## 8.1 `app/api/service/userService.py`
### 职责
- 用户基本 CRUD
- 用户与角色分配
- 聚合用户角色名称
### 方法建议
- `create(session, model_cls, add_info)`
- `update_by_id(session, model_cls, obj_id, update_info, soft_delete=True)`
- `get_by_id(session, model_cls, obj_id, soft_delete=True)`
- `list_by_filters(session, model_cls, filter_list, page_num=1, page_size=20, order_column=None)`
- `delete_by_id(session, model_cls, obj_id)`
- `assign_roles(session, user_id, role_ids)`
- `get_user_role_ids(session, user_id)`
- `get_user_roles_map(session, user_ids)`
---
## 8.2 `app/api/service/rbacService.py`
### 职责
- 角色 CRUD
- 权限 CRUD
- 菜单 CRUD
- 角色绑定权限
- 角色绑定菜单
- 菜单树构建
### 方法建议
- `create(session, model_cls, add_info)`
- `update_by_id(session, model_cls, obj_id, update_info, soft_delete=True)`
- `get_by_id(session, model_cls, obj_id, soft_delete=True)`
- `list_by_filters(session, model_cls, filter_list, page_num=1, page_size=20, order_column=None)`
- `delete_by_id(session, model_cls, obj_id)`
- `assign_permissions(session, role_id, permission_ids)`
- `assign_menus(session, role_id, menu_ids)`
- `get_role_permission_ids(session, role_id)`
- `get_role_menu_ids(session, role_id)`
- `build_menu_tree(session, filters)`
---
## 9. Controller 设计
controller 仅负责:
- 参数获取 `_get(...)`
- 必填校验
- 字段映射
- 调用 service
- 序列化返回
不得直接 `session.query(...)`
---
## 9.1 `app/api/controller/userController.py`
### 建议方法
- `user_list`
- `user_detail`
- `user_create`
- `user_update`
- `user_delete`
- `user_role_assign`
- `user_role_list`
### 返回增强建议
`user_list` 每项增加:
- `role_ids`
- `role_names`
---
## 9.2 `app/api/controller/rbacController.py`
### 角色相关
- `role_list`
- `role_detail`
- `role_create`
- `role_update`
- `role_delete`
- `role_permission_assign`
- `role_permission_list`
- `role_menu_assign`
- `role_menu_list`
### 权限相关
- `permission_list`
- `permission_detail`
- `permission_create`
- `permission_update`
- `permission_delete`
### 菜单相关
- `menu_tree`
- `menu_detail`
- `menu_create`
- `menu_update`
- `menu_delete`
---
## 10. 接口清单设计
以下接口路径保持当前项目风格。
---
## 10.1 角色管理接口
### 角色列表
- `GET /role/list`
- 参数:`keyword`, `status`, `pageNo`, `pageSize`
- 返回:角色分页列表
### 角色详情
- `GET /role/detail`
- 参数:`roleId`
### 创建角色
- `POST /role/create`
- 参数:
- `code`
- `name`
- `description`
- `status`
- `isSystem`
### 更新角色
- `POST /role/update`
- 参数:
- `roleId`
- 可选更新字段
### 删除角色
- `POST /role/delete`
- 参数:`roleId`
---
## 10.2 权限管理接口
### 权限列表
- `GET /permission/list`
- 参数:`keyword`, `module`, `status`, `pageNo`, `pageSize`
### 权限详情
- `GET /permission/detail`
- 参数:`permissionId`
### 创建权限
- `POST /permission/create`
### 更新权限
- `POST /permission/update`
### 删除权限
- `POST /permission/delete`
---
## 10.3 菜单管理接口
### 菜单树
- `GET /menu/tree`
- 参数:可选 `status`
- 返回树形结构
### 菜单详情
- `GET /menu/detail`
- 参数:`menuId`
### 创建菜单
- `POST /menu/create`
### 更新菜单
- `POST /menu/update`
### 删除菜单
- `POST /menu/delete`
---
## 10.4 角色权限分配接口
### 查询角色权限
- `GET /role/permission/list`
- 参数:`roleId`
- 返回:`permissionIds` + 权限明细列表
### 分配角色权限
- `POST /role/permission/assign`
- 参数:
- `roleId`
- `permissionIds: []`
建议语义:覆盖式保存
---
## 10.5 角色菜单分配接口
### 查询角色菜单
- `GET /role/menu/list`
- 参数:`roleId`
- 返回:`menuIds` + 菜单树
### 分配角色菜单
- `POST /role/menu/assign`
- 参数:
- `roleId`
- `menuIds: []`
建议语义:覆盖式保存
---
## 10.6 用户管理接口
### 用户列表
- `GET /user/list`
- 参数:`keyword`, `status`, `pageNo`, `pageSize`
### 用户详情
- `GET /user/detail`
- 参数:`userId`
### 创建用户
- `POST /user/create`
- 参数:
- `username`
- `realName`
- `password`
- `mobile`
- `email`
- `status`
### 更新用户
- `POST /user/update`
- 参数:
- `userId`
- 可选更新字段
### 删除用户
- `POST /user/delete`
- 参数:`userId`
---
## 10.7 用户角色分配接口
### 查询用户角色
- `GET /user/role/list`
- 参数:`userId`
- 返回:`roleIds` + 角色列表
### 分配用户角色
- `POST /user/role/assign`
- 参数:
- `userId`
- `roleIds: []`
建议语义:覆盖式保存
---
## 11. 返回结构建议
### 11.1 角色列表项
```json
{
"id": 1,
"code": "admin",
"name": "管理员",
"description": "系统管理员",
"status": 1,
"is_system": 1,
"created_time": "2025-01-01 10:00:00"
}
```
### 11.2 用户列表项
```json
{
"id": 1,
"username": "zhangsan",
"real_name": "张三",
"mobile": "13800000000",
"email": "a@test.com",
"status": 1,
"role_ids": [1, 2],
"role_names": ["管理员", "测试经理"]
}
```
### 11.3 菜单树项
```json
{
"id": 1,
"parent_id": 0,
"name": "系统管理",
"code": "system",
"type": 1,
"path": "/system",
"component": "Layout",
"icon": "setting",
"sort": 1,
"children": []
}
```
---
## 12. 文件清单
本次功能落地预计新增/修改以下文件。
### 12.1 新增 model
- `app/api/model/userModel.py`
- `app/api/model/rbacModel.py`
### 12.2 新增 dao
- `app/api/dao/userDao.py`
- `app/api/dao/rbacDao.py`
### 12.3 新增 service
- `app/api/service/userService.py`
- `app/api/service/rbacService.py`
### 12.4 新增 controller
- `app/api/controller/userController.py`
- `app/api/controller/rbacController.py`
### 12.5 修改 views
- `app/api/views.py`
### 12.6 可能新增 SQL 脚本(如果你需要)
- 数据库建表 SQL
- 初始化菜单/权限/角色种子数据 SQL
---
## 13. 分层职责清单
### model
- 只定义表结构
### dao
- 只做数据库查询/写入
- 负责关联表的增删查
### service
- 负责组合查询、覆盖式分配逻辑、聚合返回结构前的数据准备
### controller
- 参数校验、字段映射、调用 service、返回结构组装
### views
- 路由注册、request/response 包装
---
## 14. 推荐实现顺序
### 第一阶段:基础 RBAC 数据层
1. 建表 SQL
2. model
3. dao
4. service
### 第二阶段:角色/权限/菜单接口
1. role CRUD
2. permission CRUD
3. menu CRUD
4. role-permission assign
5. role-menu assign
### 第三阶段:用户接口
1. user CRUD
2. user-role assign
3. user list/detail 聚合角色信息
### 第四阶段:初始化与联调
1. 初始化菜单
2. 初始化权限
3. 初始化管理员角色
4. 初始化管理员用户
---
## 15. 关键设计决策
### 15.1 分配类接口采用覆盖式保存
原因:
- 前端实现简单
- 后端一致性更好
- 避免增删混合接口过多
### 15.2 菜单与权限分离
原因:
- 菜单是导航资源
- 权限是操作资源
- 一些按钮权限不一定出现在菜单树中
### 15.3 用户表单独建设,不复用现有 project_member
原因:
- `project_member` 是项目成员关系,不是系统账户主表
- 用户管理需要登录凭据、状态、手机号、邮箱等字段
### 15.4 先不引入复杂组织架构
原因:
- 当前需求聚焦 RBAC + 用户 + 菜单
- 可后续扩展部门/租户/产品维度数据权限
---
## 16. 后续可扩展项
1. 登录认证
- JWT / Session
2. 密码重置
3. 数据权限
- 按产品/项目/部门的数据访问范围
4. 操作审计日志
5. 菜单与接口权限自动同步
6. 超级管理员保护机制
---
## 17. 需要你确认的点
请你确认以下设计取舍:
1. 用户表是否需要登录密码字段(默认:需要)
2. 权限是否按 `module:action` 编码(默认:是)
3. 菜单是否需要按钮类型 `type=3`(默认:需要)
4. 分配接口是否采用覆盖式保存(默认:是)
5. 是否需要初始化内置角色:
- 超级管理员
- 测试经理
- 测试工程师
6. 用户是否允许多角色(默认:允许)
7. 菜单是否只做系统后台菜单,不含项目业务模块动态菜单(默认:只做后台菜单)
---
## 18. 下一步建议
如果你确认这份设计,我下一步可以继续给你输出两部分:
1. **完整建表 SQL**
2. **按当前项目风格拆好的代码落地清单**
- 每个文件该写哪些类、哪些方法、哪些接口