BaiLuoYan пре 1 дан
родитељ
комит
71ab62bb81
1 измењених фајлова са 63 додато и 19 уклоњено
  1. 63 19
      README.md

+ 63 - 19
README.md

@@ -296,8 +296,8 @@ POST /api/role/bindPerms  {"roleId": 3, "permIds": [1,5]}            # 客服:
 
 ```bash
 # 创建用户,归属研发部
-POST /api/user/create  {"username": "zhangsan", "password": "123456", "nickname": "张三", "deptId": 1}
-# 返回 userId=10
+POST /api/user/create  {"username": "zhangsan", "nickname": "张三", "deptId": 1}
+# 返回 userId=10, credentialsTicket(用于领取初始密码)
 
 # 将张三添加为 CRM 和 OA 的成员(MEMBER 类型即可)
 POST /api/member/add  {"productCode": "crm", "userId": 10, "memberType": "MEMBER"}
@@ -317,8 +317,8 @@ POST /api/member/remove  {"id": <张三在OA中的成员记录ID>}
 **场景 C:市场部李四** — 需要使用 CRM,分配销售角色
 
 ```bash
-POST /api/user/create  {"username": "lisi", "password": "123456", "nickname": "李四", "deptId": 2}
-# 返回 userId=11
+POST /api/user/create  {"username": "lisi", "nickname": "李四", "deptId": 2}
+# 返回 userId=11, credentialsTicket
 
 POST /api/member/add    {"productCode": "crm", "userId": 11, "memberType": "MEMBER"}
 POST /api/user/bindRoles  {"userId": 11, "roleIds": [2], "productCode": "crm"}  # 分配"普通销售"角色
@@ -344,7 +344,7 @@ POST /api/user/setPerms  {
 **场景 E:外部临时协作人员** — 不属于任何部门
 
 ```bash
-POST /api/user/create   {"username": "temp_wang", "password": "123456", "nickname": "外包王五"}
+POST /api/user/create   {"username": "temp_wang", "nickname": "外包王五"}
 # deptId 不传,不归属任何部门
 
 POST /api/member/add    {"productCode": "crm", "userId": 12, "memberType": "MEMBER"}
@@ -407,7 +407,9 @@ flowchart LR
 | 删除角色 | 超管 或 产品管理员 | 级联删除关联数据 |
 | 绑定角色权限 | 超管 或 产品管理员 | — |
 | **用户管理** | | |
-| 创建用户 | 超管 或 产品管理员 | — |
+| 创建用户 | 超管 或 产品管理员 | 服务端生成密码,ticket 下发 |
+| 重置密码 | 通过 `CheckManageAccess` | 不可重置超管密码 |
+| 获取用户凭证 | 超管 或 产品管理员 | ticket 一次性消费 |
 | 更新用户信息 | 仅本人 或 超管 | — |
 | 冻结/解冻用户 | 通过 `CheckManageAccess` | 不可冻结自己和超管 |
 | 绑定角色 | 通过 `CheckManageAccess` | 目标用户的成员状态必须启用 |
@@ -1295,27 +1297,69 @@ Content-Type: application/json
 
 #### POST /api/user/create — 创建用户(超级管理员 或 产品管理员)
 
-创建一个全局用户账号。用户是全局概念,创建后可通过「添加成员」接口加入多个产品
+创建一个全局用户账号。服务端自动生成符合强度要求的随机密码,通过一次性凭证票据(ticket)安全下发,避免密码明文出现在请求/响应体中
 
 **调用场景:**
 
-- **新员工入职**:HR 或管理员为新员工创建账号,设置初始密码,并归属到对应部门
+- **新员工入职**:HR 或管理员为新员工创建账号并归属到对应部门,创建成功后通过 ticket 领取初始密码交给员工
 - **批量建立账号**:运维脚本遍历员工花名册,批量调用此接口创建用户账号
 - **外部协作人员**:为外包或合作伙伴创建账号(可不设 `deptId`),后续通过成员管理授予特定产品访问权
 
-**注意事项:** 创建用户后还需通过 `/member/add` 将其加入产品才能登录使用该产品。
+**注意事项:** 创建用户后还需通过 `/member/add` 将其加入产品才能登录使用该产品。响应中携带 `credentialsTicket`(5 分钟有效),需立即调用 `/api/user/fetchCredentials` 领取用户名和初始密码。ticket 一次消费即失效。用户首次登录后会被强制要求修改密码(`mustChangePassword=1`)。
 
 | 字段 | 类型 | 必填 | 说明 |
 | ------ | ------ | ------ | ------ |
 | username | string | 是 | 登录名(全局唯一) |
-| password | string | 是 | 密码(6-72 字符) |
 | nickname | string | 否 | 昵称 |
 | email | string | 否 | 邮箱(需合法格式) |
 | phone | string | 否 | 手机号(7-15 位数字,可含 `+` 前缀) |
 | remark | string | 否 | 备注 |
 | deptId | int64 | 否 | 部门 ID(归属研发部门的用户加入产品后自动获得全部权限) |
 
-**响应 data:** `{"id": 1}`
+**响应 data:** `{"id": 1, "credentialsTicket": "...", "credentialsExpiresAt": 1716000000}`
+
+#### POST /api/user/resetPassword — 重置用户密码(超级管理员 或 产品管理员)
+
+管理员为指定用户重置密码。服务端生成新的随机强密码,通过一次性凭证票据安全下发。重置后旧令牌即时失效(tokenVersion 递增),用户下次登录需使用新密码且会被强制要求修改密码。
+
+**调用场景:**
+
+- **用户忘记密码**:用户无法自行修改密码时,管理员为其重置
+- **安全事件处置**:发现账号异常时,管理员重置密码使旧凭据失效
+- **新员工初始密码遗失**:创建用户时的 ticket 过期或已消费,管理员通过重置密码重新生成
+
+**安全约束:**
+
+- 不允许重置超级管理员的密码(超管只能通过 `/auth/changePassword` 自行修改)
+- 需通过 `CheckManageAccess` 权限检查(防止越权重置高级别用户)
+- 重置后递增 `tokenVersion`,所有已签发令牌即时失效
+
+| 字段 | 类型 | 必填 | 说明 |
+| ------ | ------ | ------ | ------ |
+| userId | int64 | 是 | 目标用户 ID |
+
+**响应 data:** `{"credentialsTicket": "...", "credentialsExpiresAt": 1716000000}`
+
+#### POST /api/user/fetchCredentials — 获取用户凭证(超级管理员 或 产品管理员)
+
+安全地获取用户创建或密码重置时生成的凭证(用户名 + 密码)。采用一次性 ticket 机制,凭证仅可获取一次。
+
+**调用场景:**
+
+- **创建用户后获取凭证**:管理后台创建用户成功后,前端使用返回的 ticket 调用此接口获取初始密码并展示给管理员
+- **重置密码后获取凭证**:管理员重置用户密码后,前端使用返回的 ticket 获取新密码
+
+**安全约束:**
+
+- 仅超级管理员或产品管理员可调用
+- ticket 存储在 Redis 中,TTL 为 5 分钟,过期后无法获取
+- ticket 采用原子性 GetDel 操作,确保一次性消费,防止重放攻击
+
+| 字段 | 类型 | 必填 | 说明 |
+| ------ | ------ | ------ | ------ |
+| ticket | string | 是 | 创建用户或重置密码时返回的一次性凭证票据 |
+
+**响应 data:** `{"username": "zhangsan", "password": "Ax7#kL9m..."}`
 
 #### POST /api/user/update — 更新用户(仅本人 或 超级管理员)
 
@@ -1694,7 +1738,7 @@ server/
 ├── gen-api.sh                        # API 代码生成脚本
 ├── gen-model.sh                      # Model 代码生成脚本
 ├── run-test.sh                       # 测试运行脚本
-├── test-design.md                    # 测试用例设计文档(433 TC)
+├── test-design.md                    # 测试用例设计文档(1065 TC)
 ├── test-report.md                    # 测试报告
 ├── etc/
 │   └── perm-api.yaml                 # 服务配置
@@ -1818,12 +1862,12 @@ server {
 
 | 指标 | 数值 |
 | ------ | ------ |
-| 测试用例总数 | 499 |
-| 已覆盖 TC | 498(99.8%) |
-| 测试函数 | 662 |
-| 测试子用例 | 744 |
-| 测试包 | 23 |
-| 通过率 | 99.7% |
+| 测试用例总数 | 1065 |
+| 已覆盖 TC | 1065(100%) |
+| 测试函数 | 1170 |
+| 测试子用例 | 1309 |
+| 测试包 | 28 |
+| 通过率 | 100% |
 
 测试覆盖范围:
 
@@ -1841,7 +1885,7 @@ server {
 
 | 文件 | 说明 |
 | ------ | ------ |
-| `test-design.md` | 测试用例设计文档(499 个 TC,含测试场景、输入数据、预期结果) |
+| `test-design.md` | 测试用例设计文档(1065 个 TC,含测试场景、输入数据、预期结果) |
 | `test-report.md` | 测试执行报告(含各包耗时、TC 明细、源码审计结果) |
 
 ### 运行测试