|
@@ -757,7 +757,20 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/auth/login — 产品端登录
|
|
#### POST /api/auth/login — 产品端登录
|
|
|
|
|
|
|
|
-**供产品后端调用**,超级管理员无法通过此接口登录。
|
|
|
|
|
|
|
+产品终端用户的统一登录入口。用户通过用户名密码 + 产品编码登录指定产品,登录成功后获得 JWT 令牌对和该用户在此产品下的权限列表。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **产品前端登录页**:用户在 CRM、OA 等业务系统的登录页面输入账号密码,前端调用此接口获取 token
|
|
|
|
|
+- **产品后端代理登录**:产品后端收到用户凭据后通过 HTTP 或 gRPC 调用此接口,将返回的 token 下发给客户端
|
|
|
|
|
+- **移动端 / 小程序登录**:移动客户端直接调用此接口完成产品侧身份认证
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:**
|
|
|
|
|
+
|
|
|
|
|
+- 超级管理员账号无法通过此接口登录(必须走 `/auth/adminLogin`),防止超管凭据在产品端暴露
|
|
|
|
|
+- 产品必须处于启用状态,否则拒绝登录
|
|
|
|
|
+- 用户必须是该产品的有效成员(`status=1`),且账号未冻结
|
|
|
|
|
+- 受 IP 维度限流保护,防止暴力破解;仅对已存在的用户名消耗限流配额
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
@@ -769,14 +782,25 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
| 字段 | 类型 | 说明 |
|
|
|
| ------ | ------ | ------ |
|
|
| ------ | ------ | ------ |
|
|
|
-| accessToken | string | 访问令牌 |
|
|
|
|
|
-| refreshToken | string | 刷新令牌 |
|
|
|
|
|
|
|
+| accessToken | string | 访问令牌(用于后续 API 调用,默认 2 小时有效) |
|
|
|
|
|
+| refreshToken | string | 刷新令牌(用于续期,默认 7 天有效) |
|
|
|
| expires | int64 | accessToken 过期时间(Unix 时间戳,秒) |
|
|
| expires | int64 | accessToken 过期时间(Unix 时间戳,秒) |
|
|
|
-| userInfo | object | 用户信息(含 perms 权限码数组) |
|
|
|
|
|
|
|
+| userInfo | object | 用户信息(含 `perms` 权限码数组,前端据此控制菜单/按钮显隐) |
|
|
|
|
|
|
|
|
#### POST /api/auth/adminLogin — 管理后台登录
|
|
#### POST /api/auth/adminLogin — 管理后台登录
|
|
|
|
|
|
|
|
-**仅供权限系统管理后台使用**,需要传入配置的 `managementKey` 进行身份验证。
|
|
|
|
|
|
|
+权限管理系统自身管理后台的登录入口。仅限超级管理员使用,必须额外提供 `managementKey` 验证身份。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **管理后台前端登录**:超级管理员在权限系统管理 UI 的登录页面输入账号密码 + managementKey
|
|
|
|
|
+- **运维脚本自动化**:运维人员通过脚本调用此接口获取超管 token,执行批量管理操作(如创建产品、批量建用户)
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:**
|
|
|
|
|
+
|
|
|
|
|
+- 必须传入与服务端配置一致的 `managementKey`,该密钥仅管理后台前端持有,不可泄露给产品端
|
|
|
|
|
+- `managementKey` 校验在限流之前执行,无效密钥不会消耗限流配额,防止 DoS 攻击
|
|
|
|
|
+- 受 IP 维度限流保护
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
@@ -784,30 +808,57 @@ Content-Type: application/json
|
|
|
| password | string | 是 | 密码 |
|
|
| password | string | 是 | 密码 |
|
|
|
| managementKey | string | 是 | 管理端密钥(配置文件中的 `Auth.ManagementKey`) |
|
|
| managementKey | string | 是 | 管理端密钥(配置文件中的 `Auth.ManagementKey`) |
|
|
|
|
|
|
|
|
-**响应 data:** 与产品端登录接口相同。登录后不携带产品上下文,token 中 `productCode` 和 `perms` 为空。
|
|
|
|
|
|
|
+**响应 data:** 与产品端登录接口相同。登录后不携带产品上下文,token 中 `productCode` 和 `perms` 为空。超管拥有所有产品的全部权限,不需要在 token 中枚举。
|
|
|
|
|
|
|
|
#### POST /api/auth/refreshToken — 刷新令牌
|
|
#### POST /api/auth/refreshToken — 刷新令牌
|
|
|
|
|
|
|
|
-通过 `Authorization: Bearer {refreshToken}` 请求头传入 refresh token。
|
|
|
|
|
|
|
+使用有效的 refreshToken 换取全新的令牌对。采用**令牌轮转**策略,每次刷新后旧令牌即时失效,确保单会话安全。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **accessToken 即将过期时自动续期**:前端在 accessToken 到期前(如提前 5 分钟)调用此接口,无感刷新用户会话
|
|
|
|
|
+- **accessToken 已过期后恢复会话**:前端收到 401 响应后,用 refreshToken 尝试换取新令牌,成功则重试原请求,失败则跳转登录
|
|
|
|
|
+- **切换产品上下文**:管理后台超管登录后,通过传入不同的 `productCode` 切换到特定产品的权限视角,获取该产品下的权限列表
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:**
|
|
|
|
|
+
|
|
|
|
|
+- 通过 `Authorization: Bearer {refreshToken}` 请求头传入,必须是 `tokenType=refresh` 的令牌
|
|
|
|
|
+- 每次刷新递增 `tokenVersion`,旧的 access/refresh 令牌即时失效——即使令牌被窃取,攻击者也只能用一次
|
|
|
|
|
+- 产品禁用时拒绝刷新,立即切断该产品下所有用户的会话
|
|
|
|
|
+- refreshToken 有固定有效期(默认 7 天),过期后必须重新登录
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| Authorization | header | 是 | `Bearer {refreshToken}` |
|
|
| Authorization | header | 是 | `Bearer {refreshToken}` |
|
|
|
| productCode | string | 否 | 切换产品上下文时传入(Body) |
|
|
| productCode | string | 否 | 切换产品上下文时传入(Body) |
|
|
|
|
|
|
|
|
-**响应 data:** 与登录接口相同。采用令牌轮转策略:每次刷新都会递增 `tokenVersion`,返回全新的 accessToken 和 refreshToken,旧令牌即时失效。refresh token 有固定有效期,过期后需重新登录。
|
|
|
|
|
|
|
+**响应 data:** 与登录接口相同,包含全新的 accessToken + refreshToken + userInfo。
|
|
|
|
|
|
|
|
#### POST /api/perm/sync — 同步产品权限
|
|
#### POST /api/perm/sync — 同步产品权限
|
|
|
|
|
|
|
|
-通过 appKey/appSecret 认证,产品后端上报全量权限列表。
|
|
|
|
|
|
|
+产品后端全量上报权限列表,系统自动对比差异执行新增、更新和禁用操作。这是产品权限声明的唯一入口,管理员无需手动创建权限。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **产品服务启动时自动同步**:产品后端在 main 函数中调用此接口,确保代码中新增或重命名的权限点自动注册到权限系统。推荐放在服务启动阶段(非请求链路),失败时 `log.Fatal` 终止启动
|
|
|
|
|
+- **CI/CD 部署流程中调用**:在产品部署脚本中调用此接口,确保新版本的权限定义在服务上线前就已同步
|
|
|
|
|
+- **权限定义热更新**:产品无需重启即可通过调用此接口更新权限列表(如通过管理接口触发)
|
|
|
|
|
+
|
|
|
|
|
+**处理逻辑:**
|
|
|
|
|
+
|
|
|
|
|
+- 列表中已存在的权限:按 `code` 匹配,更新 `name` 和 `remark`
|
|
|
|
|
+- 列表中新增的权限:自动创建
|
|
|
|
|
+- 数据库中有但列表中没有的权限:自动禁用(`status=2`),不删除——已绑定到角色的记录保留但权限计算时过滤
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:** 通过 `appKey`/`appSecret` 认证(非 JWT),无需登录,受 IP 维度限流保护
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| appKey | string | 是 | 产品接入密钥 |
|
|
| appKey | string | 是 | 产品接入密钥 |
|
|
|
| appSecret | string | 是 | 产品签名密钥 |
|
|
| appSecret | string | 是 | 产品签名密钥 |
|
|
|
-| perms | array | 是 | 权限列表 |
|
|
|
|
|
-| perms[].code | string | 是 | 权限码(如 `user:create`) |
|
|
|
|
|
-| perms[].name | string | 是 | 权限名 |
|
|
|
|
|
|
|
+| perms | array | 是 | 权限列表(全量,不在列表中的已有权限将被禁用) |
|
|
|
|
|
+| perms[].code | string | 是 | 权限码(如 `user:create`,产品内唯一) |
|
|
|
|
|
+| perms[].name | string | 是 | 权限名(用于管理后台展示) |
|
|
|
| perms[].remark | string | 否 | 备注 |
|
|
| perms[].remark | string | 否 | 备注 |
|
|
|
|
|
|
|
|
**响应 data:** `{"added": 3, "updated": 1, "disabled": 0}`
|
|
**响应 data:** `{"added": 3, "updated": 1, "disabled": 0}`
|
|
@@ -816,16 +867,43 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/auth/logout — 用户注销
|
|
#### POST /api/auth/logout — 用户注销
|
|
|
|
|
|
|
|
-无请求参数。递增当前用户的 `tokenVersion`,使所有已签发的 access/refresh 令牌立即失效,并清除用户缓存。
|
|
|
|
|
|
|
+主动吊销当前用户的所有已签发令牌,使其在所有设备/浏览器上立即失效。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **用户主动退出登录**:前端「退出登录」按钮点击后调用此接口,确保服务端即时吊销令牌(而非仅清理客户端本地存储)
|
|
|
|
|
+- **安全事件应急处置**:用户发现账号异常(如收到异地登录提醒),通过注销接口使所有设备上的令牌立即失效
|
|
|
|
|
+- **管理后台切换账号前**:超管在管理后台切换到其他账号前,先注销当前会话
|
|
|
|
|
|
|
|
-**响应 data:** `null`
|
|
|
|
|
|
|
+**处理逻辑:** 递增当前用户的 `tokenVersion`,所有持有旧版本的 access/refresh 令牌在下次使用时都会被拒绝;同时清除 UserDetailsLoader 缓存。
|
|
|
|
|
+
|
|
|
|
|
+无请求参数。**响应 data:** `null`
|
|
|
|
|
|
|
|
#### POST /api/auth/userInfo — 获取当前用户信息
|
|
#### POST /api/auth/userInfo — 获取当前用户信息
|
|
|
|
|
|
|
|
-无请求参数。**响应 data:** `UserInfo` 对象。
|
|
|
|
|
|
|
+返回当前登录用户的完整信息,包括基本资料、部门归属、产品成员身份和权限列表。数据来自 UserDetailsLoader 缓存。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **前端页面初始化**:用户刷新页面或首次加载时,前端调用此接口获取用户信息,渲染头像、昵称、菜单权限等
|
|
|
|
|
+- **前端权限刷新**:当管理员调整了用户的角色/权限后,前端可主动调用此接口重新获取最新权限列表,无需重新登录
|
|
|
|
|
+- **移动端个人中心**:展示用户头像、昵称、部门等个人资料
|
|
|
|
|
+- **前端权限守卫**:路由切换前调用此接口确认用户仍有有效会话及对应权限
|
|
|
|
|
+
|
|
|
|
|
+无请求参数。**响应 data:** `UserInfo` 对象(含 userId、username、nickname、avatar、email、phone、deptName、memberType、perms 等)。
|
|
|
|
|
|
|
|
#### POST /api/auth/changePassword — 修改密码
|
|
#### POST /api/auth/changePassword — 修改密码
|
|
|
|
|
|
|
|
|
|
+用户修改自己的登录密码。修改成功后递增 `tokenVersion`,所有已签发令牌即时失效,用户需重新登录。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **用户主动修改密码**:用户在个人设置页面修改密码
|
|
|
|
|
+- **首次登录强制改密**:管理员创建用户时设置了初始密码,用户首次登录后系统提示修改密码(前端检查 `mustChangePassword` 标志)
|
|
|
|
|
+- **密码泄露后重置**:用户怀疑密码泄露,通过修改密码使所有已签发令牌失效
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:** 必须验证原密码正确后才能修改;新密码需 6-72 字符且不能与旧密码相同。
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| oldPassword | string | 是 | 原密码 |
|
|
| oldPassword | string | 是 | 原密码 |
|
|
@@ -835,9 +913,18 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/product/create — 创建产品
|
|
#### POST /api/product/create — 创建产品
|
|
|
|
|
|
|
|
|
|
+为一个新的业务系统注册接入权限系统。创建后自动生成 `appKey`/`appSecret`(用于权限同步认证)和初始 ADMIN 管理员账号。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **新业务系统接入**:公司新开发了一个 CRM/OA/电商后台等系统,超管在管理后台创建产品,获取接入凭证交给产品开发团队
|
|
|
|
|
+- **多租户场景拓展**:SaaS 平台新增一个租户,通过创建产品实现权限隔离
|
|
|
|
|
+
|
|
|
|
|
+**注意事项:** 响应中的 `appKey`、`appSecret`、`adminUser`、`adminPassword` 仅在创建时返回一次,请立即保存。
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
-| code | string | 是 | 产品编码(全局唯一) |
|
|
|
|
|
|
|
+| code | string | 是 | 产品编码(全局唯一,仅允许字母/数字/下划线/中划线,不能以数字开头,上限 64 字符) |
|
|
|
| name | string | 是 | 产品名称 |
|
|
| name | string | 是 | 产品名称 |
|
|
|
| remark | string | 否 | 备注 |
|
|
| remark | string | 否 | 备注 |
|
|
|
|
|
|
|
@@ -845,6 +932,16 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/product/update — 更新产品
|
|
#### POST /api/product/update — 更新产品
|
|
|
|
|
|
|
|
|
|
+修改产品的名称、备注或启用/禁用状态。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **修改产品信息**:产品改名(如从「客户系统」改为「CRM 系统」)、补充备注说明
|
|
|
|
|
+- **禁用产品**:项目下线或暂停运营时,将产品状态设为禁用(`status=2`)。禁用后该产品下所有在线用户的令牌即时失效(JWT 中间件和 gRPC 接口均拦截),任何登录/刷新请求都将被拒绝
|
|
|
|
|
+- **重新启用产品**:暂停后恢复运营,将产品状态改回启用(`status=1`)
|
|
|
|
|
+
|
|
|
|
|
+**副作用:** 更新操作会清除该产品下所有用户的 UserDetailsLoader 缓存(`CleanByProduct`),确保状态变更即时生效。
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| id | int64 | 是 | 产品 ID |
|
|
| id | int64 | 是 | 产品 ID |
|
|
@@ -854,6 +951,14 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/product/list — 产品列表
|
|
#### POST /api/product/list — 产品列表
|
|
|
|
|
|
|
|
|
|
+分页查询所有已注册的产品。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **管理后台产品管理页面**:超管查看所有接入的产品列表,进行管理操作
|
|
|
|
|
+- **创建角色/成员时选择产品**:管理后台在创建角色、添加成员等操作时,需要先选择目标产品,此接口提供产品下拉列表数据
|
|
|
|
|
+- **运维监控面板**:展示当前系统管理的产品总数和各产品状态
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| page | int64 | 否 | 页码,默认 1 |
|
|
| page | int64 | 否 | 页码,默认 1 |
|
|
@@ -863,6 +968,13 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/product/detail — 产品详情
|
|
#### POST /api/product/detail — 产品详情
|
|
|
|
|
|
|
|
|
|
+查询单个产品的完整信息(含 `appKey`,不含 `appSecret`)。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **产品详情/编辑页面**:管理后台进入产品编辑页时,先调用此接口获取当前数据回填表单
|
|
|
|
|
+- **查看产品接入凭证**:超管需要查看某产品的 `appKey`(`appSecret` 仅创建时返回,此接口不包含)
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| id | int64 | 是 | 产品 ID |
|
|
| id | int64 | 是 | 产品 ID |
|
|
@@ -871,18 +983,37 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/dept/create — 创建部门
|
|
#### POST /api/dept/create — 创建部门
|
|
|
|
|
|
|
|
|
|
+在组织架构中新增一个部门节点。部门是全局概念,不隶属于任何产品。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **搭建组织架构**:公司初始化时创建一级部门(研发部、市场部、运营部),再创建子部门(前端组、后端组、测试组)
|
|
|
|
|
+- **组织调整新增部门**:公司扩张新增业务线或团队时,在对应的上级部门下创建新部门
|
|
|
|
|
+- **创建研发部门**:设置 `deptType=DEV` 的部门中的成员加入任何产品后自动拥有全部权限,适用于需要跨产品调试的研发团队
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| parentId | int64 | 是 | 父部门 ID,0 表示顶级部门 |
|
|
| parentId | int64 | 是 | 父部门 ID,0 表示顶级部门 |
|
|
|
| name | string | 是 | 部门名称 |
|
|
| name | string | 是 | 部门名称 |
|
|
|
-| sort | int64 | 否 | 排序值 |
|
|
|
|
|
-| deptType | string | 否 | `NORMAL`(默认)或 `DEV`(研发部门) |
|
|
|
|
|
|
|
+| sort | int64 | 否 | 排序值(同级部门间的排列顺序,数值越小越靠前) |
|
|
|
|
|
+| deptType | string | 否 | `NORMAL`(默认)或 `DEV`(研发部门,成员在产品中自动拥有全部权限) |
|
|
|
| remark | string | 否 | 备注 |
|
|
| remark | string | 否 | 备注 |
|
|
|
|
|
|
|
|
**响应 data:** `{"id": 1}`
|
|
**响应 data:** `{"id": 1}`
|
|
|
|
|
|
|
|
#### POST /api/dept/update — 更新部门
|
|
#### POST /api/dept/update — 更新部门
|
|
|
|
|
|
|
|
|
|
+修改部门名称、排序、类型或启禁用状态。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **部门更名**:组织调整时修改部门名称(如「技术部」改为「研发中心」)
|
|
|
|
|
+- **调整排序**:变更部门在同级中的显示顺序
|
|
|
|
|
+- **变更部门类型**:将普通部门升级为研发部门(`NORMAL` → `DEV`),或将研发部门降级为普通部门。类型变更立即影响该部门下所有用户在各产品中的权限
|
|
|
|
|
+- **禁用部门**:部门撤销时禁用,保留历史数据
|
|
|
|
|
+
|
|
|
|
|
+**副作用:** 更新操作会清除该部门下所有用户的 UserDetailsLoader 缓存,确保部门类型或状态变更即时反映到权限计算中。
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| id | int64 | 是 | 部门 ID |
|
|
| id | int64 | 是 | 部门 ID |
|
|
@@ -894,7 +1025,14 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/dept/delete — 删除部门
|
|
#### POST /api/dept/delete — 删除部门
|
|
|
|
|
|
|
|
-存在子部门时无法删除。
|
|
|
|
|
|
|
+永久删除一个部门。存在子部门时拒绝删除,必须先删除或迁移子部门。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **清理空部门**:组织架构调整后,将人员迁移到新部门后删除空的旧部门
|
|
|
|
|
+- **撤销误创建的部门**:部门创建有误时及时删除
|
|
|
|
|
+
|
|
|
|
|
+**约束:** 存在子部门时返回 400 错误,防止意外删除整个子树。删除前应先通过部门树接口确认该部门无子节点。
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
@@ -902,36 +1040,73 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/dept/tree — 部门树
|
|
#### POST /api/dept/tree — 部门树
|
|
|
|
|
|
|
|
-无请求参数。返回完整的部门树形结构(含 `children` 嵌套和 `deptType`)。
|
|
|
|
|
|
|
+返回完整的部门树形结构,包含所有层级的嵌套 `children` 和 `deptType` 标识。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **管理后台组织架构页面**:以树形控件展示公司完整的部门层级结构,支持展开/折叠
|
|
|
|
|
+- **用户创建/编辑时选择部门**:表单中的部门选择器(树形下拉)需要此接口提供数据源
|
|
|
|
|
+- **权限检查的辅助参考**:管理员查看部门层级关系,了解谁能管理谁(部门层级影响管理权限范围)
|
|
|
|
|
+
|
|
|
|
|
+无请求参数。
|
|
|
|
|
|
|
|
### 权限管理
|
|
### 权限管理
|
|
|
|
|
|
|
|
#### POST /api/perm/list — 权限列表
|
|
#### POST /api/perm/list — 权限列表
|
|
|
|
|
|
|
|
|
|
+分页查询指定产品下的所有权限定义。权限由产品后端通过 `/perm/sync` 自动上报,管理员无法手动创建或删除权限。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **角色绑定权限时选择权限**:管理后台在为角色分配权限时,需要先展示该产品下所有可用的权限列表(通常以穿梭框或复选列表形式)
|
|
|
|
|
+- **用户权限覆盖时选择权限**:管理后台在为用户设置 ALLOW/DENY 覆盖时,需要展示权限列表供选择
|
|
|
|
|
+- **权限审计**:管理员查看某产品当前注册了哪些权限,确认是否与代码中的定义一致
|
|
|
|
|
+- **排查权限同步结果**:产品部署后确认新增的权限是否已正确同步到系统中
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| productCode | string | 是 | 产品编码 |
|
|
| productCode | string | 是 | 产品编码 |
|
|
|
| page | int64 | 否 | 页码 |
|
|
| page | int64 | 否 | 页码 |
|
|
|
| pageSize | int64 | 否 | 每页条数 |
|
|
| pageSize | int64 | 否 | 每页条数 |
|
|
|
|
|
|
|
|
-**响应 data:** `{"total": N, "list": [PermItem...]}`
|
|
|
|
|
|
|
+**响应 data:** `{"total": N, "list": [PermItem...]}`(含 id、code、name、remark、status)
|
|
|
|
|
|
|
|
### 角色管理(超级管理员 或 产品管理员)
|
|
### 角色管理(超级管理员 或 产品管理员)
|
|
|
|
|
|
|
|
#### POST /api/role/create — 创建角色
|
|
#### POST /api/role/create — 创建角色
|
|
|
|
|
|
|
|
|
|
+在指定产品下创建一个新角色。角色是产品级概念,同名角色在不同产品中互不干扰。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **按岗位建立角色体系**:产品管理员根据业务需求创建角色,如「销售经理」「普通销售」「客服」「财务审批」
|
|
|
|
|
+- **按操作范围划分角色**:创建「只读角色」「编辑角色」「管理角色」等不同操作级别的角色
|
|
|
|
|
+- **新功能上线配套角色**:产品新增功能模块时,创建对应的角色(如新增报表模块时创建「报表管理员」角色)
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:** 产品必须处于启用状态;`permsLevel` 数值越小权限越高,用于同级成员间的管理权限比较。
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| productCode | string | 是 | 所属产品编码 |
|
|
| productCode | string | 是 | 所属产品编码 |
|
|
|
| name | string | 是 | 角色名(产品内唯一) |
|
|
| name | string | 是 | 角色名(产品内唯一) |
|
|
|
| remark | string | 否 | 备注 |
|
|
| remark | string | 否 | 备注 |
|
|
|
-| permsLevel | int64 | 是 | 权限等级 |
|
|
|
|
|
|
|
+| permsLevel | int64 | 是 | 权限等级(数值越小权限越高,用于管理权限判定) |
|
|
|
|
|
|
|
|
**响应 data:** `{"id": 1}`
|
|
**响应 data:** `{"id": 1}`
|
|
|
|
|
|
|
|
#### POST /api/role/update — 更新角色
|
|
#### POST /api/role/update — 更新角色
|
|
|
|
|
|
|
|
-非超级管理员不可降低角色的 `permsLevel`(即不可将数值改大)。
|
|
|
|
|
|
|
+修改角色名称、备注、权限等级或启禁用状态。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **调整角色名称和描述**:角色职责变化后更新名称和备注
|
|
|
|
|
+- **调整权限等级**:将角色的 `permsLevel` 调高或调低,影响该角色用户在管理权限检查中的级别
|
|
|
|
|
+- **禁用角色**:角色不再使用时禁用(`status=2`),已绑定该角色的用户在权限计算时将跳过该角色的权限
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:** 非超级管理员不可降低角色的 `permsLevel`(即不可将数值改大),防止产品管理员通过降低角色级别来提升自己的相对权限。
|
|
|
|
|
+
|
|
|
|
|
+**副作用:** 更新后自动清除所有绑定该角色的用户在该产品下的 UserDetailsLoader 缓存。
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
@@ -943,7 +1118,14 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/role/delete — 删除角色
|
|
#### POST /api/role/delete — 删除角色
|
|
|
|
|
|
|
|
-级联删除角色关联的权限绑定和用户绑定。
|
|
|
|
|
|
|
+永久删除一个角色,级联清理该角色的所有权限绑定(`sys_role_perm`)和用户绑定(`sys_user_role`)。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **清理废弃角色**:业务重构后旧角色不再需要,彻底删除以保持角色列表清洁
|
|
|
|
|
+- **合并角色**:将多个相似角色合并为一个时,先将用户迁移到新角色,再删除旧角色
|
|
|
|
|
+
|
|
|
|
|
+**副作用:** 删除前先查询所有绑定该角色的用户 ID 列表,删除后批量清除这些用户在该产品下的缓存,确保权限变更即时生效。
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
@@ -951,6 +1133,14 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/role/list — 角色列表
|
|
#### POST /api/role/list — 角色列表
|
|
|
|
|
|
|
|
|
|
+分页查询指定产品下的所有角色。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **管理后台角色管理页面**:展示产品下的角色列表,供管理员查看、编辑、删除
|
|
|
|
|
+- **用户绑定角色时选择角色**:管理后台在为用户分配角色时,需要展示该产品下的角色列表(通常以多选框或穿梭框形式)
|
|
|
|
|
+- **权限审计**:查看某产品下有哪些角色及其权限等级分布
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| productCode | string | 是 | 产品编码 |
|
|
| productCode | string | 是 | 产品编码 |
|
|
@@ -959,40 +1149,77 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/role/detail — 角色详情
|
|
#### POST /api/role/detail — 角色详情
|
|
|
|
|
|
|
|
-返回角色信息及绑定的权限 ID 列表(`permIds`)。
|
|
|
|
|
|
|
+查询单个角色的完整信息及其绑定的权限 ID 列表。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **角色编辑页面数据回填**:管理后台进入角色编辑页时,调用此接口获取角色信息和已绑定的权限列表回填表单
|
|
|
|
|
+- **查看角色权限配置**:管理员查看某角色具体拥有哪些权限,进行审计或排查
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| id | int64 | 是 | 角色 ID |
|
|
| id | int64 | 是 | 角色 ID |
|
|
|
|
|
|
|
|
|
|
+**响应 data:** 角色信息 + `permIds`(该角色绑定的权限 ID 数组)。
|
|
|
|
|
+
|
|
|
#### POST /api/role/bindPerms — 绑定角色权限
|
|
#### POST /api/role/bindPerms — 绑定角色权限
|
|
|
|
|
|
|
|
-全量替换该角色的权限。
|
|
|
|
|
|
|
+全量替换该角色绑定的权限列表。传入空数组清空所有绑定。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **初始化角色权限**:创建角色后为其配置初始权限集合
|
|
|
|
|
+- **调整角色权限范围**:业务变化时增减角色权限(如销售角色新增「导出报表」权限)
|
|
|
|
|
+- **权限收缩**:产品下线某功能时,从相关角色中移除对应权限
|
|
|
|
|
+- **清空角色权限**:传入空 `permIds` 数组可清除该角色的所有权限绑定
|
|
|
|
|
+
|
|
|
|
|
+**副作用:** 操作后自动清除所有绑定该角色的用户在该产品下的缓存,确保权限变更即时反映到在线用户。
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| roleId | int64 | 是 | 角色 ID |
|
|
| roleId | int64 | 是 | 角色 ID |
|
|
|
-| permIds | []int64 | 是 | 权限 ID 列表(空数组清空绑定) |
|
|
|
|
|
|
|
+| permIds | []int64 | 是 | 权限 ID 列表(全量替换,空数组清空绑定) |
|
|
|
|
|
|
|
|
### 用户管理
|
|
### 用户管理
|
|
|
|
|
|
|
|
#### POST /api/user/create — 创建用户(超级管理员 或 产品管理员)
|
|
#### POST /api/user/create — 创建用户(超级管理员 或 产品管理员)
|
|
|
|
|
|
|
|
|
|
+创建一个全局用户账号。用户是全局概念,创建后可通过「添加成员」接口加入多个产品。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **新员工入职**:HR 或管理员为新员工创建账号,设置初始密码,并归属到对应部门
|
|
|
|
|
+- **批量建立账号**:运维脚本遍历员工花名册,批量调用此接口创建用户账号
|
|
|
|
|
+- **外部协作人员**:为外包或合作伙伴创建账号(可不设 `deptId`),后续通过成员管理授予特定产品访问权
|
|
|
|
|
+
|
|
|
|
|
+**注意事项:** 创建用户后还需通过 `/member/add` 将其加入产品才能登录使用该产品。
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
-| username | string | 是 | 登录名(唯一) |
|
|
|
|
|
|
|
+| username | string | 是 | 登录名(全局唯一) |
|
|
|
| password | string | 是 | 密码(6-72 字符) |
|
|
| password | string | 是 | 密码(6-72 字符) |
|
|
|
| nickname | string | 否 | 昵称 |
|
|
| nickname | string | 否 | 昵称 |
|
|
|
| email | string | 否 | 邮箱(需合法格式) |
|
|
| email | string | 否 | 邮箱(需合法格式) |
|
|
|
| phone | string | 否 | 手机号(7-15 位数字,可含 `+` 前缀) |
|
|
| phone | string | 否 | 手机号(7-15 位数字,可含 `+` 前缀) |
|
|
|
| remark | string | 否 | 备注 |
|
|
| remark | string | 否 | 备注 |
|
|
|
-| deptId | int64 | 否 | 部门 ID |
|
|
|
|
|
|
|
+| deptId | int64 | 否 | 部门 ID(归属研发部门的用户加入产品后自动获得全部权限) |
|
|
|
|
|
|
|
|
**响应 data:** `{"id": 1}`
|
|
**响应 data:** `{"id": 1}`
|
|
|
|
|
|
|
|
#### POST /api/user/update — 更新用户(仅本人 或 超级管理员)
|
|
#### POST /api/user/update — 更新用户(仅本人 或 超级管理员)
|
|
|
|
|
|
|
|
-支持字段清空:传 `""` 清空字符串字段,传 `0` 清空 deptId,不传字段则不更新。
|
|
|
|
|
|
|
+修改用户个人信息(昵称、邮箱、手机、部门等)。使用乐观锁防止并发更新冲突。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **用户修改个人资料**:用户在个人设置页面更新昵称、邮箱、手机号
|
|
|
|
|
+- **超管调整用户部门**:组织架构调整时,超管将用户从一个部门转移到另一个部门(修改 `deptId`)。部门变更会影响权限——从研发部门转出的用户将失去自动全权限特权
|
|
|
|
|
+- **超管补充用户信息**:为缺失信息的用户补充邮箱、手机等联系方式
|
|
|
|
|
+- **取消部门归属**:传 `deptId=0` 将用户从部门中移出
|
|
|
|
|
+
|
|
|
|
|
+**字段更新规则:** 支持字段清空——传 `""` 清空字符串字段,传 `0` 清空 deptId,不传字段则不更新。
|
|
|
|
|
+
|
|
|
|
|
+**副作用:** 更新后清除该用户所有产品的 UserDetailsLoader 缓存。
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
@@ -1001,48 +1228,97 @@ Content-Type: application/json
|
|
|
| email | *string | 否 | 邮箱 |
|
|
| email | *string | 否 | 邮箱 |
|
|
|
| phone | *string | 否 | 手机号 |
|
|
| phone | *string | 否 | 手机号 |
|
|
|
| remark | *string | 否 | 备注 |
|
|
| remark | *string | 否 | 备注 |
|
|
|
-| deptId | *int64 | 否 | 部门 ID(传 0 取消部门) |
|
|
|
|
|
|
|
+| deptId | *int64 | 否 | 部门 ID(传 0 取消部门归属) |
|
|
|
| status | int64 | 否 | 状态 |
|
|
| status | int64 | 否 | 状态 |
|
|
|
|
|
|
|
|
#### POST /api/user/list — 用户列表
|
|
#### POST /api/user/list — 用户列表
|
|
|
|
|
|
|
|
|
|
+分页查询用户列表,可选传入产品编码以附带成员身份信息。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **管理后台用户管理页面**:展示所有用户列表,含基本信息和状态
|
|
|
|
|
+- **按产品筛选成员视角**:传入 `productCode` 时,列表中每个用户会附带其在该产品中的 `memberType`(ADMIN/DEVELOPER/MEMBER/空),方便管理员了解哪些用户已经是该产品的成员
|
|
|
|
|
+- **添加成员时选择用户**:管理后台在添加产品成员时,先查询用户列表让管理员选择要添加的用户
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
-| productCode | string | 否 | 产品编码(传入则附带成员类型) |
|
|
|
|
|
|
|
+| productCode | string | 否 | 产品编码(传入则每个用户附带在该产品中的成员类型) |
|
|
|
| page | int64 | 否 | 页码 |
|
|
| page | int64 | 否 | 页码 |
|
|
|
| pageSize | int64 | 否 | 每页条数 |
|
|
| pageSize | int64 | 否 | 每页条数 |
|
|
|
|
|
|
|
|
#### POST /api/user/detail — 用户详情
|
|
#### POST /api/user/detail — 用户详情
|
|
|
|
|
|
|
|
-返回用户信息及绑定的角色 ID 列表(`roleIds`)。
|
|
|
|
|
|
|
+查询单个用户的完整信息及其在当前产品下绑定的角色 ID 列表。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **用户编辑页面数据回填**:管理后台进入用户编辑页时,调用此接口获取用户信息回填表单
|
|
|
|
|
+- **查看用户角色配置**:管理员查看某用户当前绑定了哪些角色,评估权限是否合理
|
|
|
|
|
+- **用户权限排查**:当用户反馈无法访问某功能时,管理员通过此接口查看用户的角色绑定情况
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| id | int64 | 是 | 用户 ID |
|
|
| id | int64 | 是 | 用户 ID |
|
|
|
|
|
|
|
|
|
|
+**响应 data:** 用户信息 + `roleIds`(该用户在当前产品下绑定的角色 ID 数组)。
|
|
|
|
|
+
|
|
|
#### POST /api/user/bindRoles — 绑定用户角色(需管理权限)
|
|
#### POST /api/user/bindRoles — 绑定用户角色(需管理权限)
|
|
|
|
|
|
|
|
-需通过 `CheckManageAccess` 权限检查。全量替换该用户的角色。
|
|
|
|
|
|
|
+全量替换该用户在当前产品下的角色绑定。需通过 `CheckManageAccess` 权限检查。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **为新成员分配角色**:用户被添加为产品成员后,管理员为其分配一个或多个角色
|
|
|
|
|
+- **调整用户职责**:用户岗位变动时,更换其角色(如从「普通销售」升级为「销售经理」)
|
|
|
|
|
+- **多角色组合**:为用户同时分配多个角色以组合权限(如同时拥有「订单管理」和「报表查看」角色)
|
|
|
|
|
+- **清空角色**:传入空 `roleIds` 数组清除用户的所有角色绑定
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:** 操作者需要对目标用户有管理权限(通过 `CheckManageAccess` 校验超管/部门层级/权限级别);目标用户的成员状态必须启用。
|
|
|
|
|
+
|
|
|
|
|
+**副作用:** 操作后清除目标用户在该产品下的 UserDetailsLoader 缓存。
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| userId | int64 | 是 | 用户 ID |
|
|
| userId | int64 | 是 | 用户 ID |
|
|
|
-| roleIds | []int64 | 是 | 角色 ID 列表 |
|
|
|
|
|
|
|
+| roleIds | []int64 | 是 | 角色 ID 列表(全量替换) |
|
|
|
|
|
|
|
|
#### POST /api/user/setPerms — 设置用户权限覆盖(需管理权限)
|
|
#### POST /api/user/setPerms — 设置用户权限覆盖(需管理权限)
|
|
|
|
|
|
|
|
-需通过 `CheckManageAccess` 权限检查。全量替换用户级别的 ALLOW/DENY 权限覆盖。
|
|
|
|
|
|
|
+全量替换用户在当前产品下的个性化 ALLOW/DENY 权限覆盖。这是在角色权限基础上的微调机制。需通过 `CheckManageAccess` 权限检查。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **给个别用户额外授权**:用户的角色不包含某权限,但业务上需要临时或长期授予(如给李四额外授予「导出报表」权限),使用 `ALLOW`
|
|
|
|
|
+- **给个别用户限制权限**:用户的角色包含某权限,但需要对该用户个别禁止(如禁止实习生「删除客户」),使用 `DENY`
|
|
|
|
|
+- **组合 ALLOW 和 DENY**:同时为用户增加某些权限并限制某些权限,实现精细化控制
|
|
|
|
|
+- **清空所有覆盖**:传入空 `perms` 数组清除所有个性化覆盖,用户权限完全由角色决定
|
|
|
|
|
+
|
|
|
|
|
+**权限计算:** 最终权限 = (角色权限 ∪ ALLOW) - DENY。DENY 优先级最高。
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:** 目标用户的成员状态必须启用;产品必须处于启用状态。
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| userId | int64 | 是 | 用户 ID |
|
|
| userId | int64 | 是 | 用户 ID |
|
|
|
-| perms | array | 是 | 权限覆盖列表 |
|
|
|
|
|
|
|
+| perms | array | 是 | 权限覆盖列表(全量替换,空数组清除所有覆盖) |
|
|
|
| perms[].permId | int64 | 是 | 权限 ID |
|
|
| perms[].permId | int64 | 是 | 权限 ID |
|
|
|
-| perms[].effect | string | 是 | `ALLOW` 或 `DENY` |
|
|
|
|
|
|
|
+| perms[].effect | string | 是 | `ALLOW`(额外授予)或 `DENY`(强制拒绝) |
|
|
|
|
|
|
|
|
#### POST /api/user/updateStatus — 更新用户状态(需管理权限)
|
|
#### POST /api/user/updateStatus — 更新用户状态(需管理权限)
|
|
|
|
|
|
|
|
-需通过 `CheckManageAccess` 权限检查。不允许冻结自己和超级管理员。
|
|
|
|
|
|
|
+冻结或解冻用户账号。冻结后用户立即无法访问任何产品。需通过 `CheckManageAccess` 权限检查。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **员工离职冻结**:员工离职后冻结其账号,即时切断所有产品的访问权限(无需逐个产品移除成员)
|
|
|
|
|
+- **安全事件处置**:发现账号被盗用或存在违规行为时,紧急冻结账号
|
|
|
|
|
+- **临时停权**:员工休长假或处于考察期时临时冻结
|
|
|
|
|
+- **解冻恢复**:冻结原因消除后恢复账号,用户无需重新配置角色和权限
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:** 不允许冻结自己;不允许冻结超级管理员;需要对目标用户有管理权限。
|
|
|
|
|
+
|
|
|
|
|
+**副作用:** 状态变更后递增该用户的 `tokenVersion`(使所有已签发令牌失效)并清除缓存。
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
@@ -1053,19 +1329,47 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/member/add — 添加产品成员
|
|
#### POST /api/member/add — 添加产品成员
|
|
|
|
|
|
|
|
-需通过 `CheckManageAccess` + `CheckMemberTypeAssignment` 权限检查。不可分配与自己同级或更高级的成员类型。
|
|
|
|
|
|
|
+将一个已有用户添加为指定产品的成员,并指定成员类型。用户成为产品成员后才能登录该产品。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **新员工加入产品**:创建用户后,将其添加为 CRM/OA 等产品的成员,使其可以登录使用
|
|
|
|
|
+- **研发人员跨产品参与**:研发人员需要参与另一个产品的开发,将其添加为该产品的 MEMBER(因为归属研发部门,自动获得全部权限)
|
|
|
|
|
+- **提升为产品管理员**:将用户添加为 ADMIN 类型,使其拥有该产品下的角色/用户管理权限
|
|
|
|
|
+- **设置产品开发者**:将用户添加为 DEVELOPER 类型,使其自动拥有该产品的全部功能权限但不具备管理权限
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:**
|
|
|
|
|
+
|
|
|
|
|
+- 产品必须处于启用状态
|
|
|
|
|
+- 操作者不可分配与自己同级或更高级的成员类型(如 ADMIN 不能将他人设为 ADMIN)
|
|
|
|
|
+- 需通过 `CheckManageAccess` + `CheckMemberTypeAssignment` 权限检查
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| productCode | string | 是 | 产品编码 |
|
|
| productCode | string | 是 | 产品编码 |
|
|
|
| userId | int64 | 是 | 用户 ID |
|
|
| userId | int64 | 是 | 用户 ID |
|
|
|
-| memberType | string | 是 | `ADMIN` / `DEVELOPER` / `MEMBER` |
|
|
|
|
|
|
|
+| memberType | string | 是 | `ADMIN`(产品管理员)/ `DEVELOPER`(开发者,全权限)/ `MEMBER`(普通成员,按角色授权) |
|
|
|
|
|
|
|
|
**响应 data:** `{"id": 1}`
|
|
**响应 data:** `{"id": 1}`
|
|
|
|
|
|
|
|
#### POST /api/member/update — 更新成员
|
|
#### POST /api/member/update — 更新成员
|
|
|
|
|
|
|
|
-需通过 `CheckManageAccess` + `CheckMemberTypeAssignment` 权限检查。降级产品最后一个 ADMIN 时会被拒绝。
|
|
|
|
|
|
|
+修改成员类型或启禁用成员状态。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **成员升级**:将普通 MEMBER 提升为 DEVELOPER 或 ADMIN(如项目负责人变动)
|
|
|
|
|
+- **成员降级**:将 ADMIN 或 DEVELOPER 降级为 MEMBER(如不再负责管理工作)
|
|
|
|
|
+- **禁用成员**:临时禁止某成员访问产品,但保留成员关系和角色绑定(恢复时权限不变)
|
|
|
|
|
+- **恢复成员**:将禁用的成员重新启用
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:**
|
|
|
|
|
+
|
|
|
|
|
+- 不可降级产品最后一个活跃 ADMIN——系统保证每个产品至少有一个 ADMIN,防止产品进入无管理状态
|
|
|
|
|
+- 操作者不可将成员提升到与自己同级或更高的类型
|
|
|
|
|
+- 需通过 `CheckManageAccess` + `CheckMemberTypeAssignment` 权限检查
|
|
|
|
|
+
|
|
|
|
|
+**副作用:** 更新后清除该用户在该产品下的 UserDetailsLoader 缓存。
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
@@ -1075,7 +1379,20 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/member/remove — 移除成员
|
|
#### POST /api/member/remove — 移除成员
|
|
|
|
|
|
|
|
-需通过 `CheckManageAccess` 权限检查。不可移除产品最后一个 ADMIN。级联清理该成员在该产品下的角色绑定和权限覆盖。
|
|
|
|
|
|
|
+将成员从产品中移除。移除后用户无法再登录该产品,其在该产品下的所有角色绑定和权限覆盖被级联清理。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **员工不再参与某产品**:研发人员调岗不再负责 CRM 项目,从 CRM 产品成员中移除
|
|
|
|
|
+- **外部协作结束**:外包人员合同到期,从产品中移除其成员资格
|
|
|
|
|
+- **权限收紧**:安全审计后移除不应有权限的人员
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:**
|
|
|
|
|
+
|
|
|
|
|
+- 不可移除产品最后一个活跃 ADMIN——防止产品进入无管理状态
|
|
|
|
|
+- 需通过 `CheckManageAccess` 权限检查
|
|
|
|
|
+
|
|
|
|
|
+**级联清理:** 在事务内同时清理 `sys_user_role`(该用户在该产品下的角色绑定)和 `sys_user_perm`(该用户在该产品下的权限覆盖),然后删除成员记录并清除缓存。
|
|
|
|
|
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
@@ -1083,31 +1400,89 @@ Content-Type: application/json
|
|
|
|
|
|
|
|
#### POST /api/member/list — 成员列表
|
|
#### POST /api/member/list — 成员列表
|
|
|
|
|
|
|
|
|
|
+分页查询指定产品下的所有成员,含用户基本信息和成员类型/状态。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **管理后台成员管理页面**:展示产品下的所有成员列表,供管理员查看、编辑、移除
|
|
|
|
|
+- **成员权限概览**:管理员查看产品有哪些成员、各自是什么类型(ADMIN/DEVELOPER/MEMBER),评估权限分配是否合理
|
|
|
|
|
+- **成员数量统计**:了解产品的使用人数和成员构成
|
|
|
|
|
+
|
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| productCode | string | 是 | 产品编码 |
|
|
| productCode | string | 是 | 产品编码 |
|
|
|
| page | int64 | 否 | 页码 |
|
|
| page | int64 | 否 | 页码 |
|
|
|
| pageSize | int64 | 否 | 每页条数 |
|
|
| pageSize | int64 | 否 | 每页条数 |
|
|
|
|
|
|
|
|
-**响应 data:** `{"total": N, "list": [MemberItem...]}`
|
|
|
|
|
|
|
+**响应 data:** `{"total": N, "list": [MemberItem...]}`(含 userId、username、nickname、memberType、status 等)
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
## gRPC 接口文档
|
|
## gRPC 接口文档
|
|
|
|
|
|
|
|
-gRPC 服务定义见 `pb/perm.proto`,默认监听 `:10002`。
|
|
|
|
|
|
|
+gRPC 服务定义见 `pb/perm.proto`,默认监听 `:10002`。所有 gRPC 错误使用标准 `status.Error(codes.Xxx, msg)` 格式。
|
|
|
|
|
|
|
|
-| 方法 | 说明 | 使用场景 |
|
|
|
|
|
-| ------ | ------ | ---------- |
|
|
|
|
|
-| `SyncPermissions` | 同步产品权限列表 | 产品启动时调用,通过 appKey/appSecret 认证 |
|
|
|
|
|
-| `Login` | 产品端登录 | 产品后端代理用户登录(productCode 必传,超管被拒绝) |
|
|
|
|
|
-| `RefreshToken` | 刷新令牌(轮转) | accessToken 过期续期,旧令牌即时失效;产品禁用时拒绝 |
|
|
|
|
|
-| `VerifyToken` | 验证令牌 | 产品后端验证用户 token(可选,推荐本地 JWT 验证);产品禁用时拒绝 |
|
|
|
|
|
-| `GetUserPerms` | 获取用户权限 | 实时查询用户最新权限 |
|
|
|
|
|
|
|
+gRPC 接口主要面向**产品后端服务间调用**,相比 HTTP 接口具有更高性能和更强的类型安全。推荐 Go 项目通过 `permclient` 包直接调用。
|
|
|
|
|
+
|
|
|
|
|
+### SyncPermissions — 同步权限声明
|
|
|
|
|
+
|
|
|
|
|
+产品后端在启动阶段全量上报权限列表,与 HTTP 的 `/perm/sync` 功能等价。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **Go 微服务启动时自动同步**:在 `main` 函数中通过 gRPC 调用同步权限,相比 HTTP 调用减少序列化开销
|
|
|
|
|
+- **服务网格内部调用**:在 Kubernetes 等容器编排环境中,服务间直接通过 gRPC 通信,无需经过 HTTP 网关
|
|
|
|
|
+
|
|
|
|
|
+**认证方式:** 通过 `appKey`/`appSecret` 认证(与 HTTP 接口一致)。
|
|
|
|
|
+
|
|
|
|
|
+### Login — 产品端登录
|
|
|
|
|
+
|
|
|
|
|
+产品后端代理终端用户进行身份认证,返回 JWT 令牌对和权限列表。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **Go 后端代理登录**:产品的 Go 后端收到用户登录请求后,通过 gRPC 调用权限系统进行身份验证,将返回的令牌下发给前端。相比 HTTP 调用延迟更低
|
|
|
|
|
+- **服务间认证委托**:微服务架构中,网关服务通过 gRPC 调用权限系统完成用户认证
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:** `productCode` 必传;超级管理员被拒绝(必须走 adminLogin)。
|
|
|
|
|
+
|
|
|
|
|
+### RefreshToken — 刷新令牌(轮转)
|
|
|
|
|
+
|
|
|
|
|
+使用 refreshToken 换取全新令牌对,采用令牌轮转策略。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **Go 后端代理续期**:产品后端代替前端执行令牌刷新(如 BFF 模式下,后端持有 refreshToken 并管理令牌生命周期)
|
|
|
|
|
+- **长连接会话保活**:WebSocket 或长连接服务在 accessToken 即将过期时,通过 gRPC 刷新令牌维持会话
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:** 每次刷新递增 `tokenVersion`,旧令牌即时失效;产品禁用时返回 `codes.PermissionDenied`。
|
|
|
|
|
+
|
|
|
|
|
+### VerifyToken — 验证令牌
|
|
|
|
|
+
|
|
|
|
|
+服务端验证 accessToken 的有效性,返回用户信息和权限列表。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
+
|
|
|
|
|
+- **不支持本地 JWT 验证的语言/框架**:非 Go 语言的产品后端(如 Python、Node.js)可能未配置 JWT 密钥,通过 gRPC 调用权限系统进行服务端验证
|
|
|
|
|
+- **需要实时权限的场景**:本地 JWT 验证只能拿到签发时的权限快照;如果需要实时反映权限变更(如管理员刚修改了用户角色),可通过此接口获取最新权限
|
|
|
|
|
+- **关键操作的二次验证**:对敏感操作(如资金操作、数据删除),在本地 JWT 验证基础上再通过此接口做一次服务端校验,确保令牌未被吊销
|
|
|
|
|
+
|
|
|
|
|
+**推荐实践:** 常规场景推荐本地 JWT 验证(零网络开销);仅在上述特殊场景使用此接口。
|
|
|
|
|
+
|
|
|
|
|
+**安全约束:** 产品禁用时返回 `codes.PermissionDenied`。
|
|
|
|
|
+
|
|
|
|
|
+### GetUserPerms — 获取用户权限
|
|
|
|
|
+
|
|
|
|
|
+实时查询指定用户在指定产品下的最新权限码列表。
|
|
|
|
|
+
|
|
|
|
|
+**调用场景:**
|
|
|
|
|
|
|
|
-所有 gRPC 错误使用标准 `status.Error(codes.Xxx, msg)` 格式。
|
|
|
|
|
|
|
+- **实时权限网关**:API 网关在每次请求时通过 gRPC 查询用户最新权限,实现实时权限控制(适用于权限变更需要立即生效的高安全场景)
|
|
|
|
|
+- **后台任务权限校验**:异步任务/定时任务执行时,需要校验发起用户是否仍有执行权限
|
|
|
|
|
+- **权限缓存刷新**:产品后端自行维护权限缓存,定期通过此接口刷新,确保与权限系统保持一致
|
|
|
|
|
+- **管理后台权限预览**:管理员查看某用户在某产品下的实时权限,用于排查和审计
|
|
|
|
|
|
|
|
-Go 项目可直接引用 `permclient` 包:
|
|
|
|
|
|
|
+### Go SDK 使用示例
|
|
|
|
|
|
|
|
```go
|
|
```go
|
|
|
import "perms-system-server/permclient"
|
|
import "perms-system-server/permclient"
|
|
@@ -1117,6 +1492,7 @@ client, err := permclient.NewPermClient("perm-system:10002")
|
|
|
resp, err := client.SyncPermissions(ctx, &pb.SyncPermissionsReq{...})
|
|
resp, err := client.SyncPermissions(ctx, &pb.SyncPermissionsReq{...})
|
|
|
resp, err := client.Login(ctx, &pb.LoginReq{...})
|
|
resp, err := client.Login(ctx, &pb.LoginReq{...})
|
|
|
resp, err := client.VerifyToken(ctx, &pb.VerifyTokenReq{AccessToken: token})
|
|
resp, err := client.VerifyToken(ctx, &pb.VerifyTokenReq{AccessToken: token})
|
|
|
|
|
+resp, err := client.GetUserPerms(ctx, &pb.GetUserPermsReq{...})
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
---
|
|
---
|