diff --git a/src/api/trainingTask.js b/src/api/trainingTask.js index 95b4004..fe35e08 100644 --- a/src/api/trainingTask.js +++ b/src/api/trainingTask.js @@ -84,3 +84,17 @@ export function saveClassTrainingTask(teachingClassId, taskKey, data) { data, }); } + +export function restoreClassTrainingTaskDefault(teachingClassId, taskKey) { + return request({ + url: `/api/training-tasks/classes/${teachingClassId}/${taskKey}/override`, + method: "delete", + }); +} + +export function restoreClassTrainingTasksDefaults(teachingClassId) { + return request({ + url: `/api/training-tasks/classes/${teachingClassId}/overrides`, + method: "delete", + }); +} diff --git a/src/views/teacherEnd/trainingTask/index.vue b/src/views/teacherEnd/trainingTask/index.vue index df74f4f..ed902f4 100644 --- a/src/views/teacherEnd/trainingTask/index.vue +++ b/src/views/teacherEnd/trainingTask/index.vue @@ -25,6 +25,16 @@
班级配置 默认任务 + + 恢复本班全部默认任务 +
@@ -186,6 +196,15 @@ @@ -198,6 +217,8 @@ import { listTrainingTasks, listClassTrainingTasks, saveClassTrainingTask, + restoreClassTrainingTaskDefault, + restoreClassTrainingTasksDefaults, uploadTrainingTaskMaterial, } from "@/api/trainingTask"; import * as indexApi from "@/api/teacher"; @@ -211,6 +232,7 @@ const keyword = ref(""); const loading = ref(false); const classesLoading = ref(false); const saving = ref(false); +const restoring = ref(false); const materialUploading = ref(false); const tasks = ref([]); const classList = ref([]); @@ -480,6 +502,47 @@ async function submitTask() { } } +async function restoreTaskDefault() { + if (!selectedTeachingClass.value || !taskForm.taskKey) return; + const confirmed = await confirmRestoreDefault("恢复此任务默认内容"); + if (!confirmed) return; + restoring.value = true; + try { + await restoreClassTrainingTaskDefault(selectedTeachingClassId.value, taskForm.taskKey); + dialogVisible.value = false; + proxy?.$modal?.msgSuccess("已恢复此任务的默认内容"); + await queryTasks(); + } finally { + restoring.value = false; + } +} + +async function restoreAllTasksDefaults() { + if (!selectedTeachingClass.value) return; + const confirmed = await confirmRestoreDefault("恢复本班全部默认任务"); + if (!confirmed) return; + restoring.value = true; + try { + await restoreClassTrainingTasksDefaults(selectedTeachingClassId.value); + proxy?.$modal?.msgSuccess("已恢复本班全部默认任务"); + await queryTasks(); + } finally { + restoring.value = false; + } +} + +async function confirmRestoreDefault(action) { + try { + await proxy?.$modal?.confirm( + `确认${action}吗?仅恢复当前教学班的实训任务内容,不影响学生已提交数据、成绩、进度及其他班级。`, + "确认恢复默认内容" + ); + return true; + } catch (error) { + return false; + } +} + function buildPayload() { return { projectName: taskForm.project, diff --git a/tests/training-task-restore.static.test.cjs b/tests/training-task-restore.static.test.cjs new file mode 100644 index 0000000..4d1e326 --- /dev/null +++ b/tests/training-task-restore.static.test.cjs @@ -0,0 +1,20 @@ +const assert = require("assert"); +const fs = require("fs"); +const path = require("path"); + +const root = path.resolve(__dirname, ".."); +const read = (file) => fs.readFileSync(path.join(root, file), "utf8"); + +const api = read("src/api/trainingTask.js"); +const page = read("src/views/teacherEnd/trainingTask/index.vue"); + +assert(/export function restoreClassTrainingTaskDefault/.test(api)); +assert(/export function restoreClassTrainingTasksDefaults/.test(api)); +assert(/\/classes\/\$\{teachingClassId\}\/\$\{taskKey\}\/override/.test(api)); +assert(/\/classes\/\$\{teachingClassId\}\/overrides/.test(api)); +assert(/恢复此任务默认内容/.test(page)); +assert(/恢复本班全部默认任务/.test(page)); +assert(/proxy\?\.\$modal\?\.confirm/.test(page)); +assert(/v-if="selectedTeachingClass"/.test(page)); + +console.log("training task default restore front-end contract passed");