From 658bce4fbca1a204dcd177e024836844dda40667 Mon Sep 17 00:00:00 2001 From: chenyuan Date: Mon, 3 Aug 2026 09:37:45 +0800 Subject: [PATCH] docs: plan comprehensive training module --- ...026-08-03-comprehensive-training-module.md | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 docs/superpowers/plans/2026-08-03-comprehensive-training-module.md diff --git a/docs/superpowers/plans/2026-08-03-comprehensive-training-module.md b/docs/superpowers/plans/2026-08-03-comprehensive-training-module.md new file mode 100644 index 0000000..aa5aa58 --- /dev/null +++ b/docs/superpowers/plans/2026-08-03-comprehensive-training-module.md @@ -0,0 +1,180 @@ +# 综合实训模块实施计划 + +> **For Codex:** Required execution workflow: use `superpowers:executing-plans` to implement this plan task-by-task. + +**Goal:** 在既有五大实训模块前新增可独立配置、默认不向学生发布的“综合实训”,并使其在发布后按 20% 计入成绩;未发布时其余模块自动归一化为 100%。 + +**Architecture:** 以固定任务键 `comprehensive-case-training` 作为第六个内置任务,继续复用现有“班级任务配置 + 任务分配 + 通用实训页”的数据和交互链路。用“必须显式发布”的任务键规则覆盖既有“未配置班级则所有默认任务可见”的兜底逻辑;成绩服务和实验报告共用同一判断:只有本班明确发布且任务已启用的综合实训才参与 20% 权重。 + +**Tech Stack:** Spring Boot 2.7、MyBatis、JUnit 5 + Mockito;Vue 3、Vue Router、Element Plus、Vite。 + +--- + +### Task 1: 先用测试定义第六个内置任务和显式发布规则 + +**Files:** +- Modify: `link_commerce/src/test/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImplTest.java` +- Modify: `link_commerce/src/test/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationControllerTest.java` +- Modify: `link_commerce/src/main/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImpl.java` + +**Step 1: Write the failing tests** + +补充/调整服务层测试,覆盖: + +- `ensureDefaultTasks` 共生成 24 个固定任务,第一项键为 `comprehensive-case-training`,名称为“综合案例实训”,项目名为“综合实训”。 +- 未曾保存“任务分配”的班级,学生任务列表和按键查询均不返回该任务;原有五类任务仍保持可见。 +- 任务分配保存了发布标记且包含该键时,学生列表和按键查询返回该任务;取消该键或该班级任务被禁用时不返回。 +- 更新原有种子任务数量断言(现有 22/24 次插入断言)为新总数,不用硬编码掩盖键和排序错误。 + +**Step 2: Run test to verify it fails** + +Run: `mvnw.cmd -Dtest=TrainingTaskServiceImplTest,TaskAllocationControllerTest test` + +Expected: 新场景在实现前失败。若包装器仍缺少 `.mvn/wrapper/maven-wrapper.properties`,先记录为环境阻塞,再用本机 Maven 或已配置的 Maven 路径执行相同命令;不得跳过测试。 + +**Step 3: Write minimal implementation** + +在 `TrainingTaskServiceImpl`: + +- 抽出综合实训任务键常量和 `requiresExplicitPublication` 判定。 +- 在 `defaultTasks()` 的首位插入默认“综合案例实训”,使教师端动态项目分组和学生端排序均在顶部显示。 +- 调整 `listForStudentTeachingClass` 与 `getStudentTaskByTeachingClass`:普通历史任务保留“班级未配置时默认可见”的兼容行为;综合实训即使班级没有配置记录,也必须有该班的发布标记、启用分配记录和启用班级任务配置才可见。 +- 保持教师的任务配置列表始终能看到综合案例任务,避免它因未发布而无法编辑。 + +**Step 4: Run tests to verify they pass** + +Run: `mvnw.cmd -Dtest=TrainingTaskServiceImplTest,TaskAllocationControllerTest test` + +Expected: PASS。 + +**Step 5: Commit** + +```bash +git add src/main/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImpl.java src/test/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImplTest.java src/test/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationControllerTest.java +git commit -m "feat: add optional comprehensive training task" +``` + +### Task 2: 先定义成绩与实验报告的参与状态和归一化测试 + +**Files:** +- Modify: `link_commerce/src/test/java/com/sztzjy/linkCommerce/service/impl/ScoreRankServiceImplTeachingClassTest.java` +- Modify: `link_commerce/src/test/java/com/sztzjy/linkCommerce/service/impl/StudentExperimentReportServiceImplTest.java` +- Modify: `link_commerce/src/main/java/com/sztzjy/linkCommerce/entity/dto/StudentExperimentReportModuleDTO.java` +- Modify: `link_commerce/src/main/java/com/sztzjy/linkCommerce/service/impl/ScoreRankServiceImpl.java` +- Modify: `link_commerce/src/main/java/com/sztzjy/linkCommerce/service/impl/StudentExperimentReportServiceImpl.java` + +**Step 1: Write the failing tests** + +建立同一班级、同一批五类任务成绩的两组情形: + +- 无综合实训明确发布时,六模块报告仍展示“综合实训”,但其 `participating` 为 `false`、任务数为 0、总分以其余权重之和 0.80 归一化;例如五个参与模块均为 100 分,合计必须为 100,而不是 80。 +- 发布并启用综合任务但学生尚无答题时,综合模块 `participating` 为 `true`,其 20% 按 0 分计入;总分恢复六项原权重计算。 +- 发布综合任务且有作答时,排名计算与实验报告总分使用同一归一化规则;禁用/取消发布后再次回到五模块归一化。 + +**Step 2: Run test to verify it fails** + +Run: `mvnw.cmd -Dtest=ScoreRankServiceImplTeachingClassTest,StudentExperimentReportServiceImplTest test` + +Expected: 现有实现会把未布置综合实训按 0 分的 20% 扣除,测试失败。 + +**Step 3: Write minimal implementation** + +- 为 `StudentExperimentReportModuleDTO` 增加只读序列化字段 `participating`,供学生端明确显示“未布置”。 +- 在 `ScoreRankServiceImpl` 和 `StudentExperimentReportServiceImpl` 使用本班的任务分配记录判断综合实训是否“发布且启用”;不要将学校/平台默认任务误认为已发布的综合实训。 +- 将模块总分统一计算为 `Σ(模块平均分 × 原权重) ÷ Σ(参与模块原权重)`;无可参与任务时安全返回 0,避免除零。 +- 原有 10/30/10/10/20/20 权重存储和教师配置界面保持不变;综合实训被正式发布后按完整六模块权重计分。 +- 将目前压缩成单行的报告服务整理为正常方法边界,仅做该功能所需的可读性重构,避免改变其他模块名、作答统计或权限。 + +**Step 4: Run tests to verify they pass** + +Run: `mvnw.cmd -Dtest=ScoreRankServiceImplTeachingClassTest,StudentExperimentReportServiceImplTest test` + +Expected: PASS。 + +**Step 5: Commit** + +```bash +git add src/main/java/com/sztzjy/linkCommerce/entity/dto/StudentExperimentReportModuleDTO.java src/main/java/com/sztzjy/linkCommerce/service/impl/ScoreRankServiceImpl.java src/main/java/com/sztzjy/linkCommerce/service/impl/StudentExperimentReportServiceImpl.java src/test/java/com/sztzjy/linkCommerce/service/impl/ScoreRankServiceImplTeachingClassTest.java src/test/java/com/sztzjy/linkCommerce/service/impl/StudentExperimentReportServiceImplTest.java +git commit -m "fix: normalize scores when comprehensive training is unpublished" +``` + +### Task 3: 在教师任务分配中将综合实训默认设为未发布 + +**Files:** +- Modify: `e-commerce-internet/src/views/teacherEnd/task/index.vue` +- Modify: `e-commerce-internet/src/views/teacherEnd/trainingTask/index.vue` + +**Step 1: Define the UI regression checks before editing** + +把以下手工检查写入本次变更说明,而不是给生产页增加测试框架:未配置班级首次打开任务分配时,五类现有任务默认勾选,`comprehensive-case-training` 不勾选;教师勾选保存后重新进入仍勾选;取消后学生端不可见。确认动态任务配置页在顶部显示“综合实训 / 综合案例实训”,并且材料、案例、步骤、AI 说明、评分项等既有编辑能力可用。 + +**Step 2: Implement the minimal UI change** + +- 将“尚无发布配置时默认选中全部任务”的初始化逻辑改为排除综合实训固定键;有既有配置时严格使用后端已发布键。 +- 在任务分配的任务项中显示所属模块(或清晰的“综合实训”标识),让教师能辨认这项独立考试任务。 +- 不创建新的专用编辑页:继续使用已有按班级的任务配置页,保持“恢复当前班级默认”只影响该班。 + +**Step 3: Build frontend** + +Run: `C:\Users\Acer\.cache\codex-runtimes\codex-primary-runtime\dependencies\node\bin\node.exe node_modules\vite\bin\vite.js build` + +Expected: production build succeeds; only record pre-existing warnings if any. + +**Step 4: Commit** + +```bash +git add src/views/teacherEnd/task/index.vue src/views/teacherEnd/trainingTask/index.vue +git commit -m "feat: keep comprehensive training unpublished by default" +``` + +### Task 4: 接入学生端导航、路由和通用实训页 + +**Files:** +- Modify: `e-commerce-internet/src/router/index.js` +- Modify: `e-commerce-internet/src/layout/components/Sidebar/index.vue` +- Modify: `e-commerce-internet/src/views/training/studentTrainingPages.js` +- Modify: `e-commerce-internet/src/views/training/GenericTrainingPage.vue` (only if an empty default field/step needs a safe fallback) + +**Step 1: Implement the student entry** + +- 注册 `comprehensive-case-training` 对应的通用实训路由,导航置于五类模块之前,标题“综合实训”。 +- 在 `studentTrainingPages.js` 提供安全的最小初始配置(综合案例说明、作答区和提交入口);实际教学材料、案例、步骤、AI 提示由已存在的班级任务配置覆盖。 +- 让侧栏继续依赖后端 `publishedTaskKeys`:未发布时完全不显示入口;发布后显示,且直接输入 URL 也会被后端任务读取接口拒绝。 + +**Step 2: Verify by build and manual smoke test** + +Run: `C:\Users\Acer\.cache\codex-runtimes\codex-primary-runtime\dependencies\node\bin\node.exe node_modules\vite\bin\vite.js build` + +Manual: 教师配置一份综合案例并发布;学生刷新后可见“综合实训”、可打开和提交;取消发布后侧栏入口消失,旧链接显示无权限/任务不可用而不是加载默认内容。 + +**Step 3: Commit** + +```bash +git add src/router/index.js src/layout/components/Sidebar/index.vue src/views/training/studentTrainingPages.js src/views/training/GenericTrainingPage.vue +git commit -m "feat: expose published comprehensive training to students" +``` + +### Task 5: 完整回归与交付检查 + +**Files:** +- Verify only: `link_commerce/pom.xml` +- Verify only: `e-commerce-internet/package.json` + +**Step 1: Run focused backend suite** + +Run: `mvnw.cmd -Dtest=TrainingTaskServiceImplTest,TaskAllocationControllerTest,ScoreRankServiceImplTeachingClassTest,StudentExperimentReportServiceImplTest test` + +Expected: PASS。若 Maven 包装器仍缺文件,报告该仓库环境问题与实际替代命令/结果。 + +**Step 2: Run frontend production build** + +Run: `C:\Users\Acer\.cache\codex-runtimes\codex-primary-runtime\dependencies\node\bin\node.exe node_modules\vite\bin\vite.js build` + +Expected: PASS。 + +**Step 3: Inspect final diff** + +Run: `git diff --check` in each repository and `git status --short`. + +Expected: no whitespace errors; pre-existing untracked files remain untouched; only feature commits are reported. +