2. 文档的基本信息修改改用接口。 3. 重新完善角色权限管理的页面逻辑。 4.将评查点列表中的返回逻辑改用浏览器的记忆返回。
35 KiB
RBAC 权限管理前端对接文档
概述
本文档详细说明 RBAC(基于角色的访问控制)模块的所有 API 接口和业务逻辑,包括:
- 角色管理(5个接口)
- 权限管理(5个接口)
- 角色权限关联(4个接口)
- 用户角色管理(4个接口)
- 路由管理(3个接口)
总计:21个 API 接口
目录
核心概念
角色层级
| 角色 | role_key | 说明 | 数据范围 |
|---|---|---|---|
| 省级管理员 | provincial_admin |
最高权限,管理所有地区 | ALL |
| 市级管理员 | admin |
管理本地区用户 | DEPT |
| 普通员工 | common |
普通操作权限 | SELF |
数据范围 (data_scope)
| 值 | 说明 |
|---|---|
ALL |
全部数据(所有地区) |
DEPT |
部门数据(本地区) |
SELF |
个人数据(仅自己) |
权限类型 (permission_type)
| 值 | 说明 |
|---|---|
API |
API 接口权限 |
MENU |
菜单访问权限 |
BUTTON |
按钮操作权限 |
授权类型 (grant_type)
| 值 | 说明 |
|---|---|
GRANT |
授予权限 |
DENY |
拒绝权限 |
权限类型(独立/通用)
| 类型 | route_id | related_routes | 说明 |
|---|---|---|---|
| 独立权限 | 有值(如58) | NULL | 只属于单个页面 |
| 通用权限 | NULL | 有值(如[58,37]) | 被多个页面共享 |
关键数据表
| 表名 | 说明 |
|---|---|
roles |
角色定义表 |
permissions |
权限定义表 |
role_permissions |
角色-权限关联表 |
user_role |
用户-角色关联表 |
sys_routes |
前端路由配置表 |
sso_users |
用户信息表 |
rbac_audit_logs |
RBAC审计日志表 |
角色管理 API
1. 获取角色列表
请求
GET /api/v3/rbac/roles?page=1&page_size=20&role_name=&include_system=true
权限要求: 仅需登录(所有用户可访问,返回数据根据角色过滤)
Query 参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 1 | 页码 |
| page_size | int | 否 | 20 | 每页数量(1-100) |
| role_key | string | 否 | - | 角色标识精确过滤 |
| role_name | string | 否 | - | 角色名称模糊搜索 |
| include_system | bool | 否 | true | 是否包含系统角色 |
响应
{
"total": 10,
"page": 1,
"page_size": 20,
"items": [
{
"id": 1,
"role_key": "provincial_admin",
"role_name": "省级管理员",
"description": "系统最高权限管理员",
"data_scope": "ALL",
"is_system": true,
"user_count": 5,
"permission_count": 120,
"created_at": "2025-01-01T00:00:00",
"updated_at": "2025-01-01T00:00:00",
"metadata": null
},
{
"id": 2,
"role_key": "admin",
"role_name": "市级管理员",
"description": "地市级管理员",
"data_scope": "DEPT",
"is_system": true,
"user_count": 20,
"permission_count": 80,
"created_at": "2025-01-01T00:00:00",
"updated_at": "2025-01-01T00:00:00",
"metadata": null
}
]
}
业务逻辑
- 所有登录用户都可以查看角色列表
- 角色是全局统一的,不区分地区
- 返回数据包含用户数量和权限数量统计
2. 获取角色详情
请求
GET /api/v3/rbac/roles/{role_id}
权限要求: system:rbac:manage
Path 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| role_id | int | 是 | 角色ID |
响应
{
"id": 2,
"role_key": "admin",
"role_name": "市级管理员",
"description": "地市级管理员",
"data_scope": "DEPT",
"is_system": true,
"permissions": [
{
"id": 1,
"permission_id": 10,
"permission_key": "document:list:read",
"display_name": "查看文档列表",
"grant_type": "GRANT",
"data_scope": "DEPT"
},
{
"id": 2,
"permission_id": 11,
"permission_key": "document:detail:read",
"display_name": "查看文档详情",
"grant_type": "GRANT",
"data_scope": "DEPT"
}
],
"metadata": null,
"created_at": "2025-01-01T00:00:00",
"updated_at": "2025-01-01T00:00:00"
}
3. 创建角色
请求
POST /api/v3/rbac/roles
Content-Type: application/json
{
"role_key": "reviewer",
"role_name": "评查员",
"description": "负责文档评查工作",
"data_scope": "DEPT",
"metadata": {
"department": "评查部"
}
}
权限要求: system:rbac:manage
Request Body
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| role_key | string | 是 | 角色标识(唯一,只能包含小写字母、数字、下划线) |
| role_name | string | 是 | 角色名称 |
| description | string | 否 | 角色描述 |
| data_scope | string | 否 | 数据范围(ALL/DEPT/SELF,默认SELF) |
| metadata | object | 否 | 扩展元数据 |
响应
{
"id": 10,
"role_key": "reviewer",
"role_name": "评查员",
"description": "负责文档评查工作",
"data_scope": "DEPT",
"is_system": false,
"permissions": [],
"metadata": {"department": "评查部"},
"created_at": "2025-12-11T10:00:00",
"updated_at": "2025-12-11T10:00:00"
}
业务逻辑
role_key只能包含小写字母、数字、下划线,且必须以字母开头role_key必须唯一- 新创建的角色
is_system默认为false - 操作会记录到审计日志
4. 更新角色
请求
PUT /api/v3/rbac/roles/{role_id}
Content-Type: application/json
{
"role_name": "高级评查员",
"description": "负责高级文档评查工作",
"data_scope": "ALL"
}
权限要求: system:rbac:manage
Request Body(所有字段可选)
| 参数 | 类型 | 说明 |
|---|---|---|
| role_name | string | 角色名称 |
| description | string | 角色描述 |
| data_scope | string | 数据范围 |
| metadata | object | 扩展元数据 |
响应
{
"id": 10,
"role_key": "reviewer",
"role_name": "高级评查员",
"description": "负责高级文档评查工作",
"data_scope": "ALL",
"is_system": false,
"permissions": [],
"metadata": {"department": "评查部"},
"created_at": "2025-12-11T10:00:00",
"updated_at": "2025-12-11T11:00:00"
}
业务逻辑
role_key不可修改- 系统角色(
is_system=true)有额外限制 provincial_admin角色禁止修改data_scope- 操作会记录到审计日志
5. 删除角色
请求
DELETE /api/v3/rbac/roles/{role_id}?force=false
权限要求: system:rbac:manage
Query 参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| force | bool | 否 | false | 强制删除(自动解除用户关联) |
响应
{
"code": 200,
"message": "角色删除成功: 评查员",
"data": {
"role_id": 10,
"deleted_users": 5
}
}
业务逻辑
- 系统角色(
is_system=true)禁止删除 provincial_admin角色绝对禁止删除- 删除时自动解除用户关联、角色权限关联
- 操作会记录到审计日志
权限管理 API
1. 获取权限列表
请求
GET /api/v3/rbac/permissions?format=tree&module=&permission_type=&include_system=true
权限要求: system:rbac:manage
Query 参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| format | string | 否 | tree | 返回格式(tree/flat) |
| module | string | 否 | - | 按模块过滤 |
| permission_type | string | 否 | - | 权限类型过滤(API/MENU/BUTTON) |
| include_system | bool | 否 | true | 是否包含系统权限 |
响应(树形格式)
[
{
"id": 1,
"permission_key": "document:*:*",
"display_name": "文档管理",
"description": "文档管理模块全部权限",
"module": "document",
"resource": "*",
"action": "*",
"permission_type": "API",
"is_system": true,
"parent_id": null,
"sort_order": 0,
"children": [
{
"id": 2,
"permission_key": "document:list:read",
"display_name": "查看文档列表",
"module": "document",
"resource": "list",
"action": "read",
"permission_type": "API",
"is_system": false,
"parent_id": 1,
"sort_order": 0,
"children": []
}
]
}
]
业务逻辑
- 树形格式:按
parent_id构建层级结构 - 平铺格式:直接返回列表
2. 获取权限详情
请求
GET /api/v3/rbac/permissions/{permission_id}
权限要求: system:rbac:manage
响应
{
"id": 10,
"permission_key": "document:list:read",
"display_name": "查看文档列表",
"description": "允许查看文档列表",
"module": "document",
"resource": "list",
"action": "read",
"permission_type": "API",
"is_system": false,
"parent_id": 1,
"sort_order": 0,
"metadata": null,
"created_at": "2025-01-01T00:00:00",
"updated_at": "2025-01-01T00:00:00"
}
3. 创建权限
请求
POST /api/v3/rbac/permissions
Content-Type: application/json
{
"permission_key": "evaluation:result:export",
"display_name": "导出评查结果",
"description": "允许导出评查结果为Excel",
"module": "evaluation",
"resource": "result",
"action": "export",
"permission_type": "API",
"parent_id": null,
"sort_order": 10
}
权限要求: system:rbac:manage
Request Body
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| permission_key | string | 是 | 权限键(格式:module:resource:action) |
| display_name | string | 是 | 显示名称 |
| description | string | 否 | 权限描述 |
| module | string | 否 | 模块名(可从permission_key自动解析) |
| resource | string | 否 | 资源名(可从permission_key自动解析) |
| action | string | 否 | 操作名(可从permission_key自动解析) |
| permission_type | string | 否 | 权限类型(API/MENU/BUTTON,默认API) |
| parent_id | int | 否 | 父权限ID |
| sort_order | int | 否 | 排序顺序(默认0) |
| metadata | object | 否 | 扩展元数据 |
响应
{
"id": 100,
"permission_key": "evaluation:result:export",
"display_name": "导出评查结果",
"description": "允许导出评查结果为Excel",
"module": "evaluation",
"resource": "result",
"action": "export",
"permission_type": "API",
"is_system": false,
"parent_id": null,
"sort_order": 10,
"metadata": null,
"created_at": "2025-12-11T10:00:00",
"updated_at": "2025-12-11T10:00:00"
}
业务逻辑
permission_key格式必须是module:resource:actionpermission_key必须唯一- 如果包含通配符
*,自动标记为系统权限 - 如果指定
parent_id,必须指向存在的权限 - 操作会记录到审计日志
4. 更新权限
请求
PUT /api/v3/rbac/permissions/{permission_id}
Content-Type: application/json
{
"display_name": "导出评查结果(新)",
"description": "允许导出评查结果为Excel或PDF",
"sort_order": 5
}
权限要求: system:rbac:manage
Request Body(所有字段可选)
| 参数 | 类型 | 说明 |
|---|---|---|
| display_name | string | 显示名称 |
| description | string | 权限描述 |
| sort_order | int | 排序顺序 |
| metadata | object | 扩展元数据 |
业务逻辑
permission_key不可修改- 系统权限有额外限制
- 操作会记录到审计日志
5. 删除权限
请求
DELETE /api/v3/rbac/permissions/{permission_id}?force=false
权限要求: system:rbac:manage
Query 参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| force | bool | false | 强制删除(自动解除角色关联) |
响应
{
"code": 200,
"message": "权限删除成功: 导出评查结果",
"data": {
"permission_id": 100,
"deleted_role_relations": 3
}
}
业务逻辑
- 系统权限禁止删除
- 有子权限的权限禁止删除(必须先删除子权限)
force=false时,有角色关联则拒绝删除force=true时,自动解除角色关联后删除- 操作会记录到审计日志
角色权限关联 API
1. 获取角色的所有权限
请求
GET /api/v3/rbac/role-permissions?role_id=2
权限要求: system:rbac:manage
Query 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| role_id | int | 是 | 角色ID |
响应
{
"code": 200,
"message": "success",
"data": {
"role_id": 2,
"role_name": "市级管理员",
"role_key": "admin",
"permissions": [
{
"id": 1,
"permission_id": 10,
"permission_key": "document:list:read",
"display_name": "查看文档列表",
"module": "document",
"resource": "list",
"action": "read",
"permission_type": "API",
"grant_type": "GRANT",
"data_scope": "DEPT"
},
{
"id": 2,
"permission_id": 11,
"permission_key": "document:detail:read",
"display_name": "查看文档详情",
"module": "document",
"resource": "detail",
"action": "read",
"permission_type": "API",
"grant_type": "GRANT",
"data_scope": "DEPT"
}
]
}
}
2. 批量分配角色权限
请求
POST /api/v3/rbac/role-permissions
Content-Type: application/json
{
"role_id": 2,
"permissions": [
{"permission_id": 10, "grant_type": "GRANT", "data_scope": "DEPT"},
{"permission_id": 11, "grant_type": "GRANT", "data_scope": "DEPT"},
{"permission_id": 12, "grant_type": "DENY", "data_scope": null}
],
"replace": true
}
权限要求: system:rbac:manage
Request Body
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| role_id | int | 是 | 角色ID |
| permissions | array | 是 | 权限列表 |
| permissions[].permission_id | int | 是 | 权限ID |
| permissions[].grant_type | string | 是 | 授权类型(GRANT/DENY) |
| permissions[].data_scope | string | 否 | 数据范围(ALL/DEPT/SELF) |
| replace | bool | 否 | 替换模式(默认false) |
模式说明
replace=true: 替换全部权限(未在列表中的权限设为DENY)replace=false: 追加模式(保留现有权限,追加新权限)
响应
{
"code": 200,
"message": "成功替换权限",
"data": {
"role_id": 2,
"role_name": "市级管理员",
"assigned_count": 3,
"replace": true
}
}
业务逻辑
- 验证所有
permission_id必须存在 provincial_admin角色的核心权限不可移除(即使在replace模式下)- 核心权限:
system:rbac:manage、system:*:* - 操作会记录到审计日志
3. 更新单个角色权限
请求
PUT /api/v3/rbac/role-permissions?role_id=2&permission_id=10
Content-Type: application/json
{
"grant_type": "DENY",
"data_scope": "SELF"
}
权限要求: system:rbac:manage
Query 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| role_id | int | 是 | 角色ID |
| permission_id | int | 是 | 权限ID |
Request Body(至少提供一个)
| 参数 | 类型 | 说明 |
|---|---|---|
| grant_type | string | 授权类型(GRANT/DENY) |
| data_scope | string | 数据范围(ALL/DEPT/SELF) |
响应
{
"code": 200,
"message": "权限更新成功",
"data": {
"id": 1,
"role_id": 2,
"permission_id": 10,
"grant_type": "DENY",
"data_scope": "SELF"
}
}
4. 移除角色权限
请求
DELETE /api/v3/rbac/role-permissions?role_id=2&permission_id=10
权限要求: system:rbac:manage
Query 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| role_id | int | 是 | 角色ID |
| permission_id | int | 是 | 权限ID |
响应
{
"code": 200,
"message": "成功移除角色权限: 市级管理员 - 查看文档列表",
"data": {
"role_id": 2,
"permission_id": 10
}
}
业务逻辑
provincial_admin角色的核心权限不可移除- 核心权限列表:
system:rbac:manage、system:*:* - 操作会记录到审计日志
用户角色管理 API
1. 获取角色的所有用户
请求
GET /api/v3/rbac/roles/{role_id}/users?page=1&page_size=20&area=&username=
权限要求: 仅需登录(数据根据用户角色过滤)
Path 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| role_id | int | 是 | 角色ID |
Query 参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 1 | 页码 |
| page_size | int | 否 | 20 | 每页数量(1-100) |
| area | string | 否 | - | 按地区过滤 |
| username | string | 否 | - | 用户名模糊搜索 |
响应
{
"total": 20,
"page": 1,
"page_size": 20,
"items": [
{
"user_id": 100,
"username": "zhangsan",
"nick_name": "张三",
"area": "梅州",
"ou_name": "梅州市检察院",
"phone_number": "13800138000",
"email": "zhangsan@example.com",
"assigned_at": "2025-01-01T00:00:00"
}
]
}
业务逻辑
provincial_admin: 可查看所有地区用户admin: 只能查看同地区(area字段)的用户
2. 获取用户的所有角色
请求
GET /api/v3/rbac/users/{user_id}/roles
权限要求: system:rbac:manage
Path 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| user_id | int | 是 | 用户ID |
响应
{
"user_id": 100,
"username": "zhangsan",
"nick_name": "张三",
"roles": [
{
"role_id": 2,
"role_key": "admin",
"role_name": "市级管理员",
"data_scope": "DEPT",
"assigned_at": "2025-01-01T00:00:00"
}
]
}
3. 为用户分配角色
请求
POST /api/v3/rbac/users/{user_id}/roles
Content-Type: application/json
{
"role_ids": [2]
}
权限要求: system:rbac:manage
Path 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| user_id | int | 是 | 用户ID |
Request Body
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| role_ids | array | 是 | 角色ID列表 |
响应
{
"code": 200,
"message": "角色分配成功",
"data": {
"user_id": 100,
"username": "zhangsan",
"assigned_roles": [
{"role_id": 2, "role_name": "市级管理员"}
]
}
}
业务逻辑
- 一个用户只能拥有一个角色
- 如果用户已有角色,需要先移除再分配新角色
- 禁止给自己分配角色(防止自己提权)
admin只能给本地区用户分配角色admin不能分配provincial_admin或admin角色(只有省级管理员可以)- 操作会记录到审计日志
4. 移除用户角色
请求
DELETE /api/v3/rbac/users/{user_id}/roles/{role_id}
权限要求: system:rbac:manage
Path 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| user_id | int | 是 | 用户ID |
| role_id | int | 是 | 角色ID |
响应
{
"code": 200,
"message": "成功移除用户角色: zhangsan - 市级管理员",
"data": {
"user_id": 100,
"role_id": 2
}
}
业务逻辑
- 禁止移除自己的角色(防止自锁)
admin只能移除本地区用户的角色admin不能移除用户的provincial_admin或admin角色- 操作会记录到审计日志
路由管理 API
1. 获取所有路由列表
请求
GET /api/v3/routes?format=tree&include_hidden=false
权限要求: 仅需登录
Query 参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| format | string | 否 | tree | 返回格式(tree/flat) |
| include_hidden | bool | 否 | false | 是否包含隐藏路由 |
响应(树形格式)
[
{
"id": 2,
"route_path": "/documents",
"route_name": "Documents",
"route_title": "文件管理",
"component": "views/documents/index",
"parent_id": null,
"icon": "ri-file-list-line",
"sort_order": 1,
"is_hidden": false,
"is_cache": true,
"meta": null,
"status": 0,
"created_at": "2025-01-01T00:00:00",
"updated_at": "2025-01-01T00:00:00",
"children": [
{
"id": 58,
"route_path": "/reviews",
"route_name": "Reviews",
"route_title": "文档评查结果详情",
"parent_id": 2,
"children": null
}
]
}
]
2. 获取路由详情
请求
GET /api/v3/routes/{route_id}
权限要求: 仅需登录
响应
{
"id": 58,
"route_path": "/reviews",
"route_name": "Reviews",
"route_title": "文档评查结果详情",
"component": "views/reviews/index",
"parent_id": 2,
"icon": "ri-file-list-line",
"sort_order": 3,
"is_hidden": false,
"is_cache": true,
"meta": null,
"status": 0,
"created_at": "2025-01-01T00:00:00",
"updated_at": "2025-01-01T00:00:00"
}
3. 获取路由的所有权限(含通用权限)⭐核心接口
请求
GET /api/v3/routes/{route_id}/permissions
权限要求: 仅需登录
响应
{
"route_id": 58,
"route_path": "/reviews",
"route_title": "文档评查结果详情",
"permissions": [
{
"id": 82,
"permission_key": "evaluation_point:result:view",
"display_name": "查看评查结果",
"description": "查看评查结果详情",
"module": "evaluation_point",
"resource": "result",
"action": "view",
"permission_type": "API",
"route_id": 58,
"related_routes": null,
"api_path": "/api/postgrest/proxy/evaluation_results",
"api_method": "GET",
"is_system": false,
"sort_order": 0,
"is_shared": false
},
{
"id": 88,
"permission_key": "evaluation:audit_status:view",
"display_name": "查看审计状态",
"description": "查看审计状态(通用权限)",
"module": "evaluation",
"resource": "audit_status",
"action": "view",
"permission_type": "API",
"route_id": null,
"related_routes": [58, 37],
"api_path": "/api/postgrest/proxy/audit_status",
"api_method": "GET",
"is_system": false,
"sort_order": 0,
"is_shared": true
}
]
}
响应字段说明
| 字段 | 说明 |
|---|---|
route_id |
当前查询的路由ID |
route_path |
路由路径 |
route_title |
路由标题 |
permissions |
权限列表 |
permissions[].is_shared |
关键字段:true=通用权限,false=独立权限 |
permissions[].related_routes |
通用权限关联的所有路由ID |
业务逻辑
查询SQL逻辑:
SELECT * FROM permissions
WHERE route_id = {route_id} -- 独立权限
OR {route_id} = ANY(related_routes) -- 通用权限
ORDER BY
CASE WHEN related_routes IS NOT NULL THEN 1 ELSE 0 END,
sort_order, id
业务逻辑详解
1. 权限检查逻辑
后端权限检查只看 permission_key,与 route_id 无关:
SELECT p.permission_key
FROM role_permissions rp
JOIN permissions p ON rp.permission_id = p.id
WHERE rp.role_id = {user_role_id} AND rp.grant_type = 'GRANT'
2. 通用权限保存逻辑
- 通用权限在数据库中只有一条记录
- 保存时只需提交一次 permission_id
- 两个页面自动都会有该权限
// 正确:通用权限只提交一次
{
"permissions": [
{"permission_id": 88, "grant_type": "GRANT"} // 通用权限
]
}
// 错误:不需要为每个页面分别提交
{
"permissions": [
{"permission_id": 88, "grant_type": "GRANT", "route_id": 58}, // ❌ 不需要
{"permission_id": 88, "grant_type": "GRANT", "route_id": 37} // ❌ 不需要
]
}
3. 角色层级权限控制
| 操作 | provincial_admin | admin | common |
|---|---|---|---|
| 查看角色列表 | ✅ 全部 | ✅ 全部 | ✅ 全部 |
| 查看角色详情 | ✅ | ✅ | ❌ |
| 创建/修改/删除角色 | ✅ | ❌ | ❌ |
| 分配 provincial_admin 角色 | ✅ | ❌ | ❌ |
| 分配 admin 角色 | ✅ | ❌ | ❌ |
| 分配 common 角色 | ✅ | ✅(本地区) | ❌ |
| 查看用户列表 | ✅ 全部 | ✅ 本地区 | ❌ |
4. 核心权限保护
provincial_admin 角色的以下核心权限不可移除:
| 权限 | 说明 |
|---|---|
system:rbac:manage |
RBAC管理权限 |
system:*:* |
系统全部权限 |
5. 安全检查规则
| 规则 | 说明 |
|---|---|
| 禁止自操作 | 不能给自己分配/移除角色 |
| 地区隔离 | admin 只能操作本地区用户 |
| 权限升级限制 | 只有省级管理员可以分配管理员角色 |
| 系统保护 | 系统角色/权限禁止删除 |
| 关联检查 | 有子权限的权限禁止删除 |
6. 审计日志
所有写操作都会记录到 rbac_audit_logs 表:
| 操作类型 | 说明 |
|---|---|
| CREATE_ROLE | 创建角色 |
| UPDATE_ROLE | 更新角色 |
| DELETE_ROLE | 删除角色 |
| CREATE_PERMISSION | 创建权限 |
| UPDATE_PERMISSION | 更新权限 |
| DELETE_PERMISSION | 删除权限 |
| BATCH_ASSIGN_PERMISSION | 批量分配权限 |
| UPDATE_ROLE_PERMISSION | 更新角色权限 |
| REVOKE_ROLE_PERMISSION | 移除角色权限 |
| ASSIGN_USER_ROLE | 分配用户角色 |
| REVOKE_USER_ROLE | 移除用户角色 |
前端实现指南
1. 判断通用权限
// 使用后端返回的 is_shared 字段
function isSharedPermission(permission) {
return permission.is_shared === true;
}
2. 加载权限配置页面
async function loadPermissionConfigPage(roleId) {
// 1. 获取所有路由树
const routesRes = await fetch('/api/v3/routes?format=tree');
const routes = await routesRes.json();
// 2. 获取角色已有的权限
const rolePermRes = await fetch(`/api/v3/rbac/role-permissions?role_id=${roleId}`);
const rolePermissions = await rolePermRes.json();
const checkedIds = new Set(
rolePermissions.data.permissions
.filter(p => p.grant_type === 'GRANT')
.map(p => p.permission_id)
);
// 3. 为每个路由加载权限
for (const route of flattenRoutes(routes)) {
const permRes = await fetch(`/api/v3/routes/${route.id}/permissions`);
const permData = await permRes.json();
route.permissions = permData.permissions.map(p => ({
...p,
checked: checkedIds.has(p.id)
}));
}
return routes;
}
// 扁平化路由树
function flattenRoutes(routes, result = []) {
for (const route of routes) {
result.push(route);
if (route.children) {
flattenRoutes(route.children, result);
}
}
return result;
}
3. 处理通用权限勾选同步
// 权限勾选变化处理
function onPermissionCheck(permission, checked, allRoutes) {
// 更新当前权限的勾选状态
permission.checked = checked;
// 如果是通用权限,同步更新其他关联路由的显示
if (permission.is_shared && permission.related_routes) {
permission.related_routes.forEach(routeId => {
const route = findRouteById(allRoutes, routeId);
if (route && route.permissions) {
const samePerm = route.permissions.find(p => p.id === permission.id);
if (samePerm) {
samePerm.checked = checked;
}
}
});
}
}
4. 保存权限配置
async function saveRolePermissions(roleId, allRoutes) {
// 收集所有勾选的权限(去重,通用权限只收集一次)
const checkedPermissionIds = new Set();
flattenRoutes(allRoutes).forEach(route => {
if (route.permissions) {
route.permissions
.filter(p => p.checked)
.forEach(p => checkedPermissionIds.add(p.id));
}
});
// 构建请求数据
const requestData = {
role_id: roleId,
permissions: Array.from(checkedPermissionIds).map(id => ({
permission_id: id,
grant_type: 'GRANT',
data_scope: 'DEPT' // 根据业务需求设置
})),
replace: true
};
// 提交
const response = await fetch('/api/v3/rbac/role-permissions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestData)
});
return response.json();
}
5. UI 展示建议
function PermissionItem({ permission, onChange }) {
return (
<div className={`permission-item ${permission.is_shared ? 'shared' : ''}`}>
<Checkbox
checked={permission.checked}
onChange={(e) => onChange(permission, e.target.checked)}
/>
<span className="permission-name">
{permission.is_shared && <Tag color="blue">通用</Tag>}
{permission.display_name}
</span>
<span className="permission-api">
{permission.api_method} {permission.api_path}
</span>
{permission.is_shared && (
<Tooltip title={`此权限同时适用于路由: ${permission.related_routes.join(', ')}`}>
<InfoCircleOutlined />
</Tooltip>
)}
</div>
);
}
6. 样式参考
.permission-item {
display: flex;
align-items: center;
padding: 8px 12px;
border-bottom: 1px solid #f0f0f0;
}
.permission-item.shared {
background-color: #f0f7ff;
border-left: 3px solid #1890ff;
}
.permission-name {
flex: 1;
margin-left: 8px;
}
.permission-api {
color: #999;
font-size: 12px;
font-family: monospace;
}
API 接口汇总
角色管理(5个)
| 接口 | 方法 | 权限要求 | 说明 |
|---|---|---|---|
/api/v3/rbac/roles |
GET | 登录 | 获取角色列表 |
/api/v3/rbac/roles/{role_id} |
GET | system:rbac:manage | 获取角色详情 |
/api/v3/rbac/roles |
POST | system:rbac:manage | 创建角色 |
/api/v3/rbac/roles/{role_id} |
PUT | system:rbac:manage | 更新角色 |
/api/v3/rbac/roles/{role_id} |
DELETE | system:rbac:manage | 删除角色 |
权限管理(5个)
| 接口 | 方法 | 权限要求 | 说明 |
|---|---|---|---|
/api/v3/rbac/permissions |
GET | system:rbac:manage | 获取权限列表 |
/api/v3/rbac/permissions/{permission_id} |
GET | system:rbac:manage | 获取权限详情 |
/api/v3/rbac/permissions |
POST | system:rbac:manage | 创建权限 |
/api/v3/rbac/permissions/{permission_id} |
PUT | system:rbac:manage | 更新权限 |
/api/v3/rbac/permissions/{permission_id} |
DELETE | system:rbac:manage | 删除权限 |
角色权限关联(4个)
| 接口 | 方法 | 权限要求 | 说明 |
|---|---|---|---|
/api/v3/rbac/role-permissions |
GET | system:rbac:manage | 获取角色的所有权限 |
/api/v3/rbac/role-permissions |
POST | system:rbac:manage | 批量分配角色权限 |
/api/v3/rbac/role-permissions |
PUT | system:rbac:manage | 更新单个角色权限 |
/api/v3/rbac/role-permissions |
DELETE | system:rbac:manage | 移除角色权限 |
用户角色管理(4个)
| 接口 | 方法 | 权限要求 | 说明 |
|---|---|---|---|
/api/v3/rbac/roles/{role_id}/users |
GET | 登录 | 获取角色的所有用户 |
/api/v3/rbac/users/{user_id}/roles |
GET | system:rbac:manage | 获取用户的所有角色 |
/api/v3/rbac/users/{user_id}/roles |
POST | system:rbac:manage | 为用户分配角色 |
/api/v3/rbac/users/{user_id}/roles/{role_id} |
DELETE | system:rbac:manage | 移除用户角色 |
路由管理(3个)
| 接口 | 方法 | 权限要求 | 说明 |
|---|---|---|---|
/api/v3/routes |
GET | 登录 | 获取所有路由列表 |
/api/v3/routes/{route_id} |
GET | 登录 | 获取路由详情 |
/api/v3/routes/{route_id}/permissions |
GET | 登录 | 获取路由的所有权限(含通用权限) |
当前通用权限数据
| id | permission_key | display_name | related_routes |
|---|---|---|---|
| 88 | evaluation:audit_status:view | 查看审计状态 | [58, 37] |
| 89 | evaluation:audit_status:update | 更新审计状态 | [58, 37] |
| 136 | evaluation:result:update | 更新评查结果 | [58, 37] |
| 137 | evaluation:audit_status:create | 创建审核状态 | [58, 37] |
| 138 | evaluation:document:confirm | 确认文档审核完成 | [58, 37] |
关联的路由
| route_id | route_title | route_path |
|---|---|---|
| 58 | 文档评查结果详情 | /reviews |
| 37 | 评查结果 | /cross-checking/result |
更新记录
| 日期 | 版本 | 说明 |
|---|---|---|
| 2025-12-11 | 3.0 | 完整 RBAC 文档,包含 21 个 API 接口和详细业务逻辑 |
| 2025-12-11 | 2.0 | 使用 FastAPI 专用接口,删除 PostgREST 方式 |