13 KiB
后台管理 · RBAC 模块(管理员 / 角色 / 权限)
本文件描述
/api/admin/rbac下的后台 RBAC 管理(管理员、角色、权限)相关接口。公共约定(请求头、统一响应、鉴权中间件、错误码、配置)见 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 哈希存储。
请求体
{
"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 示例
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 |
每页条数。 |
响应
{
"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)。
请求体
{
"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)。
请求体
{ "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)。
请求体
{ "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 全局唯一。
请求体
{
"code": "editor",
"name": "编辑",
"description": "内容编辑角色",
"status": 1
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
code |
string | 是 | 角色标识,全局唯一;已存在返回 40900。 |
name |
string | 是 | 角色名称。 |
description |
string | 否 | 描述。 |
status |
int8 | 否 | 0 禁用,1 启用;缺省或 0 时置为 1;非法值返回 40000。 |
响应:返回创建后的 Role 对象(见 §2.2)。
curl 示例
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)。
请求体
{
"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)。
请求体
{ "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 全局唯一。
请求体
{
"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 示例
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)。
请求体
{
"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 §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,需手动执行)。 - 新增/修改上述接口时须同步更新本文档。