@@ -27,10 +65,237 @@

加载中...

+ + + + @@ -188,6 +503,7 @@ import { onMounted, ref, watch, computed } from 'vue' import { useQuestionStore } from './stores/questions' import { storeToRefs } from 'pinia' +import { ElMessage, ElMessageBox } from 'element-plus' const store = useQuestionStore() @@ -199,12 +515,22 @@ const { currentQuestion, currentTopicQuestions, showAnswer, - topicStats + topicStats, + examMode, + examCurrentIndex, + examAnswers, + examSubmittedQuestions, + examProgress, + examScore, + examPassed, + examFinished } = storeToRefs(store) const jumpQuestionNum = ref(1) const pdfDialogVisible = ref(false) const isMaximized = ref(false) +const selectedAnswer = ref('') +const tipsDialogVisible = ref(false) const currentPdfUrl = computed(() => { const topicNum = String(currentTopic.value).padStart(2, '0') @@ -215,6 +541,10 @@ watch(currentQuestionIndex, (newIndex) => { jumpQuestionNum.value = newIndex + 1 }) +watch(examCurrentIndex, () => { + selectedAnswer.value = examAnswers.value.get(examCurrentIndex.value) || '' +}) + onMounted(() => { store.loadQuestions() }) @@ -255,6 +585,173 @@ function closePdfDialog() { pdfDialogVisible.value = false isMaximized.value = false } + +// 考试模式相关函数 +function handleStartExam() { + ElMessageBox.confirm( + '考试将随机抽取50道题目,包含判断题、拖拽题、排序题、单选题和特殊Case题。答对40道及以上为合格。确定开始考试吗?', + '开始考试', + { + confirmButtonText: '开始考试', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + store.startExam() + ElMessage.success('考试开始!祝你成功!') + }).catch(() => { + // 用户取消 + }) +} + +function handleShowTips() { + tipsDialogVisible.value = true +} + +function handleSelectAnswer(optionLabel: string) { + if (examFinished.value) return + + // 多选题逻辑 + const currentAns = selectedAnswer.value + const question = currentQuestion.value + + if (!question) return + + // 判断是否是多选题 + const isMultiChoice = question.answer.length > 1 + + if (isMultiChoice) { + // 多选题:切换选项 + if (currentAns.includes(optionLabel)) { + selectedAnswer.value = currentAns.split('').filter(l => l !== optionLabel).sort().join('') + } else { + selectedAnswer.value = (currentAns + optionLabel).split('').sort().join('') + } + } else { + // 单选题:直接选择 + selectedAnswer.value = optionLabel + } + + store.submitExamAnswer(selectedAnswer.value) +} + +function isOptionSelected(optionLabel: string): boolean { + return selectedAnswer.value.includes(optionLabel) +} + +function handleExamNextQuestion() { + // 如果当前题目未提交且已作答,先提交显示答案 + if (!examSubmittedQuestions.value.has(examCurrentIndex.value) && selectedAnswer.value) { + store.submitCurrentQuestion() + return + } + + // 如果已提交,跳转到下一题 + store.examNextQuestion() +} + +function handleExamPrevQuestion() { + store.examPrevQuestion() +} + +function handleExamJumpToQuestion(index: number) { + store.examJumpToQuestion(index) +} + +function handleFinishExam() { + // 先提交当前题目(如果已作答) + if (!examSubmittedQuestions.value.has(examCurrentIndex.value) && selectedAnswer.value) { + store.submitCurrentQuestion() + return + } + + const unanswered = 50 - examProgress.value + + if (unanswered > 0) { + ElMessageBox.confirm( + `你还有 ${unanswered} 道题目未作答,确定要提交考试吗?`, + '确认提交', + { + confirmButtonText: '确定提交', + cancelButtonText: '继续答题', + type: 'warning' + } + ).then(() => { + store.finishExam() + }).catch(() => { + // 用户取消 + }) + } else { + ElMessageBox.confirm( + '确定要提交考试吗?提交后将无法修改答案。', + '确认提交', + { + confirmButtonText: '确定提交', + cancelButtonText: '继续答题', + type: 'warning' + } + ).then(() => { + store.finishExam() + }).catch(() => { + // 用户取消 + }) + } +} + +function handleReviewExam() { + store.examCurrentIndex = 0 + store.examFinished = false +} + +function handleRetakeExam() { + store.exitExam() + handleStartExam() +} + +function handleExitExam() { + if (!examFinished.value) { + ElMessageBox.confirm( + '确定要退出考试吗?当前答题进度将不会保存。', + '退出考试', + { + confirmButtonText: '确定退出', + cancelButtonText: '继续考试', + type: 'warning' + } + ).then(() => { + store.exitExam() + ElMessage.info('已退出考试') + }).catch(() => { + // 用户取消 + }) + } else { + store.exitExam() + } +} + +function getQuestionTypeLabel(type?: string): string { + const labels: Record = { + 'yes_no': '判断题', + 'drag_drop': '拖拽题', + 'order': '排序题', + 'case': '特殊Case题', + 'single': '单选题', + 'multi': '多选题' + } + return labels[type || 'single'] || '选择题' +} + +function getQuestionTypeTag(type?: string): '' | 'success' | 'warning' | 'info' | 'danger' { + const tags: Record = { + 'yes_no': 'info', + 'drag_drop': 'warning', + 'order': 'warning', + 'case': 'danger', + 'single': 'success', + 'multi': '' + } + return tags[type || 'single'] || '' +}