SFT/缺失的后端接口.md

351 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 缺失的后端接口
> 说明:本项目前端已按下述接口契约完成开发,并使用 `mock-server/`(开发期专用、不作为交付物)完整模拟了 8.1 通用鉴权 与 8.3 系统管理 共 18 个接口用于本地验证;8.2 基础通用能力共 5 个接口在阶段 1 暂无实际消费页面(将在后续"授信管理""钱包管理"等阶段接入),此处先登记契约供后端团队提前评估。
>
> 通用约定:
> - 所有接口返回统一包裹结构 `{ "code": number, "msg": string, "data": any }`,`code === 200` 表示业务成功,其余为业务错误码(本文档中列出的错误码均为 mock-server 已实现的示例编码,后端可自行编排,前端仅依赖 `code !== 200` 判断失败并展示 `msg`)。
> - 除登录、刷新令牌、发送短信外,其余接口均需在请求头携带 `Authorization: Bearer {access_token}`;未携带或已过期返回 HTTP 401。
> - 日期时间字段格式统一为 `yyyy-MM-dd HH:mm:ss`。
> - `access_token` 建议有效期 30 分钟,`refresh_token` 建议有效期 7 天,通过 `Set-Cookie`(`HttpOnly`)下发,前端请求需 `withCredentials: true`。
> - 所有按 `{id}` 修改/删除/查看的接口,若目标资源不存在,统一返回 `40404`(资源不存在);`access_token` 失效或缺失统一返回 HTTP 401(mock-server 中对应业务码 `40100`)。
## 8.1 通用鉴权接口
### 1. 发送登录短信验证码
`POST /auth/sms/send`
请求参数(Body):
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| username | string | 是 | 账号 |
| password | string | 是 | 密码,用于登录前校验账号密码有效性 |
后端需校验账号密码正确且账号未锁定后,向该账号绑定手机号发送验证码(mock-server 固定验证码为 `123456`)。
响应 `data`:`null`
可能的业务错误码:账号或密码错误(如 40001)、账号已锁定(如 40002)。
### 2. 登录
`POST /auth/login`
请求参数(Body):
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| username | string | 是 | 账号 |
| password | string | 是 | 密码 |
| code | string | 是 | 短信验证码 |
响应 `data`:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| accessToken | string | 访问令牌 |
| userInfo | object | `{ id, username, realName, orgId, roleIds }` |
| menuTree | array | 按当前用户角色裁剪后的菜单权限树(结构见 8.3.21) |
| buttonCodes | array\<string\> | 按当前用户角色裁剪后的按钮权限码集合 |
| mustChangePassword | boolean | 是否强制修改密码(新建用户首次登录 / 管理员重置密码后为 `true`) |
`refresh_token` 通过 `Set-Cookie`(`HttpOnly`)下发,不出现在响应体中。
可能的业务错误码:账号或密码错误(40001)、账号已锁定(40002)、验证码错误或已过期(40003)、连续5次登录失败自动锁定(40002)。
### 3. 刷新令牌
`POST /auth/refresh`
请求参数:无 Body,依赖 Cookie 中的 `refresh_token`
响应 `data`:`{ accessToken: string }`
`refresh_token` 失效或不存在时返回 HTTP 401,前端将清空登录态并跳转登录页。
### 4. 登出
`POST /auth/logout`
请求参数:无。后端需失效当前 `refresh_token` 并清除 Cookie。
响应 `data`:`null`
### 5. 获取当前用户信息
`GET /auth/userinfo`
响应 `data`:`{ id, username, realName, orgId, roleIds }`
### 6. 获取当前用户菜单权限树
`GET /auth/menu`
响应 `data`:`{ menuTree, buttonCodes }`(结构同登录接口,供页面刷新后重建路由使用)
---
## 8.2 基础通用能力接口
> 本阶段暂无页面直接消费,契约供后续阶段(授信管理的证件识别、钱包管理的开户等)提前评估。
### 7. 文件上传(Base64)
`POST /common/file/upload`
请求参数(Body):
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| fileName | string | 是 | 原始文件名(含扩展名) |
| fileBase64 | string | 是 | 文件内容 Base64 编码(不含 `data:` 前缀) |
| bizType | string | 否 | 业务场景标识,便于后端分类存储,取值由后端定义 |
响应 `data`:`{ fileId: string, fileUrl: string }`
### 8. OCR 识别 - 身份证
`POST /common/ocr/idcard`
请求参数(Body):
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| imageBase64 | string | 是 | 身份证图片 Base64 编码 |
| side | string | 是 | `front`(人像面)/ `back`(国徽面) |
响应 `data`(`side=front`):`{ name, idNumber, gender, birthDate, address }`
响应 `data`(`side=back`):`{ issueAuthority, validPeriod }`
### 9. OCR 识别 - 营业执照
`POST /common/ocr/license`
请求参数(Body):`{ imageBase64: string }`
响应 `data`:`{ companyName, creditCode, legalPerson, registeredAddress, businessScope, establishDate, validPeriod }`
### 10. 短信发送(通用业务场景)
`POST /common/sms/send`
请求参数(Body):
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| phone | string | 是 | 目标手机号 |
| sceneCode | string | 是 | 业务场景码(如开户验证、支付验证等,枚举值由后端维护) |
响应 `data`:`null`
### 11. 短信校验
`POST /common/sms/verify`
请求参数(Body):`{ phone: string, sceneCode: string, code: string }`
响应 `data`:`{ valid: boolean }`
---
## 8.3 系统管理接口
### 12. 用户列表查询
`GET /system/user/list`
查询参数:
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| orgId | string | 否 | 所属机构 ID(精确匹配) |
| username | string | 否 | 用户名,模糊匹配 |
| phone | string | 否 | 手机号,模糊匹配 |
| status | string | 否 | `enabled`(正常) / `locked`(已锁定) |
| roleId | string | 否 | 角色 ID |
| page | number | 否 | 页码,默认 1 |
| pageSize | number | 否 | 每页条数,默认 10 |
响应 `data`:`{ list: UserItem[], total: number }`,`UserItem` 字段:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | string | 用户 ID |
| username | string | 用户名 |
| realName | string | 真实姓名 |
| phone | string | 手机号 |
| orgId | string | 所属机构 ID |
| orgName | string | 所属机构名称 |
| roleIds | string[] | 角色 ID 列表 |
| roleNames | string[] | 角色名称列表 |
| status | string | `enabled` / `locked` |
| createdAt | string | 创建时间 |
| lastLoginAt | string | 最后登录时间(未登录过为空字符串) |
### 13. 新增用户
`POST /system/user`
请求参数(Body):
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| username | string | 是 | 用户名,不做唯一性强制校验 |
| phone | string | 是 | 11 位手机号,全局唯一 |
| realName | string | 否 | 真实姓名 |
| orgId | string | 是 | 所属机构 ID |
| roleIds | string[] | 是 | 用户角色 ID 列表(需为已启用角色) |
后端需随机生成 8 位初始密码(含大写字母+数字),并将 `mustChangePassword` 置为 `true`
响应 `data`:`{ id: string, initialPassword: string }`(`initialPassword` 仅在创建时一次性返回,供管理员告知用户,不再另行短信通知)。
可能的业务错误码:用户名为空(40010)、手机号格式错误(40011)、手机号已注册(40012)、所属机构无效(40013)、未选择角色(40014)。
### 14. 修改用户
`PUT /system/user/{id}`
请求参数(Body):`{ phone, realName, orgId, roleIds }`(不含 `username`,用户名创建后不可修改)
响应 `data`:`null`;校验规则同新增(手机号格式/唯一性、机构有效性、角色非空)。
### 15. 删除用户
`DELETE /system/user/{id}`
响应 `data`:`null`
### 16. 锁定 / 解锁用户
`PUT /system/user/{id}/lock`、`PUT /system/user/{id}/unlock`
无请求参数。解锁时后端需同时将连续登录失败次数计数清零。响应 `data`:`null`
### 17. 密码修改(管理员直接指定新密码)
`PUT /system/user/{id}/password`
请求参数(Body):`{ newPassword: string }`(需满足 8 位以上且包含大小写字母和数字)
后端需将该用户 `mustChangePassword` 置为 `false`。响应 `data`:`null`
可能的业务错误码:密码强度不足(40015)。
> 该接口同时被"首次登录强制改密"流程复用:新建用户或被管理员重置密码后,登录成功响应中 `mustChangePassword=true`,前端会弹出强制改密弹窗,调用本接口完成改密后才允许进入系统。
### 18. 密码重置并发送短信
`PUT /system/user/{id}/password/reset`
无请求参数。后端固定将密码重置为 `123456`,`mustChangePassword` 置为 `true`,并通过短信通知用户。响应 `data`:`null`
### 19. 角色列表查询
`GET /system/role/list`
查询参数:
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| name | string | 否 | 角色名称,模糊匹配 |
| orgId | string | 否 | 所属机构 ID |
| status | string | 否 | `enabled` / `disabled` |
| page | number | 否 | 页码,默认 1 |
| pageSize | number | 否 | 每页条数,默认较大值(供无分页场景一次性取全量,如用户新增页的角色下拉) |
响应 `data`:`{ list: RoleItem[], total: number }`,`RoleItem` 字段:`{ id, name, orgId, orgName, status, builtin, createdAt }`
### 20. 新增 / 修改 / 删除 / 查看角色
`POST /system/role`、`PUT /system/role/{id}`、`DELETE /system/role/{id}`、`GET /system/role/{id}`
新增/修改请求参数(Body):
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| name | string | 是 | 角色名称,同一所属机构下不可重复 |
| orgId | string | 是 | 所属机构 ID |
| menuIds | string[] | 是 | 已勾选的页面权限(菜单节点 ID),至少 1 项 |
| buttonCodes | string[] | 否 | 已勾选的功能权限(按钮码),可为空数组 |
| dataScope | string | 是 | 数据权限范围,枚举:`own`(本机构)/ `ownAndSub`(本机构及下级机构)/ `all`(全部机构) |
查看接口 `GET /system/role/{id}` 响应 `data` 在上述字段基础上附加 `id、builtin、status、createdAt`
删除接口无请求参数,响应 `data`:`null`。
业务规则:
- 内置角色(`builtin=true`,如【内置】系统管理员)不可删除、不可改名(如 `PUT` 请求体 `name` 与原值不同则拒绝)。
- 同一 `orgId``name` 不可重复。
- 已被任意用户 `roleIds` 引用的角色禁止删除,需先解除关联。
可能的业务错误码:角色名称为空(40016)、未选择页面权限(40017)、数据权限范围无效(40018)、同机构下角色名重复(40019)、内置角色不可改名(40020)、内置角色不可删除(40021)、角色已关联用户不可删除(40022)。
### 21. 获取权限字典树(菜单+按钮)
`GET /system/permission/tree`
响应 `data`:菜单权限树(供角色管理页"权限配置"组件勾选使用),节点结构:
```json
{
"id": "sys_user",
"name": "用户管理",
"path": "/system/user",
"icon": "SettingOutlined",
"type": "menu",
"component": "system/user/UserList",
"children": [],
"buttons": [
{ "code": "user:add", "name": "新增" }
]
}
```
> 登录接口 / 获取菜单接口(8.1.2、8.1.6)返回的 `menuTree` 是本树按当前用户所有已启用角色的 `menuIds``buttonCodes` 裁剪后的子集(仅保留命中节点及其祖先节点,按钮列表同步过滤),用于驱动前端动态路由与按钮显隐。
### 22. 机构列表查询(树)
`GET /system/org/list`
查询参数:`{ name?: string, id?: string }`(按机构名称或机构 ID 模糊匹配;命中节点的祖先节点会一并返回以保持树结构完整)
响应 `data`:机构树,节点结构:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | string | 机构 ID,全局唯一、自动生成、不可修改 |
| name | string | 机构名称 |
| parentId | string \| null | 上级机构 ID,一级机构为 `null` |
| level | number | 机构级别,一级机构为 1 |
| remark | string | 备注 |
| builtin | boolean | 是否为内置一级机构(不可删除) |
| createdAt | string | 创建时间 |
| children | array | 下级机构(结构同上,递归) |
### 23. 新增 / 修改 / 删除机构
`POST /system/org`、`PUT /system/org/{id}`、`DELETE /system/org/{id}`
新增/修改请求参数(Body):
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| name | string | 是 | 机构名称 |
| parentId | string | 一级机构(内置根机构)本身除外均为是 | 上级机构 ID,不可选择自身或自身下级 |
| remark | string | 否 | 备注 |
删除接口无请求参数,响应 `data`:`null`。
业务规则:
- 一级机构(内置根机构,`builtin=true`)不可删除。
- 存在下级机构时禁止删除。
- 已关联用户(`user.orgId` 命中)时禁止删除。
- 同一 `parentId``name` 不可重复。
- **已知限制**:业务需求文档中"存在已关联核心企业时禁止删除机构"的规则,因"核心企业"功能属于后续阶段(基础配置模块),本阶段尚无该数据源,暂未实现该项校验,待核心企业模块上线后需补充。
可能的业务错误码:机构名称为空(40004)、上级机构无效(40004)、同上级下机构名重复(40005)、上级机构选择了自身或下级(40006)、一级机构不可删除(40007)、存在下级机构不可删除(40008)、已关联用户不可删除(40009)。