fix: address code review issues in interactive exercises
Some checks failed
Deploy / deploy (build, debian, 22, /root/OJDeploy/data/clientnext) (push) Has been cancelled
Deploy / deploy (build:staging, school, 8822, /root/OJ/data/dist) (push) Has been cancelled

- ExerciseSort: replace unbounded shuffle recursion with deterministic swap
- ExerciseManager: add sortQuestion field so sort exercises have custom questions
- index.vue: use Promise.allSettled so exercise fetch failure doesn't break lesson content
- ExerciseManager: guard mcqAnswer index after option deletion

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-23 06:35:45 -06:00
parent 67a23c51c8
commit f00dab9c6d
3 changed files with 13 additions and 6 deletions

View File

@@ -21,6 +21,7 @@ const mcqQuestion = ref("")
const mcqOptions = ref(["", ""])
const mcqAnswer = ref(0)
const sortQuestion = ref("")
const sortCode = ref("")
async function load() {
@@ -36,6 +37,7 @@ function openCreate() {
mcqQuestion.value = ""
mcqOptions.value = ["", ""]
mcqAnswer.value = 0
sortQuestion.value = ""
sortCode.value = ""
showForm.value = true
}
@@ -51,6 +53,7 @@ function openEdit(ex: Exercise) {
mcqAnswer.value = d.answer
} else {
const d = ex.data as ExerciseSortData
sortQuestion.value = d.question
sortCode.value = d.lines.join("\n")
}
showForm.value = true
@@ -61,7 +64,7 @@ async function save() {
formType.value === "mcq"
? { question: mcqQuestion.value, options: mcqOptions.value, answer: mcqAnswer.value }
: {
question: "将下列代码行排列为正确顺序",
question: sortQuestion.value || "将下列代码行排列为正确顺序",
lines: sortCode.value.split("\n").filter((l) => l.trim() !== ""),
}
@@ -179,7 +182,7 @@ function typeName(type: string) {
<n-button
size="small"
:disabled="mcqOptions.length <= 2"
@click="mcqOptions.splice(i, 1)"
@click="() => { mcqOptions.splice(i, 1); if (mcqAnswer >= mcqOptions.length) mcqAnswer = mcqOptions.length - 1 }"
>
</n-button>
@@ -190,6 +193,9 @@ function typeName(type: string) {
</template>
<template v-else>
<n-form-item label="题目">
<n-input v-model:value="sortQuestion" type="textarea" :rows="2" placeholder="将下列代码行排列为正确顺序" />
</n-form-item>
<n-form-item label="正确代码(每行将自动成为一道排序项)">
<n-input
v-model:value="sortCode"

View File

@@ -22,7 +22,8 @@ function shuffle(arr: LineItem[]): LineItem[] {
;[a[i], a[j]] = [a[j], a[i]]
}
const isCorrect = a.every((item, i) => item.originalIdx === i)
return isCorrect && a.length > 1 ? shuffle(arr) : a
if (isCorrect && a.length > 1) [a[0], a[1]] = [a[1], a[0]]
return a
}
function init() {

View File

@@ -147,9 +147,9 @@ async function init() {
titles.value = res1.data
if (titles.value.length === 0) return
const id = titles.value[step.value - 1].id
const [res2, exs] = await Promise.all([getTutorial(id), getExercises(id)])
tutorial.value = res2.data
exercises.value = exs
const [res2, exs] = await Promise.allSettled([getTutorial(id), getExercises(id)])
if (res2.status === "fulfilled") tutorial.value = res2.value.data
exercises.value = exs.status === "fulfilled" ? exs.value : []
}
watch(