|
|
|
|
@ -44,7 +44,7 @@
|
|
|
|
|
- Consumes: requireOwnedTeachingClass(String, String)。
|
|
|
|
|
- Produces: restoreClassTaskDefault(String, String, String) 和 restoreClassTasksDefaults(String, String)。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 1: 写失败的服务测试**
|
|
|
|
|
- [x] **Step 1: 写失败的服务测试**
|
|
|
|
|
|
|
|
|
|
在 TrainingTaskServiceImplTest 新增如下测试。测试类创建 class-1(TEACHING,createdBy 为 teacher-1)和 class-2(createdBy 为 teacher-a)。
|
|
|
|
|
|
|
|
|
|
@ -73,13 +73,13 @@ void teacherCannotRestoreAnotherTeachersClass() {
|
|
|
|
|
}
|
|
|
|
|
~~~
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 2: 运行失败测试**
|
|
|
|
|
- [x] **Step 2: 运行失败测试**
|
|
|
|
|
|
|
|
|
|
Run: mvn -q -Dtest=TrainingTaskServiceImplTest test
|
|
|
|
|
|
|
|
|
|
Expected: 编译失败,缺少恢复服务或 Mapper 方法。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 3: 添加 Mapper 契约与 SQL**
|
|
|
|
|
- [x] **Step 3: 添加 Mapper 契约与 SQL**
|
|
|
|
|
|
|
|
|
|
~~~java
|
|
|
|
|
int deleteByTeachingClassAndTaskKey(@Param("teachingClassId") String teachingClassId,
|
|
|
|
|
@ -99,7 +99,7 @@ int deleteByTeachingClass(@Param("teachingClassId") String teachingClassId);
|
|
|
|
|
</delete>
|
|
|
|
|
~~~
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 4: 实现服务**
|
|
|
|
|
- [x] **Step 4: 实现服务**
|
|
|
|
|
|
|
|
|
|
~~~java
|
|
|
|
|
@Override
|
|
|
|
|
@ -118,7 +118,7 @@ public void restoreClassTasksDefaults(String teachingClassId, String operatorId)
|
|
|
|
|
}
|
|
|
|
|
~~~
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 5: 验证并提交**
|
|
|
|
|
- [x] **Step 5: 验证并提交**
|
|
|
|
|
|
|
|
|
|
Run: mvn -q -Dtest=TrainingTaskServiceImplTest test
|
|
|
|
|
|
|
|
|
|
@ -133,30 +133,33 @@ git commit -m "feat: restore class training task defaults"
|
|
|
|
|
|
|
|
|
|
**Files:**
|
|
|
|
|
- Modify: src/main/java/com/sztzjy/linkCommerce/controller/stu/TrainingTaskController.java
|
|
|
|
|
- Test: src/test/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImplTest.java
|
|
|
|
|
- Create: src/test/java/com/sztzjy/linkCommerce/controller/stu/TrainingTaskControllerRestoreDefaultTest.java
|
|
|
|
|
|
|
|
|
|
**Interfaces:**
|
|
|
|
|
- Consumes: Task 1 服务方法。
|
|
|
|
|
- Produces: DELETE /api/training-tasks/classes/{teachingClassId}/{taskKey}/override 和 DELETE /api/training-tasks/classes/{teachingClassId}/overrides。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 1: 写失败的源文件契约测试**
|
|
|
|
|
- [x] **Step 1: 写失败的控制器调用测试**
|
|
|
|
|
|
|
|
|
|
在现有测试中读取控制器源码,添加:
|
|
|
|
|
创建 TrainingTaskControllerRestoreDefaultTest,向控制器注入 mock TrainingTaskService,并用带 roleId=3 的 JWT 请求调用两个端点:
|
|
|
|
|
|
|
|
|
|
~~~java
|
|
|
|
|
assertTrue(source.contains("@DeleteMapping(\"/classes/{teachingClassId}/{taskKey}/override\")"));
|
|
|
|
|
assertTrue(source.contains("trainingTaskService.restoreClassTaskDefault"));
|
|
|
|
|
assertTrue(source.contains("@DeleteMapping(\"/classes/{teachingClassId}/overrides\")"));
|
|
|
|
|
assertTrue(source.contains("trainingTaskService.restoreClassTasksDefaults"));
|
|
|
|
|
ResultEntity result = controller.restoreClassTaskDefault(
|
|
|
|
|
"class-1", "new-product-survey", requestFor("teacher-1"));
|
|
|
|
|
|
|
|
|
|
assertEquals(HttpStatus.OK, result.getStatusCode());
|
|
|
|
|
verify(service).restoreClassTaskDefault("class-1", "new-product-survey", "teacher-1");
|
|
|
|
|
~~~
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 2: 运行失败测试**
|
|
|
|
|
全班测试调用 controller.restoreClassTasksDefaults("class-1", requestFor("teacher-1")),并验证服务收到 restoreClassTasksDefaults("class-1", "teacher-1")。
|
|
|
|
|
|
|
|
|
|
Run: mvn -q -Dtest=TrainingTaskServiceImplTest test
|
|
|
|
|
- [x] **Step 2: 运行失败测试**
|
|
|
|
|
|
|
|
|
|
Expected: FAIL,两个路由尚不存在。
|
|
|
|
|
Run: mvn -q -Dtest=TrainingTaskControllerRestoreDefaultTest test
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 3: 实现两个 DELETE 控制器方法**
|
|
|
|
|
Expected: 编译失败,两个控制器方法尚不存在。
|
|
|
|
|
|
|
|
|
|
- [x] **Step 3: 实现两个 DELETE 控制器方法**
|
|
|
|
|
|
|
|
|
|
每个方法均使用 requireTeacher(request)。成功返回 new ResultEntity(HttpStatus.OK, "Restore success");捕获 IllegalArgumentException 后返回 new ResultEntity(HttpStatus.BAD_REQUEST, e.getMessage())。单任务方法调用:
|
|
|
|
|
|
|
|
|
|
@ -170,14 +173,14 @@ trainingTaskService.restoreClassTaskDefault(teachingClassId, taskKey, user.getUs
|
|
|
|
|
trainingTaskService.restoreClassTasksDefaults(teachingClassId, user.getUserId());
|
|
|
|
|
~~~
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 4: 验证并提交**
|
|
|
|
|
- [x] **Step 4: 验证并提交**
|
|
|
|
|
|
|
|
|
|
Run: mvn -q -DforkCount=0 test
|
|
|
|
|
|
|
|
|
|
Expected: PASS。
|
|
|
|
|
|
|
|
|
|
~~~powershell
|
|
|
|
|
git add src/main/java/com/sztzjy/linkCommerce/controller/stu/TrainingTaskController.java src/test/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImplTest.java
|
|
|
|
|
git add src/main/java/com/sztzjy/linkCommerce/controller/stu/TrainingTaskController.java src/test/java/com/sztzjy/linkCommerce/controller/stu/TrainingTaskControllerRestoreDefaultTest.java
|
|
|
|
|
git commit -m "feat: expose training task default restore APIs"
|
|
|
|
|
~~~
|
|
|
|
|
|
|
|
|
|
@ -192,7 +195,7 @@ git commit -m "feat: expose training task default restore APIs"
|
|
|
|
|
- Consumes: Task 2 的 DELETE 路由。
|
|
|
|
|
- Produces: restoreClassTrainingTaskDefault、restoreClassTrainingTasksDefaults,以及二次确认的页面操作。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 1: 写失败的静态契约测试**
|
|
|
|
|
- [x] **Step 1: 写失败的静态契约测试**
|
|
|
|
|
|
|
|
|
|
创建测试文件,读取 API 和页面源码,断言存在两个恢复 API、两个中文按钮、confirm 调用和 selectedTeachingClass 条件:
|
|
|
|
|
|
|
|
|
|
@ -205,13 +208,13 @@ assert(/proxy\?\.\$modal\?\.confirm/.test(page));
|
|
|
|
|
assert(/v-if="selectedTeachingClass"/.test(page));
|
|
|
|
|
~~~
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 2: 运行失败测试**
|
|
|
|
|
- [x] **Step 2: 运行失败测试**
|
|
|
|
|
|
|
|
|
|
Run: node tests/training-task-restore.static.test.cjs
|
|
|
|
|
|
|
|
|
|
Expected: FAIL,恢复函数和按钮不存在。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 3: 添加 API 函数**
|
|
|
|
|
- [x] **Step 3: 添加 API 函数**
|
|
|
|
|
|
|
|
|
|
~~~javascript
|
|
|
|
|
export function restoreClassTrainingTaskDefault(teachingClassId, taskKey) {
|
|
|
|
|
@ -229,13 +232,13 @@ export function restoreClassTrainingTasksDefaults(teachingClassId) {
|
|
|
|
|
}
|
|
|
|
|
~~~
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 4: 实现恢复交互**
|
|
|
|
|
- [x] **Step 4: 实现恢复交互**
|
|
|
|
|
|
|
|
|
|
导入两个 API 并新增 restoring 状态。教学班筛选区仅当 selectedTeachingClass 存在时显示“恢复本班全部默认任务”;编辑抽屉 footer 仅在非只读时显示“恢复此任务默认内容”。
|
|
|
|
|
|
|
|
|
|
两个处理方法都先调用 proxy.$modal.confirm,文案明确为“仅恢复当前教学班的实训任务内容,不影响学生已提交数据、成绩、进度及其他班级。是否继续?”。确认后分别调用 API,成功提示,单任务关闭抽屉,两个操作均 await queryTasks();取消确认不提示失败。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 5: 验证并提交**
|
|
|
|
|
- [x] **Step 5: 验证并提交**
|
|
|
|
|
|
|
|
|
|
Run: node tests/training-task-restore.static.test.cjs; node tests/school-default-task.static.test.cjs; npm run build:prod
|
|
|
|
|
|
|
|
|
|
@ -255,13 +258,13 @@ git commit -m "feat: restore teaching class task defaults"
|
|
|
|
|
- Consumes: Task 1–3 完成功能。
|
|
|
|
|
- Produces: 可复现验证记录。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 1: 完整后端回归**
|
|
|
|
|
- [x] **Step 1: 完整后端回归**
|
|
|
|
|
|
|
|
|
|
Run: mvn -q -DforkCount=0 test
|
|
|
|
|
|
|
|
|
|
Expected: PASS。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 2: 完整前端回归**
|
|
|
|
|
- [x] **Step 2: 完整前端回归**
|
|
|
|
|
|
|
|
|
|
Run: node tests/training-task-restore.static.test.cjs; node tests/school-default-task.static.test.cjs; npm run build:prod
|
|
|
|
|
|
|
|
|
|
@ -271,7 +274,7 @@ Expected: PASS。
|
|
|
|
|
|
|
|
|
|
以教师账号编辑 A 班一个任务后刷新,确认 A 显示编辑内容;切换 B 班,确认 B 不变。恢复 A 的单任务,确认仅该任务默认化;恢复 A 的全部任务,确认全部默认化。检查 A 班学生端内容同步默认,且既有完成记录、成绩、进度保留。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 4: 提交验证记录**
|
|
|
|
|
- [x] **Step 4: 提交验证记录**
|
|
|
|
|
|
|
|
|
|
~~~powershell
|
|
|
|
|
git add docs/superpowers/plans/2026-07-30-training-task-restore-default.md
|
|
|
|
|
@ -284,3 +287,9 @@ git commit -m "docs: verify training task default restore"
|
|
|
|
|
- Placeholder scan:无 TBD、TODO 或“类似 Task N”等占位说明。
|
|
|
|
|
- Type consistency:后端统一使用 restoreClassTaskDefault / restoreClassTasksDefaults,前端统一使用 restoreClassTrainingTaskDefault / restoreClassTrainingTasksDefaults。
|
|
|
|
|
|
|
|
|
|
## 执行记录(2026-07-30)
|
|
|
|
|
|
|
|
|
|
- 后端服务测试先因恢复方法与 Mapper 删除方法不存在而编译失败,最小实现后转绿。
|
|
|
|
|
- 控制器使用 `TrainingTaskControllerRestoreDefaultTest` 做实际教师 JWT 调用测试,替代原计划的源码文本断言;该测试先因端点方法不存在而编译失败,新增端点后转绿。
|
|
|
|
|
- 最终自动验证:`mvn -q -DforkCount=0 test`、`node tests/training-task-restore.static.test.cjs`、`node tests/school-default-task.static.test.cjs`、`npm run build:prod` 均以退出码 0 结束。
|
|
|
|
|
- 人工验收仍待在运行中的教师端完成:编辑班级 A 的任务、单任务恢复、全班恢复,并核验班级 B 与学生的既有数据未受影响。
|
|
|
|
|
|