# Web 管理端权限系统设计 **日期:** 2026-06-20 **状态:** 设计稿 ## 1. 目标 将 Web 管理端从单角色互斥权限模式(`v-if="isPlanner"/v-else-if="isVendor"/v-else`)升级为多角色权限合并模式,支持以下角色: | 角色 | 标识 | 职责 | |------|------|------| | 管理员 | `admin` | 系统全功能管理 | | 成长规划师 | `teacher` | 家庭教育相关服务 | | 营养师 | `nutritionist` | 家庭健康相关服务 | | 文章管理员 | `article_manager` | 文章内容管理 | | 活动管理员 | `activity_manager` | 活动发布和管理 | **核心约束:** 一个用户可以拥有多个角色(如同时是营养师 + 文章管理员),其有效权限为所有角色权限的并集。 ## 2. 现有状态分析 ### 2.1 后端现状 - `User` 实体已有 `roles` 字段(JSON 数组格式,支持多角色存储) - `UserService.hasRole()` 已支持解析多角色 - 但 JWT 只存单 `role` 字段,登录仅返回单角色 - 后端 Controller 对应关系: - `GrowthRecordController` / `GrowthPlanController` — `/api/growth/*`(成长档案) - `HealthReportController` — `/api/health/*`(健康报告) - `HealthCheckinController` — `/api/health/checkin/*`(健康打卡) - `ActivityController` — `/api/activity/*`(活动管理) - 其余管理端 API 均可用 ### 2.2 前端现状 - **Layout.vue:** 三选一互斥分支(`v-if="isPlanner"` / `v-else-if="isVendor"` / `v-else`) - **Router:** 硬编码 `teacherRoutes` / `adminRoutes` 名单判断 - **认证:** `localStorage` 存单 `role` 字段 - **现有页面:** 文章管理页面已有;成长档案/健康档案/活动管理页面需新建 ### 2.3 需新建的前端页面 | 页面 | 路径 | 对应角色 | 后端 API | |------|------|---------|---------| | 我的家庭 | `/my-families` | teacher, nutritionist | 现有 `/api/guide/*` | | 成长记录 | `/growth-records` | teacher | `GrowthRecordController` | | 成长计划 | `/growth-plans` | teacher | `GrowthPlanController` | | 健康报告 | `/health-reports` | nutritionist | `HealthReportController` | | 健康指标 | `/health-indicators` | nutritionist | `HealthReportController` | | 健康打卡 | `/health-checkins` | nutritionist | `HealthCheckinController` | | 活动列表 | `/activities` | activity_manager | `ActivityController` | | 活动审核 | `/activity-review` | activity_manager | `ActivityController` | ## 3. 架构设计 ### 3.1 权限模型 采用 **Permission-based** 方案。定义两层权限标识: - **通配级:** `'assessment:*'` 匹配所有 `assessment:` 开头的权限 - **原子级:** `'articles:manage'` 精确匹配单个功能 #### 角色→权限映射 ```javascript // src/utils/permissions.js const ROLE_PERMISSIONS = { admin: ['*'], teacher: ['dashboard', 'service:*', 'growth:*', 'biz:*', 'assessment:*', 'messages'], nutritionist: ['dashboard', 'service:family', 'health:*', 'assessment:dan', 'energy'], article_manager: ['dashboard', 'articles:*'], activity_manager: ['dashboard', 'activity:*'], } ``` #### 菜单→权限映射 ``` 首页 /dashboard → dashboard 家庭管理 (system) /families /children /points → family:* 任务管理 /tasks /task-templates → task:* 奖励管理 /rewards → reward:* 系统管理 /users /sys-config /... → system:* 我的家庭 /my-families → service:family 成长记录 /growth-records → growth:records 成长计划 /growth-plans → growth:plans 套餐管理 /teacher-packages → biz:packages 订单佣金 /teacher-orders → biz:orders DAN测评 /teacher-assessment → assessment:dan 家长咨询 /teacher-consult → assessment:consult 消息中心 /teacher-messages → messages 健康报告 /health-reports → health:reports 健康指标 /health-indicators → health:indicators 健康打卡 /health-checkins → health:checkins 五维能量 /energy-sandbox → energy 文章分类 /article-categories → articles:categories 文章管理 /article-manage → articles:manage 文章编辑 /article-edit → articles:edit 活动列表 /activities → activity:list 活动审核 /activity-review → activity:review ``` ### 3.2 后端变更 #### JWT 变更 **当前:** `generateToken(userId, role)` → JWT payload 含 `role: "admin"` **改为:** `generateToken(userId, roles)` → JWT payload 含 `roles: ["admin", "article_manager"]` #### API 变更 `POST /api/admin-auth/login` 响应增加 `roles` 数组: ```json { "code": 200, "data": { "token": "...", "adminId": 1, "username": "admin", "realName": "管理员", "role": "admin", "roles": ["admin", "article_manager"] } } ``` `POST /api/admin-auth/info` 响应同样增加 `roles` 数组。 **无需迁移:** User 表 `roles` 字段已存在,仅前端新增的角色值(`nutritionist`, `article_manager`, `activity_manager`)需要在用户管理后台可设置。 ### 3.3 前端变更 #### 3.3.1 权限工具模块 新增 `src/utils/permissions.js`: ```javascript // 角色→权限映射表 const ROLE_PERMISSIONS = { ... } // 菜单定义(每个菜单项带权限标识) const MENU_DEFINITIONS = [ ... ] // 核心函数 function getEffectivePermissions(roles) { /* 合并所有角色的权限 */ } function hasPermission(userPerms, required) { /* 前缀匹配 + 通配 * 支持 */ } ``` #### 3.3.2 状态管理 `Login.vue` 登录后存储: ```javascript localStorage.setItem('roles', JSON.stringify(res.data.roles)) ``` 新增 Vuex store 或全局 computed 读取 `roles`。 #### 3.3.3 Layout.vue 菜单渲染 从目前的硬编码三层分支改为: ``` ``` #### 3.3.4 Router 守卫 路由 meta 增加 `perm` 字段: ```javascript { path: 'article-manage', component: ..., meta: { title: '文章管理', perm: 'articles:manage' } } ``` 路由守卫检查逻辑: ```javascript if (to.meta.perm) { const perms = getEffectivePermissions(userRoles) if (!hasPermission(perms, to.meta.perm)) { return next({ path: '/403', replace: true }) } } ``` 保留现有 `requiresTeacher` 兼容过渡,逐步替换为 `perm`。 ## 4. 菜单结构(最终效果) ### 管理员登录 ``` 首页 | 家庭管理 | 任务管理 | 奖励管理 | 系统管理(全部子项) ``` ### 成长规划师登录 ``` 首页 我的家庭 → 家庭详情 → 成长档案tab / 成长计划tab / 家庭成员tab 成长记录 成长计划 业务管理 → 套餐管理 / 订单佣金 测评管理 → DAN测评 / 家长咨询 消息中心 ``` ### 营养师登录 ``` 首页 我的家庭 → 家庭详情 → 健康报告tab / 健康指标tab / 健康打卡tab 健康报告 健康指标 健康打卡 五维能量 ``` ### 文章管理员登录 ``` 首页 文章分类 文章管理 ``` ### 活动管理员登录 ``` 首页 活动列表 活动审核 ``` ### 多角色合并(示例:营养师 + 文章管理员) ``` 首页 我的家庭 | 健康报告 | 健康指标 | 健康打卡 | 五维能量 文章分类 | 文章管理 ``` ## 5. 新建页面骨架 每个新建页面仅创建 Vue 文件 + 路由注册,内容为一个带 el-table 骨架的占位页: - `/my-families` — 授权家庭列表(复用教师端现有 `TeacherFamilies.vue` 逻辑) - `/growth-records` — 成长记录列表,依赖 `GrowthRecordController` - `/growth-plans` — 成长计划列表,依赖 `GrowthPlanController` - `/health-reports` — 健康报告列表,依赖 `HealthReportController` - `/health-indicators` — 健康指标管理,依赖 `HealthReportController` - `/health-checkins` — 健康打卡列表,依赖 `HealthCheckinController` - `/activities` — 活动列表管理,依赖 `ActivityController` - `/activity-review` — 活动审核,依赖 `ActivityController` ## 6. 实施步骤 1. 后端:JWT 及 API 多角色支持 2. 新增 `src/utils/permissions.js` 权限引擎 3. 重构 Layout.vue 菜单渲染(权限驱动) 4. 重构 Router 守卫(权限检查) 5. Login.vue 适配多角色存储 6. 新建 8 个页面骨架 + 路由注册 7. 验证:admin/teacher 现有功能不受影响 ## 7. 未纳入范围 - 用户管理后台的角色编辑界面(已有 `User.roles` 字段,未来可通过管理接口直接编辑) - 「我的家庭」进入后的 tab 式详情页设计(本期只搭路由和菜单入口) - 小程序端权限(仅 Web 管理端)