d4000cd292
2. 文档的基本信息修改改用接口。 3. 重新完善角色权限管理的页面逻辑。 4.将评查点列表中的返回逻辑改用浏览器的记忆返回。
1425 lines
35 KiB
Markdown
1425 lines
35 KiB
Markdown
# RBAC 权限管理前端对接文档
|
||
|
||
## 概述
|
||
|
||
本文档详细说明 RBAC(基于角色的访问控制)模块的所有 API 接口和业务逻辑,包括:
|
||
- 角色管理(5个接口)
|
||
- 权限管理(5个接口)
|
||
- 角色权限关联(4个接口)
|
||
- 用户角色管理(4个接口)
|
||
- 路由管理(3个接口)
|
||
|
||
**总计:21个 API 接口**
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [核心概念](#核心概念)
|
||
2. [角色管理 API](#角色管理-api)
|
||
3. [权限管理 API](#权限管理-api)
|
||
4. [角色权限关联 API](#角色权限关联-api)
|
||
5. [用户角色管理 API](#用户角色管理-api)
|
||
6. [路由管理 API](#路由管理-api)
|
||
7. [业务逻辑详解](#业务逻辑详解)
|
||
8. [前端实现指南](#前端实现指南)
|
||
|
||
---
|
||
|
||
## 核心概念
|
||
|
||
### 角色层级
|
||
|
||
| 角色 | 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. 获取角色列表
|
||
|
||
**请求**
|
||
```http
|
||
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 | 是否包含系统角色 |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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. 获取角色详情
|
||
|
||
**请求**
|
||
```http
|
||
GET /api/v3/rbac/roles/{role_id}
|
||
```
|
||
|
||
**权限要求**: `system:rbac:manage`
|
||
|
||
**Path 参数**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| role_id | int | 是 | 角色ID |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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. 创建角色
|
||
|
||
**请求**
|
||
```http
|
||
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 | 否 | 扩展元数据 |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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. 更新角色
|
||
|
||
**请求**
|
||
```http
|
||
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 | 扩展元数据 |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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. 删除角色
|
||
|
||
**请求**
|
||
```http
|
||
DELETE /api/v3/rbac/roles/{role_id}?force=false
|
||
```
|
||
|
||
**权限要求**: `system:rbac:manage`
|
||
|
||
**Query 参数**
|
||
|
||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| force | bool | 否 | false | 强制删除(自动解除用户关联) |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "角色删除成功: 评查员",
|
||
"data": {
|
||
"role_id": 10,
|
||
"deleted_users": 5
|
||
}
|
||
}
|
||
```
|
||
|
||
**业务逻辑**
|
||
- 系统角色(`is_system=true`)禁止删除
|
||
- `provincial_admin` 角色绝对禁止删除
|
||
- 删除时自动解除用户关联、角色权限关联
|
||
- 操作会记录到审计日志
|
||
|
||
---
|
||
|
||
## 权限管理 API
|
||
|
||
### 1. 获取权限列表
|
||
|
||
**请求**
|
||
```http
|
||
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 | 是否包含系统权限 |
|
||
|
||
**响应(树形格式)**
|
||
```json
|
||
[
|
||
{
|
||
"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. 获取权限详情
|
||
|
||
**请求**
|
||
```http
|
||
GET /api/v3/rbac/permissions/{permission_id}
|
||
```
|
||
|
||
**权限要求**: `system:rbac:manage`
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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. 创建权限
|
||
|
||
**请求**
|
||
```http
|
||
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 | 否 | 扩展元数据 |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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:action`
|
||
- `permission_key` 必须唯一
|
||
- 如果包含通配符 `*`,自动标记为系统权限
|
||
- 如果指定 `parent_id`,必须指向存在的权限
|
||
- 操作会记录到审计日志
|
||
|
||
---
|
||
|
||
### 4. 更新权限
|
||
|
||
**请求**
|
||
```http
|
||
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. 删除权限
|
||
|
||
**请求**
|
||
```http
|
||
DELETE /api/v3/rbac/permissions/{permission_id}?force=false
|
||
```
|
||
|
||
**权限要求**: `system:rbac:manage`
|
||
|
||
**Query 参数**
|
||
|
||
| 参数 | 类型 | 默认值 | 说明 |
|
||
|------|------|--------|------|
|
||
| force | bool | false | 强制删除(自动解除角色关联) |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "权限删除成功: 导出评查结果",
|
||
"data": {
|
||
"permission_id": 100,
|
||
"deleted_role_relations": 3
|
||
}
|
||
}
|
||
```
|
||
|
||
**业务逻辑**
|
||
- 系统权限禁止删除
|
||
- 有子权限的权限禁止删除(必须先删除子权限)
|
||
- `force=false` 时,有角色关联则拒绝删除
|
||
- `force=true` 时,自动解除角色关联后删除
|
||
- 操作会记录到审计日志
|
||
|
||
---
|
||
|
||
## 角色权限关联 API
|
||
|
||
### 1. 获取角色的所有权限
|
||
|
||
**请求**
|
||
```http
|
||
GET /api/v3/rbac/role-permissions?role_id=2
|
||
```
|
||
|
||
**权限要求**: `system:rbac:manage`
|
||
|
||
**Query 参数**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| role_id | int | 是 | 角色ID |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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. 批量分配角色权限
|
||
|
||
**请求**
|
||
```http
|
||
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`: 追加模式(保留现有权限,追加新权限)
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功替换权限",
|
||
"data": {
|
||
"role_id": 2,
|
||
"role_name": "市级管理员",
|
||
"assigned_count": 3,
|
||
"replace": true
|
||
}
|
||
}
|
||
```
|
||
|
||
**业务逻辑**
|
||
- 验证所有 `permission_id` 必须存在
|
||
- `provincial_admin` 角色的核心权限不可移除(即使在replace模式下)
|
||
- 核心权限:`system:rbac:manage`、`system:*:*`
|
||
- 操作会记录到审计日志
|
||
|
||
---
|
||
|
||
### 3. 更新单个角色权限
|
||
|
||
**请求**
|
||
```http
|
||
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) |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "权限更新成功",
|
||
"data": {
|
||
"id": 1,
|
||
"role_id": 2,
|
||
"permission_id": 10,
|
||
"grant_type": "DENY",
|
||
"data_scope": "SELF"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 移除角色权限
|
||
|
||
**请求**
|
||
```http
|
||
DELETE /api/v3/rbac/role-permissions?role_id=2&permission_id=10
|
||
```
|
||
|
||
**权限要求**: `system:rbac:manage`
|
||
|
||
**Query 参数**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| role_id | int | 是 | 角色ID |
|
||
| permission_id | int | 是 | 权限ID |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功移除角色权限: 市级管理员 - 查看文档列表",
|
||
"data": {
|
||
"role_id": 2,
|
||
"permission_id": 10
|
||
}
|
||
}
|
||
```
|
||
|
||
**业务逻辑**
|
||
- `provincial_admin` 角色的核心权限不可移除
|
||
- 核心权限列表:`system:rbac:manage`、`system:*:*`
|
||
- 操作会记录到审计日志
|
||
|
||
---
|
||
|
||
## 用户角色管理 API
|
||
|
||
### 1. 获取角色的所有用户
|
||
|
||
**请求**
|
||
```http
|
||
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 | 否 | - | 用户名模糊搜索 |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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. 获取用户的所有角色
|
||
|
||
**请求**
|
||
```http
|
||
GET /api/v3/rbac/users/{user_id}/roles
|
||
```
|
||
|
||
**权限要求**: `system:rbac:manage`
|
||
|
||
**Path 参数**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| user_id | int | 是 | 用户ID |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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. 为用户分配角色
|
||
|
||
**请求**
|
||
```http
|
||
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列表 |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "角色分配成功",
|
||
"data": {
|
||
"user_id": 100,
|
||
"username": "zhangsan",
|
||
"assigned_roles": [
|
||
{"role_id": 2, "role_name": "市级管理员"}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
**业务逻辑**
|
||
- 一个用户只能拥有一个角色
|
||
- 如果用户已有角色,需要先移除再分配新角色
|
||
- 禁止给自己分配角色(防止自己提权)
|
||
- `admin` 只能给本地区用户分配角色
|
||
- `admin` 不能分配 `provincial_admin` 或 `admin` 角色(只有省级管理员可以)
|
||
- 操作会记录到审计日志
|
||
|
||
---
|
||
|
||
### 4. 移除用户角色
|
||
|
||
**请求**
|
||
```http
|
||
DELETE /api/v3/rbac/users/{user_id}/roles/{role_id}
|
||
```
|
||
|
||
**权限要求**: `system:rbac:manage`
|
||
|
||
**Path 参数**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| user_id | int | 是 | 用户ID |
|
||
| role_id | int | 是 | 角色ID |
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功移除用户角色: zhangsan - 市级管理员",
|
||
"data": {
|
||
"user_id": 100,
|
||
"role_id": 2
|
||
}
|
||
}
|
||
```
|
||
|
||
**业务逻辑**
|
||
- 禁止移除自己的角色(防止自锁)
|
||
- `admin` 只能移除本地区用户的角色
|
||
- `admin` 不能移除用户的 `provincial_admin` 或 `admin` 角色
|
||
- 操作会记录到审计日志
|
||
|
||
---
|
||
|
||
## 路由管理 API
|
||
|
||
### 1. 获取所有路由列表
|
||
|
||
**请求**
|
||
```http
|
||
GET /api/v3/routes?format=tree&include_hidden=false
|
||
```
|
||
|
||
**权限要求**: 仅需登录
|
||
|
||
**Query 参数**
|
||
|
||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| format | string | 否 | tree | 返回格式(tree/flat) |
|
||
| include_hidden | bool | 否 | false | 是否包含隐藏路由 |
|
||
|
||
**响应(树形格式)**
|
||
```json
|
||
[
|
||
{
|
||
"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. 获取路由详情
|
||
|
||
**请求**
|
||
```http
|
||
GET /api/v3/routes/{route_id}
|
||
```
|
||
|
||
**权限要求**: 仅需登录
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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. 获取路由的所有权限(含通用权限)⭐核心接口
|
||
|
||
**请求**
|
||
```http
|
||
GET /api/v3/routes/{route_id}/permissions
|
||
```
|
||
|
||
**权限要求**: 仅需登录
|
||
|
||
**响应**
|
||
```json
|
||
{
|
||
"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逻辑:
|
||
```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` 无关:
|
||
|
||
```sql
|
||
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**
|
||
- 两个页面自动都会有该权限
|
||
|
||
```javascript
|
||
// 正确:通用权限只提交一次
|
||
{
|
||
"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. 判断通用权限
|
||
|
||
```javascript
|
||
// 使用后端返回的 is_shared 字段
|
||
function isSharedPermission(permission) {
|
||
return permission.is_shared === true;
|
||
}
|
||
```
|
||
|
||
### 2. 加载权限配置页面
|
||
|
||
```javascript
|
||
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. 处理通用权限勾选同步
|
||
|
||
```javascript
|
||
// 权限勾选变化处理
|
||
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. 保存权限配置
|
||
|
||
```javascript
|
||
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 展示建议
|
||
|
||
```jsx
|
||
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. 样式参考
|
||
|
||
```css
|
||
.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 方式 |
|