diff --git a/src/views/schoolAdmin/trainingTask/index.vue b/src/views/schoolAdmin/trainingTask/index.vue index dae2a16..8aff34b 100644 --- a/src/views/schoolAdmin/trainingTask/index.vue +++ b/src/views/schoolAdmin/trainingTask/index.vue @@ -394,6 +394,27 @@ + +
+
+ + + + +
+ 第一步选择题 + 已配置 {{ stepOneQuestionCount }} 道题 + 暂未配置,学生端第一步将不显示选择题 +
+
+
+ + 设置选择题 + +
+
+ +
@@ -456,6 +477,8 @@ import { updateTrainingTask, uploadTrainingTaskMaterial, } from "@/api/trainingTask"; +import StepOneChoiceQuestionEditor from "@/views/components/StepOneChoiceQuestionEditor.vue"; +import { parseStepOneChoiceQuestions, supportsStepOneChoiceQuestions } from "@/utils/stepOneChoiceQuestions"; const { proxy } = getCurrentInstance(); @@ -464,6 +487,7 @@ const keyword = ref(""); const loading = ref(false); const saving = ref(false); const uploadingField = ref(""); +const choiceEditorVisible = ref(false); // 四类资料槽位:key 对应 taskForm 的 `${key}Name` / `${key}Url` 字段 const materialSlots = [ { key: "material", label: "案例资料" }, @@ -477,6 +501,7 @@ const dialogMode = ref("view"); const currentTaskId = ref(""); const taskForm = reactive(createEmptyTask()); const isReadonly = computed(() => dialogMode.value === "view"); +const stepOneQuestionCount = computed(() => taskForm.stepOneQuestions?.length || 0); const enabledCount = computed(() => tasks.value.filter(t => t.enabled).length); @@ -564,12 +589,17 @@ function createEmptyTask() { guideManualUrl: "", aiManualName: "", aiManualUrl: "", + stepOneQuestions: [], steps: createBuiltinSteps(), sort: 0, enabled: true, }; } +function supportsStepOneChoice(taskKey) { + return supportsStepOneChoiceQuestions(taskKey); +} + function hasMaterial(slotKey) { return isRealMaterial(taskForm[`${slotKey}Name`], taskForm[`${slotKey}Url`]); } @@ -599,6 +629,7 @@ function normalizeTask(task) { guideManualUrl: guideManual.url, aiManualName: aiManual.name, aiManualUrl: aiManual.url, + stepOneQuestions: parseStepOneChoiceQuestions(task.stepOneQuestions), steps: normalizeSteps(parseArray(task.steps, createBuiltinSteps())), sort: task.sort || 0, enabled: task.enabled !== false, @@ -771,6 +802,7 @@ function buildPayload() { guideManualUrl: taskForm.guideManualUrl, aiManualName: taskForm.aiManualName, aiManualUrl: taskForm.aiManualUrl, + stepOneQuestions: JSON.stringify(taskForm.stepOneQuestions || []), sort: taskForm.sort, enabled: taskForm.enabled, }; diff --git a/src/views/teacherEnd/trainingTask/index.vue b/src/views/teacherEnd/trainingTask/index.vue index 484db09..5a53891 100644 --- a/src/views/teacherEnd/trainingTask/index.vue +++ b/src/views/teacherEnd/trainingTask/index.vue @@ -344,6 +344,28 @@
+ +
+
+ + + + +
+ 第一步选择题 + 已配置 {{ stepOneQuestionCount }} 道题 + 暂未配置,学生端第一步将不显示选择题 +
+
+
+ + 设置选择题 + +
+
+ +
@@ -397,6 +419,8 @@ import { listTrainingTasks, listClassTrainingTasks, saveClassTrainingTask, resto import { createStudentDemoSession } from "@/api/studentDemo" import * as indexApi from "@/api/teacher" import useUserStore from "@/store/modules/user" +import StepOneChoiceQuestionEditor from "@/views/components/StepOneChoiceQuestionEditor.vue" +import { parseStepOneChoiceQuestions, supportsStepOneChoiceQuestions } from "@/utils/stepOneChoiceQuestions" const { proxy } = getCurrentInstance() const userStore = useUserStore() @@ -408,6 +432,7 @@ const classesLoading = ref(false) const saving = ref(false) const restoring = ref(false) const uploadingField = ref("") +const choiceEditorVisible = ref(false) // 四类资料槽位:key 对应 taskForm 的 `${key}Name` / `${key}Url` 字段 const materialSlots = [ { key: "material", label: "案例资料" }, @@ -423,6 +448,7 @@ const dialogMode = ref("view") const taskForm = reactive(createEmptyTask()) const currentUserId = computed(() => userStore.userInfo.userId) const isReadonly = computed(() => dialogMode.value === "view") +const stepOneQuestionCount = computed(() => taskForm.stepOneQuestions?.length || 0) const projects = computed(() => [...new Set(tasks.value.map((task) => task.project).filter(Boolean))]) const projectOptions = computed(() => { return projects.value.map((project) => ({ @@ -566,12 +592,17 @@ function createEmptyTask() { guideManualUrl: "", aiManualName: "", aiManualUrl: "", + stepOneQuestions: [], steps: createBuiltinSteps(), sort: 0, enabled: true, } } +function supportsStepOneChoice(taskKey) { + return supportsStepOneChoiceQuestions(taskKey) +} + function hasMaterial(slotKey) { return isRealMaterial(taskForm[`${slotKey}Name`], taskForm[`${slotKey}Url`]) } @@ -601,6 +632,7 @@ function normalizeTask(task) { guideManualUrl: guideManual.url, aiManualName: aiManual.name, aiManualUrl: aiManual.url, + stepOneQuestions: parseStepOneChoiceQuestions(task.stepOneQuestions), steps: normalizeSteps(parseArray(task.steps, createBuiltinSteps())), sort: task.sort || 0, enabled: task.enabled !== false, @@ -833,6 +865,7 @@ function buildPayload() { guideManualUrl: taskForm.guideManualUrl, aiManualName: taskForm.aiManualName, aiManualUrl: taskForm.aiManualUrl, + stepOneQuestions: JSON.stringify(taskForm.stepOneQuestions || []), sort: taskForm.sort, enabled: taskForm.enabled, }