# 角色/用户/菜单管理详细设计文档

## 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 | 父菜单ID，0表示根节点 |
| 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. **按当前项目风格拆好的代码落地清单**
   - 每个文件该写哪些类、哪些方法、哪些接口

