# HYApp 管理后台权限管理功能文档 本文档作为后台管理系统权限管理的设计基准。以后后台相关文档统一放在 `hyapp-admin-server/docs/`。 ## 目标 后台权限采用 RBAC: - 用户通过角色获得权限,不直接给用户绑定权限。 - 菜单权限控制页面入口和前端路由访问。 - 按钮权限控制页面内操作按钮、批量操作、导出、状态变更等动作。 - 后端接口必须做权限校验,前端按钮隐藏或禁用只作为体验层控制。 - 权限码是前后端契约,不能只改文案或按钮,不同步后端权限码。 ## 当前实现事实 当前后端已经具备基础 RBAC 表: - `admin_users`:后台用户。 - `admin_roles`:后台角色。 - `admin_permissions`:权限定义,字段包含 `code`、`name`、`kind`。 - `admin_user_roles`:用户角色关系。 - `admin_role_permissions`:角色权限关系。 - `admin_menus`:菜单定义,通过 `permission_code` 绑定菜单查看权限。 当前认证链路: - 登录成功后,后端把用户权限码写入 access token。 - 前端 `AuthProvider` 保存 `permissions`,通过 `can(code)` 判断。 - 前端路由使用 `RequirePermission` 拦截页面。 - 后端 API 使用 `middleware.RequirePermission(code)` 校验。 当前注意点: - 角色权限变更后,旧 access token 内的权限不会立即变化;用户重新登录或 refresh 后才会获得新权限。若后续需要立即生效,需要增加 session 失效或 token version 机制。 - `platform-admin` 当前会绑定全部权限;其他预置角色需要补默认权限绑定策略。 - `菜单权限` 页面当前只读,没有菜单、权限定义的增删改能力。 ## 权限类型 权限 `kind` 使用以下值: | kind | 用途 | 示例 | | --- | --- | --- | | `menu` | 页面入口、路由访问、菜单展示 | `user:view` | | `button` | 页面按钮、批量操作、导出、状态变更 | `user:create` | | `api` | 独立接口权限。只有当接口不能自然归属到菜单或按钮时才使用 | `search:global` | 约定: - 普通页面查看权限统一使用 `模块:view`。 - 创建使用 `模块:create`。 - 编辑使用 `模块:update`。 - 删除使用 `模块:delete`。 - 导出使用 `模块:export`。 - 状态切换使用 `模块:status`。 - 批量操作如果风险高于单条操作,单独定义 `模块:batch-*`。 - 不再新增过宽的 `*:manage` 权限;当前已有 `role:manage` 可兼容保留,后续应拆到按钮级权限。 ## 后台基础权限矩阵 ### 总览 | 权限码 | kind | 控制范围 | 后端接口 | | --- | --- | --- | --- | | `overview:view` | `menu` | 总览页面、总览菜单 | `GET /api/v1/dashboard/overview` | 按钮: | 按钮 | 权限码 | 当前状态 | 目标 | | --- | --- | --- | --- | | 刷新 | `overview:view` | 已实现 | 查看总览即可刷新 | | 部署服务 | `service:create` | 按钮已展示但未接动作 | 跳转或打开服务创建抽屉 | ### 服务管理 | 权限码 | kind | 控制范围 | 后端接口 | | --- | --- | --- | --- | | `service:view` | `menu` | 服务管理菜单、列表、详情 | `GET /api/v1/services`、`GET /api/v1/services/:id` | | `service:create` | `button` | 创建服务、总览部署服务 | `POST /api/v1/services` | | `service:update` | `button` | 编辑服务基础信息、配置 | `PATCH /api/v1/services/:id` | | `service:operate` | `button` | 启动、停止、重启 | `PATCH /api/v1/services/:id/status`、`POST /api/v1/services/:id/restart` | 按钮: | 页面 | 按钮 | 权限码 | 当前状态 | 目标 | | --- | --- | --- | --- | --- | | 总览 | 部署服务 | `service:create` | 缺少动作 | 接入服务创建 | | 总览/服务管理 | 启动 | `service:operate` | 已按权限控制 | 保持 | | 总览/服务管理 | 停止 | `service:operate` | 已按权限控制 | 保持 | | 总览/服务管理 | 重启 | `service:operate` | 已按权限控制 | 保持 | | 服务管理 | 创建服务 | `service:create` | 已按权限控制 | 保持 | | 服务管理 | 编辑服务 | `service:update` | API 已有,页面未接 | 新增编辑入口 | | 服务管理 | 更多 | 按具体动作拆分 | 当前无实际动作 | 有动作后再展示 | ### 用户管理 | 权限码 | kind | 控制范围 | 后端接口 | | --- | --- | --- | --- | | `user:view` | `menu` | 用户管理菜单、列表、详情 | `GET /api/v1/users`、`GET /api/v1/users/:id` | | `user:create` | `button` | 新增后台用户 | `POST /api/v1/users` | | `user:update` | `button` | 编辑后台用户姓名、团队、MFA、角色 | `PATCH /api/v1/users/:id` | | `user:status` | `button` | 启用、停用、锁定、解锁、批量状态 | `PATCH /api/v1/users/:id/status`、`POST /api/v1/users/batch/status` | | `user:reset-password` | `button` | 重置后台用户密码 | `POST /api/v1/users/:id/reset-password` | | `user:export` | `button` | 导出后台用户 CSV | `GET /api/v1/users/export` | 按钮: | 按钮 | 权限码 | 当前状态 | 目标 | | --- | --- | --- | --- | | 新增用户 | `user:create` | 已按权限控制 | 保持 | | 编辑 | `user:update` | 已按权限控制 | 保持 | | 锁定/解锁 | `user:status` | 已按权限控制 | 保持 | | 启用/停用 | `user:status` | 已按权限控制 | 保持 | | 批量启用/停用 | `user:status` | 已按权限控制 | 后续可拆 `user:batch-status` | | 重置密码 | `user:reset-password` | 已按权限控制 | 保持 | | 导出 | `user:export` | 当前使用 `user:view`,前端按钮未单独控制 | 拆独立导出权限 | | 角色配置快捷入口 | `role:view` | 已按权限控制 | 保持 | ### 角色管理 当前后端使用 `role:view` 和 `role:manage`,目标需要拆细。 | 权限码 | kind | 控制范围 | 后端接口 | | --- | --- | --- | --- | | `role:view` | `menu` | 角色配置菜单、角色列表 | `GET /api/v1/roles` | | `permission:view` | `menu` | 权限定义列表 | `GET /api/v1/permissions` | | `role:create` | `button` | 新增角色 | `POST /api/v1/roles` | | `role:update` | `button` | 编辑角色名称、编码、说明 | `PATCH /api/v1/roles/:id` | | `role:delete` | `button` | 删除角色 | `DELETE /api/v1/roles/:id` | | `role:permission` | `button` | 配置角色权限 | `PUT /api/v1/roles/:id/permissions` | | `role:manage` | `button` | 兼容旧权限 | 当前已实现,后续拆分后保留迁移期 | 按钮: | 按钮 | 权限码 | 当前状态 | 目标 | | --- | --- | --- | --- | | 新增角色 | `role:create` | 当前使用 `role:manage` | 拆为 `role:create` | | 编辑角色 | `role:update` | 当前使用 `role:manage` | 拆为 `role:update` | | 删除角色 | `role:delete` | 当前使用 `role:manage` | 拆为 `role:delete` | | 勾选权限 | `role:permission` | 当前跟随编辑角色保存 | 拆为角色授权权限 | ### 菜单权限 当前页面只读,目标需要支持菜单树维护和权限定义查看。 | 权限码 | kind | 控制范围 | 后端接口 | | --- | --- | --- | --- | | `menu:view` | `menu` | 菜单权限页面、菜单树查看 | 当前用 `GET /api/v1/navigation/menus` | | `menu:create` | `button` | 新增菜单 | 待新增 | | `menu:update` | `button` | 编辑菜单标题、路由、图标、权限码 | 待新增 | | `menu:delete` | `button` | 删除菜单 | 待新增 | | `menu:sort` | `button` | 菜单排序 | 待新增 | | `menu:visible` | `button` | 菜单显示/隐藏 | 待新增 | | `permission:create` | `button` | 新增权限定义 | 待新增 | | `permission:update` | `button` | 编辑权限名称、类型、说明 | 待新增 | | `permission:delete` | `button` | 删除未绑定权限 | 待新增 | | `permission:sync` | `button` | 从代码或配置同步权限种子 | 待新增 | 按钮: | 按钮 | 权限码 | 当前状态 | 目标 | | --- | --- | --- | --- | | 新增菜单 | `menu:create` | 未实现 | 新增 | | 编辑菜单 | `menu:update` | 未实现 | 新增 | | 删除菜单 | `menu:delete` | 未实现 | 新增 | | 上移/下移 | `menu:sort` | 未实现 | 新增 | | 显示/隐藏 | `menu:visible` | 未实现 | 新增 | | 新增权限 | `permission:create` | 未实现 | 新增 | | 编辑权限 | `permission:update` | 未实现 | 新增 | | 删除权限 | `permission:delete` | 未实现 | 新增 | | 同步权限 | `permission:sync` | 未实现 | 新增 | ### 日志审计 | 权限码 | kind | 控制范围 | 后端接口 | | --- | --- | --- | --- | | `log:view` | `menu` | 登录日志、操作日志页面 | `GET /api/v1/logs/login`、`GET /api/v1/logs/operations` | | `log:export` | `button` | 导出日志 | 待新增 | 按钮: | 按钮 | 权限码 | 当前状态 | 目标 | | --- | --- | --- | --- | | 搜索 | `log:view` | 已实现 | 保持 | | 导出 | `log:export` | 未实现 | 新增 | | 查看详情 | `log:view` | 未实现 | 新增详情抽屉 | ### 通知中心 | 权限码 | kind | 控制范围 | 后端接口 | | --- | --- | --- | --- | | `notification:view` | `menu` | 通知中心页面、通知列表 | `GET /api/v1/notifications` | | `notification:read` | `button` | 单条标记已读 | `PATCH /api/v1/notifications/:id/read` | | `notification:read-all` | `button` | 批量已读 | 待新增 | | `notification:delete` | `button` | 删除通知 | 待新增 | 按钮: | 按钮 | 权限码 | 当前状态 | 目标 | | --- | --- | --- | --- | | 已读 | `notification:read` | 当前使用 `notification:view` | 拆独立权限 | | 全部已读 | `notification:read-all` | 未实现 | 新增 | | 删除 | `notification:delete` | 未实现 | 新增 | ### 个人账户 个人账户操作不走角色授权,登录用户默认可操作自己的会话和密码。 | 功能 | 权限 | 后端接口 | 当前状态 | | --- | --- | --- | --- | | 查看自己 | 登录态 | `GET /api/v1/auth/me` | 已实现 | | 修改自己的密码 | 登录态 | `POST /api/v1/auth/change-password` | API 已有,前端入口未实现 | | 退出登录 | 登录态 | `POST /api/v1/auth/logout` | 已实现 | ### 全局搜索 当前搜索接口为登录态可用:`GET /api/v1/search`。 目标: - 搜索结果必须按用户权限过滤。 - 没有 `service:view` 时不返回服务结果。 - 没有 `user:view` 时不返回用户结果。 - 没有 `role:view` 时不返回角色结果。 - 搜索结果跳转的目标页面必须有对应菜单权限。 ## App 业务后台权限预留 以下权限用于 App 业务管理模块。已接入默认菜单的模块由后台种子同步菜单、权限和平台管理员授权。 ### App 用户 | 权限码 | kind | 控制范围 | | --- | --- | --- | | `app-user:view` | `menu` | App 用户列表、详情 | | `app-user:update` | `button` | 修改用户资料 | | `app-user:status` | `button` | 后台封禁、解封 | | `app-user:password` | `button` | 后台设置 App 用户密码 | | `app-user:identity` | `button` | 短号、靓号管理 | | `app-user:country` | `button` | 国家/区域调整 | ### 国家和区域 | 权限码 | kind | 控制范围 | | --- | --- | --- | | `country:view` | `menu` | 国家列表 | | `country:create` | `button` | 新增国家 | | `country:update` | `button` | 编辑国家 | | `country:status` | `button` | 启用、停用国家 | | `region:view` | `menu` | 区域列表 | | `region:create` | `button` | 新增区域 | | `region:update` | `button` | 编辑区域 | | `region:status` | `button` | 停用区域 | | `region:countries` | `button` | 维护区域国家 | ### 房间管理 | 权限码 | kind | 控制范围 | | --- | --- | --- | | `room:view` | `menu` | 房间列表、详情、房间状态 | | `room:update` | `button` | 后台修改房间展示资料、模式、状态、区域 | | `room:delete` | `button` | 后台删除房间 | | `room:create` | `button` | 后台创建房间 | | `room:mic` | `button` | 上下麦、换麦、锁麦 | | `room:chat` | `button` | 公屏开关 | | `room:admin` | `button` | 设置房间管理员 | | `room:host-transfer` | `button` | 转移主持 | | `room:mute` | `button` | 禁言、解除禁言 | | `room:kick` | `button` | 踢出房间 | | `room:unban` | `button` | 房间解封用户 | ### 文件上传 | 权限码 | kind | 控制范围 | | --- | --- | --- | | `upload:create` | `button` | 后台上传文件、图片到 COS;object key 使用后台独立前缀 | ### 钱包和交易 | 权限码 | kind | 控制范围 | | --- | --- | --- | | `wallet:view` | `menu` | 钱包概览、余额查询 | | `wallet:transaction-view` | `menu` | 交易流水 | | `wallet:adjust` | `button` | 后台调账 | | `withdrawal:view` | `menu` | 提现记录 | | `withdrawal:review` | `button` | 提现审核 | | `withdrawal:export` | `button` | 提现导出 | ### 礼物和活动 | 权限码 | kind | 控制范围 | | --- | --- | --- | | `resource:view` | `menu` | 资源列表、资源详情 | | `resource:create` | `button` | 新增资源 | | `resource:update` | `button` | 编辑资源、启用、禁用 | | `resource-group:view` | `menu` | 资源组列表、资源组详情 | | `resource-group:create` | `button` | 新增资源组 | | `resource-group:update` | `button` | 编辑资源组、替换组成员、启用、禁用 | | `resource-grant:view` | `menu` | 资源赠送记录 | | `resource-grant:create` | `button` | 给用户赠送资源或资源组 | | `gift:view` | `menu` | 礼物列表 | | `gift:create` | `button` | 从资源库选择资源新增礼物 | | `gift:update` | `button` | 编辑礼物、资源绑定和价格 | | `gift:status` | `button` | 上架、下架 | | `activity:view` | `menu` | 活动列表 | | `activity:create` | `button` | 新增活动 | | `activity:update` | `button` | 编辑活动 | | `activity:status` | `button` | 发布、暂停、结束 | ### 主播、公会和 BD | 权限码 | kind | 控制范围 | | --- | --- | --- | | `host:view` | `menu` | 主播列表、主播资料 | | `host:update` | `button` | 编辑主播资料 | | `host:status` | `button` | 主播状态调整 | | `agency:view` | `menu` | 公会列表、详情 | | `agency:create` | `button` | 新增公会 | | `agency:update` | `button` | 编辑公会 | | `agency:status` | `button` | 关闭公会、开关入会 | | `bd:view` | `menu` | BD 列表 | | `bd:create` | `button` | 新增 BD | | `bd:update` | `button` | 编辑 BD | | `coin-seller:view` | `menu` | 币商列表、币商余额 | | `coin-seller:create` | `button` | 新增币商 | | `coin-seller:update` | `button` | 启用或禁用币商 | | `coin-seller:stock-credit` | `button` | 币商进货、金币补偿 | | `salary:view` | `menu` | 薪资周期、薪资明细 | | `salary:calculate` | `button` | 计算薪资 | | `salary:approve` | `button` | 审批薪资 | | `salary:post` | `button` | 入账薪资 | | `salary:void` | `button` | 作废薪资 | | `salary:adjust` | `button` | 调整薪资项 | ## 角色预设 ### 平台管理员 `platform-admin` - 拥有全部权限。 - 能维护用户、角色、权限、菜单和所有业务模块。 ### 运维管理员 `ops-admin` 建议权限: - `overview:view` - `service:view` - `service:create` - `service:update` - `service:operate` - `user:view` - `user:status` - `log:view` - `notification:view` - `notification:read` ### 审计员 `auditor` 建议权限: - `overview:view` - `log:view` - `user:view` - `role:view` - `permission:view` ### 只读用户 `readonly` 建议权限: - 所有已开放模块的 `*:view` - 不包含创建、更新、删除、导出、状态变更、重置密码、授权等按钮权限。 ## 前端落地规则 页面路由: - 路由必须配置菜单查看权限。 - 没有菜单权限时跳转到用户有权限的第一个页面;不能固定跳到无权限页面。 菜单: - 左侧菜单只展示当前用户拥有 `permission_code` 的菜单。 - 父菜单没有权限码时,只要存在可见子菜单即可展示。 - 父菜单没有可见子菜单时不展示。 按钮: - 危险操作按钮没有权限时不展示。 - 表格行内操作没有权限时不展示,必要时可以禁用但必须有明确状态。 - 批量操作必须同时检查权限和选中项。 - 导出按钮必须有独立导出权限。 搜索: - 搜索入口登录后可见。 - 搜索结果按权限过滤。 - 点击结果前仍由路由权限兜底。 ## 后端落地规则 接口: - 除登录、刷新、健康检查外,所有接口必须先通过认证。 - 每个写接口必须绑定按钮权限。 - 每个读接口必须绑定菜单查看权限或更细读权限。 - 批量、导出、重置密码、状态变更不能复用普通查看权限。 日志: - 创建、更新、删除、授权、状态变更、密码重置、导出、批量操作必须写操作日志。 - 操作日志需要记录操作者、资源、动作、结果、详情、IP、路径。 权限变更: - 角色权限保存后必须记录操作日志。 - 后续若要求立即生效,需要使相关用户 session 失效或提高 token version。 数据约束: - 权限 `code` 唯一。 - 菜单 `code` 唯一。 - 删除权限前必须确认没有角色绑定、没有菜单引用。 - 删除菜单前必须确认没有子菜单,或明确采用级联删除策略。 - 删除角色前必须确认没有用户绑定,或要求先解绑。 ## 需要补齐的接口 ### 权限定义 | 方法 | 路径 | 权限 | | --- | --- | --- | | `GET` | `/api/v1/permissions` | `permission:view` | | `POST` | `/api/v1/permissions` | `permission:create` | | `PATCH` | `/api/v1/permissions/:id` | `permission:update` | | `DELETE` | `/api/v1/permissions/:id` | `permission:delete` | | `POST` | `/api/v1/permissions/sync` | `permission:sync` | ### 菜单管理 | 方法 | 路径 | 权限 | | --- | --- | --- | | `GET` | `/api/v1/system/menus` | `menu:view` | | `POST` | `/api/v1/system/menus` | `menu:create` | | `PATCH` | `/api/v1/system/menus/:id` | `menu:update` | | `DELETE` | `/api/v1/system/menus/:id` | `menu:delete` | | `PATCH` | `/api/v1/system/menus/:id/visible` | `menu:visible` | | `PUT` | `/api/v1/system/menus/sort` | `menu:sort` | 说明: - `GET /api/v1/navigation/menus` 保留为当前用户菜单接口,只返回当前用户可见菜单。 - `GET /api/v1/system/menus` 是后台菜单维护接口,返回全量菜单树。 ### 角色权限 | 方法 | 路径 | 权限 | | --- | --- | --- | | `GET` | `/api/v1/roles` | `role:view` | | `POST` | `/api/v1/roles` | `role:create` | | `PATCH` | `/api/v1/roles/:id` | `role:update` | | `DELETE` | `/api/v1/roles/:id` | `role:delete` | | `PUT` | `/api/v1/roles/:id/permissions` | `role:permission` | ## 前端页面规划 ### 角色配置页 功能: - 角色列表。 - 新增角色。 - 编辑角色。 - 删除角色。 - 打开授权抽屉。 - 按模块、菜单、按钮分组勾选权限。 按钮权限: - 新增角色:`role:create` - 编辑角色:`role:update` - 删除角色:`role:delete` - 保存授权:`role:permission` ### 菜单权限页 功能: - 菜单树维护。 - 菜单绑定权限码。 - 菜单排序。 - 菜单显隐。 - 权限定义列表。 - 权限同步。 按钮权限: - 新增菜单:`menu:create` - 编辑菜单:`menu:update` - 删除菜单:`menu:delete` - 排序:`menu:sort` - 显隐:`menu:visible` - 新增权限:`permission:create` - 编辑权限:`permission:update` - 删除权限:`permission:delete` - 同步权限:`permission:sync` ### 用户管理页 功能: - 用户列表。 - 新增后台用户。 - 编辑后台用户。 - 绑定角色。 - 启用、停用、锁定、解锁。 - 重置密码。 - 导出。 按钮权限: - 新增用户:`user:create` - 编辑用户:`user:update` - 状态操作:`user:status` - 重置密码:`user:reset-password` - 导出:`user:export` ## 验收标准 - 无权限用户看不到对应菜单。 - 直接访问无权限路由会被拦截。 - 无按钮权限用户看不到对应操作按钮。 - 直接调用无权限接口返回 403。 - 角色授权保存后,用户重新登录或 refresh 后权限生效。 - 创建、更新、删除、授权、导出、批量和状态类操作都有操作日志。 - 全局搜索结果按当前用户权限过滤。 - `platform-admin` 拥有所有权限。 - `readonly` 只有查看权限,不能触发任何写操作。 ## 实施顺序 1. 拆分并补齐权限种子:新增 `permission:*`、`menu:*`、`role:create/update/delete/permission`、`user:export`、`notification:read/read-all/delete`、`log:export`。 2. 后端补权限定义和菜单管理接口。 3. 后端把现有接口从宽权限调整到按钮级权限。 4. 前端补角色授权抽屉和菜单权限页编辑能力。 5. 前端替换按钮权限码,导出、已读等动作不再复用查看权限。 6. 补默认角色权限绑定策略。 7. 补搜索结果权限过滤。 8. 补后端权限相关测试和前端构建验证。