fix(exams): fix composite question sub-questions not showing in preview

- Fix buildQuestion in editor-to-structure.ts: recursively detect nested
  questionBlock nodes as subQuestions (composite questions now properly
  extract child questions instead of treating them as plain text)
- Fix buildQuestionBlock in actions.ts: AI auto-mark now generates nested
  questionBlock nodes for sub-questions instead of plain paragraphs, so
  they are properly structured and detectable by the parser
- Rewrite ExamPreview component with proper layout:
  - Question header: number + type label badge + score
  - Indented question text and options
  - Composite sub-questions shown in nested block with left border
  - Image thumbnails
  - Empty state message
  - Title centered at top
  - Group titles with bottom border
This commit is contained in:
SpecialX
2026-06-24 13:54:24 +08:00
parent 7380f1e6c8
commit f260720443
3 changed files with 130 additions and 37 deletions

View File

@@ -1137,17 +1137,28 @@ const buildTiptapDocFromAiResponse = (data: unknown): unknown => {
})
}
// 子题(阅读理解的小题)
// 子题(阅读理解的小题)—— 生成为嵌套的 questionBlock,便于编辑器层级展示与解析
const subQuestions = Array.isArray(contentNode.subQuestions)
? contentNode.subQuestions
: []
for (const sub of subQuestions) {
if (!isRecord(sub)) continue
const subText = typeof sub.text === "string" ? sub.text : ""
const subScore = typeof sub.score === "number" ? sub.score : 0
if (subText) {
// 子题文本按行拆分为段落
const subLines = subText.split("\n").filter((l) => l.trim().length > 0)
const subInner =
subLines.length > 0
? subLines.map((line) => ({
type: "paragraph",
content: [{ type: "text", text: line }],
}))
: [{ type: "paragraph", content: [{ type: "text", text: " " }] }]
inner.push({
type: "paragraph",
content: [{ type: "text", text: subText }],
type: "questionBlock",
attrs: { questionId: "", type: "text", score: subScore },
content: subInner,
})
}
}