Files
xh-medical-sign-web/clinical-web/docs/users-permissions-api.md
T
yelan fc22d22f85 feat(config): 按业务模块拆分 Mock 开关
用 VITE_MOCK_* 系列环境变量替换全局 VITE_USE_MOCK,各模块独立控制演示数据
启用,并新增 src/utils/mock-flags.ts 统一解析缺省值。文档库关闭演示库时
如实提示接口待接入,避免静默沿用本地数据或覆盖已保存内容。
2026-09-15 09:47:31 +08:00

97 lines
8.8 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.
# 用户与权限接口核验与接入说明
> 核验基准:本机后端 `http://127.0.0.1:18080/v3/api-docs`(接口前缀为 `/api`)。浏览器请求仍统一使用 `/api`,认证请求头为 `X-Token`。
## 1. 核验结论
后端当前已经提供用户、角色、API 权限关系和模板权限所需的主要接口。前端原实现的主要问题不是代理地址,而是把已经存在的接口误判为缺失,导致角色显示、密码重置、批量导入和角色权限分配没有真正接通。
本轮已完成以下接入:
- 用户列表和详情正确映射后端 `LOCKED` 状态、角色摘要、院区/科室名称、版本号和首次改密标记;
- 新增用户提交 `roleIds`,编辑用户使用聚合管理接口完整替换资料和角色,并提交 `expectedVersion`;
- 角色卡片改用 `GET /api/v1/roles/summary` 获取服务端人数统计;
- 重置密码使用 `POST /api/v1/users/{userId}/password/reset`,前端校验 12 位密码并支持下次登录改密;
- 批量导入使用预览、确认提交和任务查询三段流程,不展示或记录密码、手机号和邮箱;
- 用户与角色的 API 权限分配使用 `GET/PUT /api/v1/roles/{roleId}/permissions`,不再把权限目录 CRUD 当成关系接口;
- 模板文档权限页支持 `USER` 授权对象,可对单个用户增加或删除模板权限;
- 登录后的受保护路由会刷新 `/api/v1/auth/me`,用户页菜单和路由至少按 `system:user:query` 做体验层门控,最终权限仍由后端校验。
## 2. 后端契约与前端映射
| 页面能力 | 后端接口 | 前端状态 | 关键约束 |
| -------------- | ------------------------------------------------------------ | ---------- | ------------------------------------------------------------------------------------- |
| 用户列表 | `GET /api/v1/users` | 已接入 | `page` 从 1 开始,`size` 传后端分页参数;支持 `keyword`、`campusId` |
| 用户详情 | `GET /api/v1/users/{id}` | 已接入 | 角色从 `roles` 摘要映射为角色名称和 ID |
| 新增用户 | `POST /api/v1/users` | 已接入 | `username`、`password`、`displayName`、`campusId` 必填;密码至少 8 位;可传 `roleIds` |
| 编辑用户资料 | `PUT /api/v1/users/{id}` | API 已封装 | 不接收用户名和密码;支持 `clearPhone`、`clearEmail`、`expectedVersion` |
| 编辑用户与角色 | `PUT /api/v1/users/{id}/management` | 已接入 | 一次提交资料、数据范围和完整 `roleIds`;使用版本号避免覆盖并发修改 |
| 读取用户角色 | `GET /api/v1/users/{userId}/roles` | API 已封装 | 返回角色摘要、关系版本和更新时间 |
| 覆盖用户角色 | `PUT /api/v1/users/{userId}/roles` | API 已封装 | `roleIds` 是完整替换集合,可选 `expectedVersion` |
| 停用用户 | `DELETE /api/v1/users/{id}` | 已接入 | 后端语义为软停用,前端保留二次确认 |
| 重置密码 | `POST /api/v1/users/{userId}/password/reset` | 已接入 | `newPassword` 至少 12 位;响应不返回密码 |
| 导入预览 | `POST /api/v1/users/import/preview` | 已接入 | `multipart/form-data`,字段为 `file`,可选默认 `campusId` |
| 确认导入 | `POST /api/v1/users/import/commit` | 已接入 | 仅提交预览返回的 `importId`;预览存在错误时前端禁止提交 |
| 导入任务 | `GET /api/v1/users/import/jobs/{jobId}` | 已接入 | 展示服务端任务状态,不把文件内容写入日志 |
| 角色分页 | `GET /api/v1/roles` | 已接入 | `RoleResponse` 不含 `userCount`,只用于角色选项和基础信息 |
| 角色人数 | `GET /api/v1/roles/summary` | 已接入 | 人数由服务端统计,支持可选 `campusId` |
| API 权限目录 | `GET/POST/PUT/DELETE /api/v1/permissions` | API 已封装 | 这是权限定义目录,不是角色关系 |
| 角色 API 权限 | `GET/PUT /api/v1/roles/{roleId}/permissions` | 已接入 | `permissionIds` 完整替换,可选 `expectedVersion` |
| 当前用户 | `GET /api/v1/auth/me` | 已接入 | 刷新 `permissions`、角色、数据范围和 `passwordChangeRequired` |
| 模板权限 | `GET/POST/DELETE /api/v1/templates/{templateId}/permissions` | 已接入 | `subjectType` 支持 `ROLE`、`DEPARTMENT`、`USER`;继承记录不可直接删除 |
## 3. 重要 DTO 规则
### 3.1 用户状态和并发版本
后端用户状态为 `ENABLED`、`DISABLED`、`LOCKED`。此前前端把除 `DISABLED` 外的所有值都当成启用,已修复为三态映射;锁定用户不能建立会话,不能仅按“停用”展示。
用户编辑响应带有 `version`。聚合编辑会将该版本作为 `expectedVersion` 提交,服务端返回并发冲突时前端不会自行覆盖新数据。
### 3.2 脱敏联系方式
详情可能返回脱敏手机号或邮箱。前端未修改脱敏字段时不回传该字段;用户明确清空时才提交 `clearPhone: true` 或 `clearEmail: true`。完整手机号、邮箱和密码不写入日志或审计展示。
### 3.3 批量导入
预览响应只包含行号、校验状态、错误、用户名和姓名,不包含手机号、邮箱或密码。前端只有在 `invalidRows === 0` 时才启用确认按钮,提交后展示 `jobId` 和服务端状态。
## 4. 仍需后端确认或前端后续补齐的事项
1. OpenAPI 给出了权限资源和动作枚举,但没有给出完整的权限编码初始化清单。前端目前使用已存在于权限目录 Mock/约定中的 `system:user:query` 做用户页菜单与路由门控;`system:user:create`、`system:user:update`、`system:user:disable`、角色及权限关系的最终编码需要以后端权限中心实际数据为准。
2. 当前页面已经能分配角色 API 权限,但 API 权限目录本身的新增、编辑、停用尚未做独立管理页面;对应 API 封装已存在。
3. 后端提供了 `POST /api/v1/auth/password/change`,当前只完成请求类型和 API 封装,尚未在本轮新增强制改密弹窗。`passwordChangeRequired` 已保留在登录和当前用户模型中,产品若要求登录后强制改密,应补充全局改密流程。
4. 导入任务契约当前状态为 `PREVIEWED`、`COMMITTED`、`EXPIRED`、`FAILED`;如果未来改为真正异步处理,应在后端扩展状态和前端轮询策略,不能由前端猜测完成状态。
5. 所有管理接口仍必须由后端执行 `401/403`、数据范围、角色/权限状态和审计校验。前端隐藏菜单或按钮只改善体验,不能作为安全边界。
## 5. 联调验收
真实接口模式:
```bash
VITE_MOCK_USERS=false npm run dev
```
至少验证以下场景:
- 登录后 Network 中所有业务请求带 `X-Token`,并能看到一次 `/api/v1/auth/me`;
- 用户详情显示后端角色名称,编辑角色后刷新列表仍保持;
- `LOCKED` 用户显示为锁定而不是启用;
- 未修改脱敏联系方式时编辑不会覆盖原值,清空时发送清除标记;
- 重置密码不出现在任何响应、列表或前端日志;
- 导入存在错误时不能提交,零错误预览才允许提交并显示任务号;
- 角色 API 权限保存后重新读取,确认 `permissionIds` 是完整替换结果;
- 模板权限可选择单个用户,直接权限可删除,继承权限保持不可删除;
- 无用户查询权限的账号不能通过菜单或直接 URL进入用户页,后端 `403` 仍是最终判断。
## 6. 验证命令
本轮修改后应在 `clinical-web` 目录执行:
```bash
npm run lint
npm run format:check
npx vue-tsc --noEmit
npm run build -- --outDir /tmp/clinical-web-build-<date>
```