451 lines
13 KiB
Markdown
451 lines
13 KiB
Markdown
# 后台管理 · RBAC 模块(管理员 / 角色 / 权限)
|
||
|
||
> 本文件描述 `/api/admin/rbac` 下的**后台 RBAC 管理**(管理员、角色、权限)相关接口。公共约定(请求头、统一响应、鉴权中间件、错误码、配置)见 [admin-api.md](./admin-api.md)。
|
||
|
||
## 1. 接口列表
|
||
|
||
所有接口均需登录后携带 `Authorization: Bearer <JWT>`(由 `AdminAuth` 校验),并经由 `PermissionLoader` 加载权限集合后,由路由守卫(`RequirePerm`)按权限 code 拦截:
|
||
|
||
| 资源 | 路由前缀 | 所需权限 code |
|
||
| --- | --- | --- |
|
||
| 管理员 | `/api/admin/rbac/admins` | `admin:manage` |
|
||
| 角色 | `/api/admin/rbac/roles` | `role:manage` |
|
||
| 权限 | `/api/admin/rbac/permissions` | `perm:manage` |
|
||
|
||
> 超级管理员角色(`super_admin`)对所有接口短路放行,无需逐条匹配权限。
|
||
|
||
状态枚举(`admin_users` / `admin_roles` 的 `status`):`0` 禁用,`1` 启用(默认 `1`)。
|
||
|
||
---
|
||
|
||
### 1.1 管理员接口(需 `admin:manage`)
|
||
|
||
#### 1.1.1 `POST /api/admin/rbac/admins`
|
||
|
||
新建管理员。用户名全局唯一,密码以 bcrypt 哈希存储。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"username": "alice",
|
||
"nickname": "Alice",
|
||
"password": "Admin@123456",
|
||
"status": 1
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `username` | string | 是 | 管理员账号,全局唯一。已存在返回 `40900`。 |
|
||
| `nickname` | string | 否 | 昵称。 |
|
||
| `password` | string | 是 | 明文密码,后端以 bcrypt 哈希存储。 |
|
||
| `status` | int8 | 否 | `0` 禁用,`1` 启用;缺省或 `0` 时置为 `1`;非法值返回 `40000`。 |
|
||
|
||
**响应**:返回创建后的 `User` 对象(见 §2.1),`password_hash` 不返回。
|
||
|
||
**curl 示例**
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/api/admin/rbac/admins \
|
||
-H "Authorization: Bearer <JWT>" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"username":"alice","password":"Admin@123456","status":1}'
|
||
```
|
||
|
||
#### 1.1.2 `GET /api/admin/rbac/admins`
|
||
|
||
分页查询管理员列表,支持按关键字与状态过滤。
|
||
|
||
**查询参数**
|
||
|
||
| 参数 | 类型 | 默认值 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `keyword` | string | 空 | 模糊匹配 `username` 或 `nickname`。 |
|
||
| `status` | int8 | `-1`(全部) | `0` 禁用,`1` 启用,`-1` 全部。 |
|
||
| `page` | int | `1` | 页码,从 1 开始。 |
|
||
| `size` | int | `20` | 每页条数。 |
|
||
|
||
**响应**
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"msg": "ok",
|
||
"data": {
|
||
"list": [
|
||
{
|
||
"id": 1,
|
||
"username": "alice",
|
||
"nickname": "Alice",
|
||
"status": 1,
|
||
"created_at": "2026-01-01T00:00:00Z",
|
||
"updated_at": "2026-01-01T00:00:00Z"
|
||
}
|
||
],
|
||
"total": 1,
|
||
"page": 1,
|
||
"size": 20
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 1.1.3 `GET /api/admin/rbac/admins/:id`
|
||
|
||
查询单个管理员。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**响应**:返回 `User` 对象;不存在返回 `40400`。
|
||
|
||
#### 1.1.4 `PUT /api/admin/rbac/admins/:id`
|
||
|
||
编辑管理员昵称 / 状态。字段以指针区分「未提供」与「置空」,全部为空时直接返回原记录。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"nickname": "新昵称",
|
||
"status": 0
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `nickname` | string | 否 | 昵称,提供即更新。 |
|
||
| `status` | int8 | 否 | `0` 禁用,`1` 启用;非法值返回 `40000`。 |
|
||
|
||
**响应**:返回更新后的 `User` 对象。
|
||
|
||
#### 1.1.5 `DELETE /api/admin/rbac/admins/:id`
|
||
|
||
删除管理员(同时清理其角色关联并失效权限缓存)。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**响应**:`{ "code": 0, "msg": "ok" }`。
|
||
|
||
#### 1.1.6 `POST /api/admin/rbac/admins/:id/roles`
|
||
|
||
为管理员分配角色(**全量替换**)。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{ "role_ids": [1, 2] }
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `role_ids` | []uint64 | 是(binding:`required`) | 角色 ID 列表,覆盖该管理员原有关联。 |
|
||
|
||
**响应**:`{ "code": 0, "msg": "ok" }`。
|
||
|
||
#### 1.1.7 `POST /api/admin/rbac/admins/:id/reset-pwd`
|
||
|
||
重置管理员密码。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{ "password": "New@123456" }
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `password` | string | 是(binding:`required`) | 新明文密码,后端以 bcrypt 哈希存储。 |
|
||
|
||
**响应**:`{ "code": 0, "msg": "ok" }`。
|
||
|
||
---
|
||
|
||
### 1.2 角色接口(需 `role:manage`)
|
||
|
||
#### 1.2.1 `POST /api/admin/rbac/roles`
|
||
|
||
新建角色。`code` 全局唯一。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"code": "editor",
|
||
"name": "编辑",
|
||
"description": "内容编辑角色",
|
||
"status": 1
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `code` | string | 是 | 角色标识,全局唯一;已存在返回 `40900`。 |
|
||
| `name` | string | 是 | 角色名称。 |
|
||
| `description` | string | 否 | 描述。 |
|
||
| `status` | int8 | 否 | `0` 禁用,`1` 启用;缺省或 `0` 时置为 `1`;非法值返回 `40000`。 |
|
||
|
||
**响应**:返回创建后的 `Role` 对象(见 §2.2)。
|
||
|
||
**curl 示例**
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/api/admin/rbac/roles \
|
||
-H "Authorization: Bearer <JWT>" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"code":"editor","name":"编辑","status":1}'
|
||
```
|
||
|
||
#### 1.2.2 `GET /api/admin/rbac/roles`
|
||
|
||
分页查询角色列表,支持按关键字与状态过滤。
|
||
|
||
**查询参数**
|
||
|
||
| 参数 | 类型 | 默认值 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `keyword` | string | 空 | 模糊匹配 `code` 或 `name`。 |
|
||
| `status` | int8 | `-1`(全部) | `0` 禁用,`1` 启用,`-1` 全部。 |
|
||
| `page` | int | `1` | 页码。 |
|
||
| `size` | int | `20` | 每页条数。 |
|
||
|
||
**响应**:`data` 为 `{ "list": [...Role], "total": N, "page": 1, "size": 20 }`。
|
||
|
||
#### 1.2.3 `GET /api/admin/rbac/roles/:id`
|
||
|
||
查询单个角色。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**响应**:返回 `Role` 对象;不存在返回 `40400`。
|
||
|
||
#### 1.2.4 `PUT /api/admin/rbac/roles/:id`
|
||
|
||
编辑角色。字段以指针区分「未提供」与「置空」,全部为空时直接返回原记录。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"name": "新名称",
|
||
"description": "新描述",
|
||
"status": 0
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `name` | string | 否 | 角色名称,提供即更新。 |
|
||
| `description` | string | 否 | 描述,提供即更新。 |
|
||
| `status` | int8 | 否 | `0` 禁用,`1` 启用;非法值返回 `40000`。 |
|
||
|
||
**响应**:返回更新后的 `Role` 对象。
|
||
|
||
#### 1.2.5 `DELETE /api/admin/rbac/roles/:id`
|
||
|
||
删除角色(清理关联并失效权限缓存)。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**响应**:`{ "code": 0, "msg": "ok" }`。
|
||
|
||
#### 1.2.6 `POST /api/admin/rbac/roles/:id/permissions`
|
||
|
||
为角色分配权限(**全量替换**)。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{ "permission_ids": [1, 2, 3] }
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `permission_ids` | []uint64 | 是(binding:`required`) | 权限 ID 列表,覆盖该角色原有关联。 |
|
||
|
||
**响应**:`{ "code": 0, "msg": "ok" }`。
|
||
|
||
---
|
||
|
||
### 1.3 权限接口(需 `perm:manage`)
|
||
|
||
权限分两类:`api`(接口权限,对应后端守卫 code)与 `menu`(菜单权限,用于前端动态渲染菜单树)。
|
||
|
||
#### 1.3.1 `POST /api/admin/rbac/permissions`
|
||
|
||
新建权限。`code` 全局唯一。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"code": "user:view",
|
||
"name": "用户查看",
|
||
"type": "api",
|
||
"method": "GET",
|
||
"path": "/api/admin/users",
|
||
"parent_id": 0,
|
||
"sort": 0
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `code` | string | 是 | 权限标识,全局唯一;已存在返回 `40900`。 |
|
||
| `name` | string | 是 | 权限名称。 |
|
||
| `type` | string | 是 | 权限类型:`api` 或 `menu`;非法值返回 `40000`。 |
|
||
| `method` | string | 否 | 接口方法(如 `GET`/`POST`),`type=api` 时建议填写。 |
|
||
| `path` | string | 否 | 接口路径或菜单路由;`type=api` 时建议填写。 |
|
||
| `parent_id` | uint64 | 否 | 父级权限 ID,菜单树用;`0` 表示顶级。 |
|
||
| `sort` | int | 否 | 排序号,菜单树用。 |
|
||
|
||
**响应**:返回创建后的 `Permission` 对象(见 §2.3)。
|
||
|
||
**curl 示例**
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/api/admin/rbac/permissions \
|
||
-H "Authorization: Bearer <JWT>" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"code":"user:view","name":"用户查看","type":"api","method":"GET","path":"/api/admin/users"}'
|
||
```
|
||
|
||
#### 1.3.2 `GET /api/admin/rbac/permissions`
|
||
|
||
分页查询权限列表,支持按类型与关键字过滤。
|
||
|
||
**查询参数**
|
||
|
||
| 参数 | 类型 | 默认值 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `type` | string | 空(全部) | `api` 或 `menu`;为空表示全部类型。 |
|
||
| `keyword` | string | 空 | 模糊匹配 `code` 或 `name`。 |
|
||
| `page` | int | `1` | 页码。 |
|
||
| `size` | int | `20` | 每页条数。 |
|
||
|
||
**响应**:`data` 为 `{ "list": [...Permission], "total": N, "page": 1, "size": 20 }`。
|
||
|
||
#### 1.3.3 `GET /api/admin/rbac/permissions/:id`
|
||
|
||
查询单个权限。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**响应**:返回 `Permission` 对象;不存在返回 `40400`。
|
||
|
||
#### 1.3.4 `PUT /api/admin/rbac/permissions/:id`
|
||
|
||
编辑权限。字段以指针区分「未提供」与「置空」,全部为空时直接返回原记录。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"name": "新名称",
|
||
"type": "menu",
|
||
"method": "GET",
|
||
"path": "/dashboard",
|
||
"parent_id": 0,
|
||
"sort": 1
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `name` | string | 否 | 名称,提供即更新。 |
|
||
| `type` | string | 否 | `api` 或 `menu`;非法值返回 `40000`。 |
|
||
| `method` | string | 否 | 接口方法,提供即更新。 |
|
||
| `path` | string | 否 | 路径/路由,提供即更新。 |
|
||
| `parent_id` | uint64 | 否 | 父级权限 ID,提供即更新。 |
|
||
| `sort` | int | 否 | 排序号,提供即更新。 |
|
||
|
||
**响应**:返回更新后的 `Permission` 对象。
|
||
|
||
#### 1.3.5 `DELETE /api/admin/rbac/permissions/:id`
|
||
|
||
删除权限(清理关联并失效权限缓存)。
|
||
|
||
**路径参数**:`id`(uint64)。
|
||
|
||
**响应**:`{ "code": 0, "msg": "ok" }`。
|
||
|
||
---
|
||
|
||
## 2. 数据模型
|
||
|
||
### 2.1 User(后台管理员)
|
||
|
||
| 字段 | 类型 | JSON | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `ID` | uint64 | `id` | 主键,自增。 |
|
||
| `Username` | string | `username` | 账号,全局唯一。 |
|
||
| `PasswordHash` | string | `password_hash` | **不返回**(json `-`)。 |
|
||
| `Nickname` | string | `nickname` | 昵称。 |
|
||
| `Status` | int8 | `status` | `0` 禁用,`1` 启用(默认 `1`)。 |
|
||
| `CreatedAt` | time | `created_at` | 创建时间。 |
|
||
| `UpdatedAt` | time | `updated_at` | 更新时间。 |
|
||
|
||
### 2.2 Role(角色)
|
||
|
||
| 字段 | 类型 | JSON | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `ID` | uint64 | `id` | 主键,自增。 |
|
||
| `Code` | string | `code` | 角色标识,全局唯一。 |
|
||
| `Name` | string | `name` | 角色名称。 |
|
||
| `Description` | string | `description` | 描述。 |
|
||
| `Status` | int8 | `status` | `0` 禁用,`1` 启用(默认 `1`)。 |
|
||
| `CreatedAt` | time | `created_at` | 创建时间。 |
|
||
| `UpdatedAt` | time | `updated_at` | 更新时间。 |
|
||
|
||
### 2.3 Permission(权限)
|
||
|
||
| 字段 | 类型 | JSON | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `ID` | uint64 | `id` | 主键,自增。 |
|
||
| `Code` | string | `code` | 权限标识,全局唯一。 |
|
||
| `Name` | string | `name` | 权限名称。 |
|
||
| `Type` | string | `type` | `api`(接口)或 `menu`(菜单)。 |
|
||
| `Method` | string | `method` | 接口方法(如 `GET`)。 |
|
||
| `Path` | string | `path` | 接口路径或菜单路由。 |
|
||
| `ParentID` | uint64 | `parent_id` | 父级权限 ID(`0` 为顶级)。 |
|
||
| `Sort` | int | `sort` | 排序号(菜单树用)。 |
|
||
| `CreatedAt` | time | `created_at` | 创建时间。 |
|
||
|
||
### 2.4 关联中间表
|
||
|
||
| 表名 | 字段 | 说明 |
|
||
| --- | --- | --- |
|
||
| `admin_user_roles` | `admin_id`, `role_id` | 管理员-角色多对多。 |
|
||
| `admin_role_permissions` | `role_id`, `permission_id` | 角色-权限多对多。 |
|
||
|
||
---
|
||
|
||
## 3. 补充错误码
|
||
|
||
除 [admin-api.md](./admin-api.md) §2.4 所列错误码外,RBAC 模块额外使用:
|
||
|
||
| 业务码 | 含义 |
|
||
| --- | --- |
|
||
| `40900` | 资源冲突(用户名已存在 / 角色 `code` 已存在 / 权限 `code` 已存在)。 |
|
||
|
||
> 资源不存在统一返回 `40400`;状态/类型等非法枚举统一返回 `40000`。
|
||
|
||
## 4. 备注
|
||
|
||
- **权限守卫**:RBAC 管理接口自身受 `RequirePerm` 守卫(见 §1 表),需调用方具备对应权限 `code`;`super_admin` 角色短路放行。权限 `code` 常量定义见 `internal/middleware/permission.go`(`PermAdminManage` / `PermRoleManage` / `PermPermManage`)。
|
||
- **缓存失效**:新建/编辑/删除管理员、角色、权限,或调整角色-权限、管理员-角色关联后,会失效对应权限缓存(`PermissionProvider` 的 `Load`/`MenuTree` 优先走缓存),下次请求重新加载。
|
||
- **种子初始化**:服务启动时由 `provider.Seed` 用环境变量 `ADMIN_SEED_USERNAME` / `ADMIN_SEED_PASSWORD`(缺省 `admin` / `Admin@123456`)初始化首个管理员,详见 `internal/router/router.go`。
|
||
- **建表脚本**:RBAC 相关表结构见 `scripts/001_rbac.sql`(项目未开启 AutoMigrate,需手动执行)。
|
||
- 新增/修改上述接口时须同步更新本文档。
|