From d8a963f6117e0cbc8aadd7a75d11222118a4581b Mon Sep 17 00:00:00 2001 From: wangzhibiao Date: Tue, 15 Sep 2026 16:12:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9D=83=E9=99=90=EF=BC=9A?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=95=99=E5=B8=88=E4=B8=8E=E5=AD=A6=E5=91=98?= =?UTF-8?q?=E8=87=AA=E6=9C=8D=E5=8A=A1=E5=89=8D=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RbacPermissionMigrationContractTest.java | 29 + .../005_training_roles_permissions.sql | 6 +- build_ui/src/api/train/meStudent.js | 60 ++ build_ui/src/api/train/meTeacher.js | 44 ++ build_ui/src/views/index.vue | 114 +++- build_ui/src/views/login.vue | 8 +- build_ui/src/views/train/board/index.vue | 12 +- build_ui/src/views/train/me/student/index.vue | 638 ++++++++++++++++++ build_ui/src/views/train/me/teacher/index.vue | 519 ++++++++++++++ .../08_implementation_task_breakdown.md | 75 +- 10 files changed, 1438 insertions(+), 67 deletions(-) create mode 100644 build_ui/src/api/train/meStudent.js create mode 100644 build_ui/src/api/train/meTeacher.js create mode 100644 build_ui/src/views/train/me/student/index.vue create mode 100644 build_ui/src/views/train/me/teacher/index.vue diff --git a/RuoYi-Vue/ruoyi-admin/src/test/java/com/ruoyi/web/controller/train/RbacPermissionMigrationContractTest.java b/RuoYi-Vue/ruoyi-admin/src/test/java/com/ruoyi/web/controller/train/RbacPermissionMigrationContractTest.java index 1a8d502fa..fcf77b737 100644 --- a/RuoYi-Vue/ruoyi-admin/src/test/java/com/ruoyi/web/controller/train/RbacPermissionMigrationContractTest.java +++ b/RuoYi-Vue/ruoyi-admin/src/test/java/com/ruoyi/web/controller/train/RbacPermissionMigrationContractTest.java @@ -74,6 +74,35 @@ public class RbacPermissionMigrationContractTest } } + @Test + public void migration005ConfiguresTeacherAndStudentRouteMenusAndRoleBindings() throws Exception + { + String sql = new String(Files.readAllBytes(findMigration("005_training_roles_permissions.sql")), StandardCharsets.UTF_8).toLowerCase(); + + // 验证 2239 教师工作台路由配置 + assertContains(sql, + "2239", + "教师工作台", + "'teacher'", + "'train/me/teacher/index'", + "'c'", + "'train:me:teacher'"); + + // 验证 2240 学员中心路由配置 + assertContains(sql, + "2240", + "学员中心", + "'student'", + "'train/me/student/index'", + "'c'", + "'train:me:student'"); + + // 验证教师角色 (role_id=4) 与学员角色 (role_id=5) 的专属菜单绑定 + assertContains(sql, + "select 4, 2239", + "select 5, 2240"); + } + private Path findMigration(String filename) { for (Path path = Paths.get("").toAbsolutePath(); path != null; path = path.getParent()) diff --git a/RuoYi-Vue/sql/system/kingbase/005_training_roles_permissions.sql b/RuoYi-Vue/sql/system/kingbase/005_training_roles_permissions.sql index cb18aebbe..6151550a3 100644 --- a/RuoYi-Vue/sql/system/kingbase/005_training_roles_permissions.sql +++ b/RuoYi-Vue/sql/system/kingbase/005_training_roles_permissions.sql @@ -249,13 +249,13 @@ INSERT INTO public.sys_menu (menu_id, menu_name, parent_id, order_num, path, com SELECT 2238, '班牌导出', 2174, 6, '#', '', '', 1, 0, 'F', '0', '0', 'train:board:export', '#', 'admin', CURRENT_TIMESTAMP, '电子班牌导出' WHERE NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE menu_id = 2238 OR perms = 'train:board:export'); --- 3.11 自服务专属接口权限 (虚拟节点挂载于 0) +-- 3.11 自服务专属菜单与页面路由 (挂载于根节点 0,供教师与学员在侧边栏直达工作台) INSERT INTO public.sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) -SELECT 2239, '教师自服务', 0, 99, '#', '', '', 1, 0, 'F', '0', '0', 'train:me:teacher', '#', 'admin', CURRENT_TIMESTAMP, '教师专属自服务接口权限' +SELECT 2239, '教师工作台', 0, 99, 'teacher', 'train/me/teacher/index', '', 1, 0, 'C', '0', '0', 'train:me:teacher', 'education', 'admin', CURRENT_TIMESTAMP, '教师专属工作台页面及自服务权限' WHERE NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE menu_id = 2239 OR perms = 'train:me:teacher'); INSERT INTO public.sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) -SELECT 2240, '学员自服务', 0, 100, '#', '', '', 1, 0, 'F', '0', '0', 'train:me:student', '#', 'admin', CURRENT_TIMESTAMP, '学员专属自服务接口权限' +SELECT 2240, '学员中心', 0, 100, 'student', 'train/me/student/index', '', 1, 0, 'C', '0', '0', 'train:me:student', 'user', 'admin', CURRENT_TIMESTAMP, '学员专属个人培训中心页面及自服务权限' WHERE NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE menu_id = 2240 OR perms = 'train:me:student'); -- ============================================================================= diff --git a/build_ui/src/api/train/meStudent.js b/build_ui/src/api/train/meStudent.js new file mode 100644 index 000000000..588c7ce61 --- /dev/null +++ b/build_ui/src/api/train/meStudent.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 获取学员本人档案信息 (敏感信息已脱敏,严禁传 studentId) +export function getStudentProfile() { + return request({ + url: '/train/me/student', + method: 'get' + }) +} + +// 获取本人参训班级及报名状态列表 +export function getMyEnrollments(query) { + return request({ + url: '/train/me/student/enrollments', + method: 'get', + params: query + }) +} + +// 获取本人参训课表日程 +export function getMyTimetable(query) { + return request({ + url: '/train/me/student/timetable', + method: 'get', + params: query + }) +} + +// 获取本人最新开班报到凭据与状态 +export function getMyReport() { + return request({ + url: '/train/me/student/report', + method: 'get' + }) +} + +// 获取本人考勤打卡流水 +export function getMyAttendance(query) { + return request({ + url: '/train/me/student/attendance', + method: 'get', + params: query + }) +} + +// 获取本人累计培训学时记录 +export function getMyDuration() { + return request({ + url: '/train/me/student/duration', + method: 'get' + }) +} + +// 获取本人多维成长雷达画像 +export function getMyPortrait() { + return request({ + url: '/train/me/student/portrait', + method: 'get' + }) +} diff --git a/build_ui/src/api/train/meTeacher.js b/build_ui/src/api/train/meTeacher.js new file mode 100644 index 000000000..47b898528 --- /dev/null +++ b/build_ui/src/api/train/meTeacher.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 获取教师本人档案信息 +export function getTeacherProfile() { + return request({ + url: '/train/me/teacher', + method: 'get' + }) +} + +// 获取教师本人任教的培训班列表 +export function getMyPlans(query) { + return request({ + url: '/train/me/teacher/plans', + method: 'get', + params: query + }) +} + +// 获取教师授课课表日程 +export function getMyTimetable(query) { + return request({ + url: '/train/me/teacher/timetable', + method: 'get', + params: query + }) +} + +// 获取任教班级学员花名册 (强制携带 planId) +export function getMyClassStudents(query) { + return request({ + url: '/train/me/teacher/students', + method: 'get', + params: query + }) +} + +// 查看指定课次打卡考勤 +export function getLessonAttendance(lessonId) { + return request({ + url: '/train/me/teacher/lessons/' + lessonId + '/attendance', + method: 'get' + }) +} diff --git a/build_ui/src/views/index.vue b/build_ui/src/views/index.vue index 4db63a33e..09c5f4d50 100644 --- a/build_ui/src/views/index.vue +++ b/build_ui/src/views/index.vue @@ -1,36 +1,105 @@ - - - -
- 智慧培训管理平台 -
-
-

欢迎使用智慧培训管理平台。本平台提供培训计划编排、学员主档与参训管理、智能排课排程、电子班牌联动、教学设施与实训场地调度,以及全流程多维学习数据分析等核心功能。

-
-
- 系统架构 -
- -
- 系统版本:V1.0 - 版权所有:中国科学院沈阳计算技术研究所有限公司 -
-
-
-
- + + + diff --git a/build_ui/src/views/train/me/teacher/index.vue b/build_ui/src/views/train/me/teacher/index.vue new file mode 100644 index 000000000..4dd454b62 --- /dev/null +++ b/build_ui/src/views/train/me/teacher/index.vue @@ -0,0 +1,519 @@ + + + + + diff --git a/docs/development/rbac-r2/08_implementation_task_breakdown.md b/docs/development/rbac-r2/08_implementation_task_breakdown.md index 67efa9718..9991f4329 100644 --- a/docs/development/rbac-r2/08_implementation_task_breakdown.md +++ b/docs/development/rbac-r2/08_implementation_task_breakdown.md @@ -89,33 +89,41 @@ flowchart TD 4. `StudentSelfServiceApiTest` 6 个单测用例全部通过。 - **完成标志**: 接口单元测试通过率 100%,敏感信息脱敏合格。 -### 任务 5: RBAC-B5 - 教师工作台前端视图开发 (Teacher Frontend) [PENDING (Wave 2)] -- **依赖关系**: 依赖 B2 菜单路由,可与 B3 并行(采用 Mock 或接口契约联调)。 -- **任务目标**: - 1. 在 `build_ui/src/views/train/teacher/` 下开发工作台看板与我的日程日历组件。 - 2. 开发任教班级花名册抽屉视图。 -- **完成标志**: 教师登录后正常展现日历课表与花名册。 +### 任务 5: RBAC-B5 - 教师工作台前端视图开发 (Teacher Frontend) [COMPLETED (Wave 2)] +- **依赖关系**: 依赖 B2 菜单路由与 B3 后端自服务 API。 +- **当前状态**: 已完成 +- **交付内容**: + 1. `build_ui/src/api/train/meTeacher.js`:封装 `/train/me/teacher/**` 全套轻量查询 API。 + 2. `build_ui/src/views/train/me/teacher/index.vue`:教师自服务工作台,包含个人主档、任教班级列表、授课日历课表、脱敏花名册抽屉与课次考勤查看抽屉,支持 403 业务未绑定友好告警与 Empty State。 + 3. `build_ui/src/views/index.vue`:实现角色智能 Landing,教师身份登录自适应直达教师工作台。 +- **完成标志**: 教师工作台组件与路由完备,构建与静态校验通过。 -### 任务 6: RBAC-B6 - 学员个人培训中心前端开发 (Student Frontend) [PENDING (Wave 2)] -- **依赖关系**: 依赖 B2 菜单路由,可与 B4 并行开发。 -- **任务目标**: - 1. 在 `build_ui/src/views/train/student/` 下开发学员培训个人中心。 - 2. 整合培训流程步骤条、今日课表卡片、个人考勤打卡流水与雷达画像组件。 -- **完成标志**: 学员登录后清晰直观呈现个人培训全流程状态。 +### 任务 6: RBAC-B6 - 学员个人培训中心前端开发 (Student Frontend) [COMPLETED (Wave 2)] +- **依赖关系**: 依赖 B2 菜单路由与 B4 后端自服务 API。 +- **当前状态**: 已完成 +- **交付内容**: + 1. `build_ui/src/api/train/meStudent.js`:封装 `/train/me/student/**` 个人自服务 API(无任何外部 studentId 入参)。 + 2. `build_ui/src/views/train/me/student/index.vue`:学员专属培训中心,集成个人档案、参训流转状态条、所在班级日程课表、开班报到回执单卡片、规范考勤流水打卡记录、累计学时统计与 ECharts 多维能力成长雷达图。 + 3. `build_ui/src/views/index.vue`:学员身份登录自适应直达学员个人中心。 +- **完成标志**: 学员工作台各模块渲染与空状态处理严密,构建通过。 -### 任务 7: RBAC-B7 - 登录界面注册入口安全改造 (Login UI Policy) [PENDING (Wave 2)] -- **依赖关系**: 独立任务,可立即开工。 -- **任务目标**: - 1. 修改 `build_ui/src/views/login.vue`,彻底关闭 `register` 开关,移除“立即注册”链接。 - 2. 增加居中提示:“*账号由培训管理部门统一创建与授权维护*”。 -- **完成标志**: 登录页面无注册链接,提示文案清晰优雅。 +### 任务 7: RBAC-B7 - 登录界面注册入口安全改造 (Login UI Policy) [COMPLETED (Wave 2)] +- **依赖关系**: 独立前端改造。 +- **当前状态**: 已完成 +- **交付内容**: + 1. 修改 `build_ui/src/views/login.vue`,系统标题更新为暂定对外名称“沈阳房建公寓段学员管理系统”。 + 2. 固化 `register: false`,彻底移除“立即注册”路由跳转链接。 + 3. 增加表单底部居中受控提示:“*账号由培训管理部门统一创建与授权维护*”。 +- **完成标志**: 登录界面无注册外漏,提示文案清晰企业化。 -### 任务 8: RBAC-B8 - 班牌权限命名空间统一对齐 (Namespace Alignment) [PARTIALLY COMPLETED (Wave 1 后端已完成)] -- **依赖关系**: 独立任务,可立即开工。 -- **当前状态**: - - 后端:`TrainElectronicBoardController.java` 中的权限注解已全部从 `system:board:*` 收敛统一为 `train:board:*` [COMPLETED] - - 前端:`build_ui/src/views/train/board/index.vue` 中的 `v-hasPermi` 对齐计划在 Wave 2 前端阶段完成 [PENDING] -- **完成标志**: 静态契约测试 `testElectronicBoardControllerPermissionsAligned` 验证通过。 +### 任务 8: RBAC-B8 - 班牌权限命名空间统一对齐 (Namespace Alignment) [COMPLETED (Wave 1 & 2)] +- **依赖关系**: 前后端对齐。 +- **当前状态**: 已完成 +- **交付内容**: + - 后端:`TrainElectronicBoardController.java` 中的权限注解全部收敛统一为 `train:board:*` [COMPLETED (Wave 1)] + - 前端:`build_ui/src/views/train/board/index.vue` 中的 6 处 `v-hasPermi` 全部统一为 `['train:board:*']`,彻底消除 `system:board:*` 遗留 [COMPLETED (Wave 2)] + - 迁移脚本:`005_training_roles_permissions.sql` 将 2239/2240 提升为二级路由菜单(`menu_type='C'`),支持若依侧边栏独立挂载与静态契约验证。 +- **完成标志**: 前后端权限命名空间与菜单路由 100% 对齐。 ### 任务 9: RBAC-B9 - 数据范围与 IDOR 安全渗透自动化测试 (IDOR Gate) [PARTIALLY COMPLETED (Wave 1 后端 IDOR 已通过)] - **依赖关系**: 依赖 B3、B4、B5、B6 联调完成。 @@ -137,15 +145,20 @@ flowchart TD ## 3. 并行施工调度建议与 Wave 进展 -- **Wave 1 (已完成)**: +- **系统对外展示名称规范**: + - 暂定对外展示名称: **沈阳房建公寓段学员管理系统** + - 内部工程名、Git 仓库、Java 包名、数据库名仍严格保持 `RailwaySystem`,禁止全局非必要替换。 +- **Wave 1 (已完成并 Checkpoint)**: - 后端基础设施与迁移脚本准备: `RBAC-B1`, `RBAC-B2` (完成) - 核心身份服务与自服务后端: `RBAC-B3`, `RBAC-B4` (完成) - 班牌后端权限收敛: `RBAC-B8 (后端)` (完成) - 安全与契约单元测试: `RBAC-B9 (后端)` (完成,194/194 PASS) -- **Wave 2 (待推进)**: - - 教师工作台前端视图开发: `RBAC-B5` - - 学员个人培训中心前端开发: `RBAC-B6` - - 登录入口安全策略改造: `RBAC-B7` - - 班牌前端权限指令对齐: `RBAC-B8 (前端)` -- **Wave 3 (最终验收)**: +- **Wave 2 (已完成待评审)**: + - 教师工作台前端视图开发: `RBAC-B5` (完成) + - 学员个人培训中心前端开发: `RBAC-B6` (完成) + - 登录入口安全策略改造: `RBAC-B7` (完成) + - 班牌前端权限指令对齐与菜单提升: `RBAC-B8 (前端 & 005.sql)` (完成) + - 生产构建与代码规范校验: `npm run build:prod` & ESLint 100% 通过 + - 后端回归单测验证: 194 / 194 PASS +- **Wave 3 (后续推进)**: - 三角色端到端联调与 E2E-R2 回归测试: `RBAC-B10`