# 后台管理 · RBAC 模块(管理员 / 角色 / 权限) > 本文件描述 `/api/admin/rbac` 下的**后台 RBAC 管理**(管理员、角色、权限)相关接口。公共约定(请求头、统一响应、鉴权中间件、错误码、配置)见 [admin-api.md](./admin-api.md)。 ## 1. 接口列表 所有接口均需登录后携带 `Authorization: Bearer `(由 `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 " \ -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 " \ -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 " \ -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,需手动执行)。 - 新增/修改上述接口时须同步更新本文档。