# 05-API接口契约 BasePath: `/api` 端口: `8080` ## 全局约定 ### 响应格式 ```json {"code": 200, "message": "操作成功", "data": {}, "timestamp": 1700000000000} ``` ### 错误码 | 范围 | 含义 | |---|---| | 200 | 成功 | | 400xx | 客户端参数错误 | | 401xx | 认证/授权错误 | | 403xx | 权限不足 | | 404xx | 资源不存在 | | 500xx | 服务端内部错误 | ### 鉴权 所有业务接口走 JWT Bearer。客户端在 `Authorization: Bearer ` 头中携带访问令牌。 - 登录 `POST /api/usr/auth/login` 返回 `accessToken`(8 小时)+ `refreshToken`(7 天) - 临期前端用 refresh token 换新 access token:`POST /api/usr/auth/refresh` - 注销 `POST /api/usr/auth/logout` 服务端把 token 加入 Redis 吊销名单 - 未携带 / 过期 / 已吊销 → 401,对应错误码 `40101 未登录` / `40102 Token 已过期` / `40103 Token 已吊销` ### 分页参数 统一查询入参: | 字段 | 类型 | 必填 | 默认 | 说明 | |---|---|---|---|---| | `pageNum` | int | 否 | 1 | 当前页码,从 1 开始 | | `pageSize` | int | 否 | 20 | 每页条数;上限 100 | | `orderBy` | string | 否 | `tCreateDate DESC` | 排序表达式,列名 + 方向 | 响应包装: ```json { "code": 200, "message": "ok", "data": { "records": [ ... ], "total": 1234, "pageNum": 1, "pageSize": 20 }, "timestamp": 1700000000000 } ``` ## 接口清单 (各模块接口段落见下方,由 `downstream-gen` 按 REQ 填入) ## module_usr — USR 用户管理 ### REQ-USR-001 用户登录 - **Method**: POST - **Path**: `/api/usr/auth/login` - **Auth**: 公开(无需 JWT) - **请求**: ```json { "userName": "admin", "password": "P@ssw0rd", "companyVersion": "STANDARD" } ``` - `userName` (string, 必填, 3-50 位) - `password` (string, 必填, 明文传输,由 TLS 保证机密性;后端用 BCrypt/Argon2 比对哈希) - `companyVersion` (string, 必填, 枚举 `STANDARD` / `PRO` / `FLAGSHIP`) - **响应**: ```json { "code": 200, "message": "ok", "data": { "accessToken": "eyJ...", "refreshToken": "eyJ...", "expiresIn": 28800, "user": { "iIncrement": 1, "sUserName": "admin", "sUserType": "SUPER_ADMIN", "sLanguage": "zh-CN", "permissionCodes": ["USR:ADD", "USR:EDIT", "USR:DELETE", "USR:VIEW"] } }, "timestamp": 1700000000000 } ``` #### 错误码 - `40001` — 用户名或密码错误(不区分两者,防爆破) - `40301` — 账号已锁定,请稍后再试 - `40302` — 账号已作废 - `40010` — 参数校验失败(用户名 / 密码 / 版本字段为空或格式不合法) --- ### REQ-USR-002 新增用户 - **Method**: POST - **Path**: `/api/usr/users` - **Auth**: JWT;要求权限码 `USR:ADD` - **请求**: ```json { "userNo": "U10001", "userName": "zhangsan", "employeeId": 12, "userType": "NORMAL", "language": "zh-CN", "modifyDoc": false, "permissionIds": [3, 5, 8] } ``` - `userNo` / `userName` 必填且系统内唯一 - `employeeId` 可空(非员工账号) - `userType` 枚举 `NORMAL` / `SUPER_ADMIN`(仅超级管理员可创建超级管理员) - `language` 枚举 `zh-CN` / `en-US` / `zh-TW` - `permissionIds` 权限分类 ID 数组,可为空 - 初始密码后端固定生成(`666666`),不在请求体中 - **响应**: ```json { "code": 200, "message": "ok", "data": { "userNo": "U10001", "iIncrement": 42 }, "timestamp": 1700000000000 } ``` #### 错误码 - `40001` — 用户名 / 用户号已存在 - `40010` — 参数校验失败 - `40310` — 普通用户无权创建超级管理员 - `40411` — 关联职员不存在 - `40412` — 关联权限分类不存在 --- ### REQ-USR-003 修改用户 - **Method**: PUT - **Path**: `/api/usr/users/{iIncrement}` - **Auth**: JWT;要求权限码 `USR:EDIT` - **请求**: ```json { "employeeId": 12, "userType": "NORMAL", "language": "en-US", "modifyDoc": true, "void": false, "permissionIds": [3, 5] } ``` - `userName` 不可修改,故请求体不包含 - `void = true` 等价于禁用(软删除) - `permissionIds` 全量覆盖(先 DELETE 后 INSERT,事务内) - **响应**: ```json { "code": 200, "message": "ok", "data": { "iIncrement": 42 }, "timestamp": 1700000000000 } ``` #### 错误码 - `40404` — 目标用户不存在 - `40310` — 不可修改超级管理员(非超级管理员调用) - `40311` — 不可禁用 / 修改自己 - `40411` — 关联职员不存在 - `40412` — 关联权限分类不存在 - `40010` — 参数校验失败 --- ### REQ-USR-004 查询用户 - **Method**: GET - **Path**: `/api/usr/users` - **Auth**: JWT;要求权限码 `USR:VIEW` - **请求**: query string - `searchField` 枚举 `userName` / `employeeName` / `userNo` / `departmentName` / `userType` / `void` / `lastLoginDate` / `creator` - `matchMode` 枚举 `CONTAINS` / `NOT_CONTAINS` / `EQUALS` - `searchValue` 字符串,空则不过滤 - `includeVoid` 布尔,默认 false(不返回已作废用户) - `pageNum` / `pageSize` / `orderBy` 通用分页参数 - **响应**: 分页结构,`records[]` 元素: ```json { "iIncrement": 42, "sUserName": "zhangsan", "employeeName": "张三", "sUserNo": "U10001", "departmentName": "技术部", "sUserType": "NORMAL", "sLanguage": "zh-CN", "bVoid": false, "tLastLoginDate": "2026-05-13 09:12:33", "sCreator": "admin", "tCreateDate": "2025-12-01 10:00:00" } ``` - 不返回 `sPasswordHash` / `iLoginFailCount` / `tLockUntil` #### 错误码 - `40010` — 参数校验失败(`pageSize > 100` / `matchMode` 不合法 / `searchField` 不合法)