- formatCorrectAnswer: 增加空值保护和 try-catch - checkObjectiveAnswer: 增加 options 数组校验 - recordWrongAnswer: 使用 dialogQuestion 快照,增加错误处理
This commit is contained in:
@@ -772,32 +772,48 @@ const submitAnswer = () => {
|
|||||||
const checkObjectiveAnswer = (): boolean => {
|
const checkObjectiveAnswer = (): boolean => {
|
||||||
const q = currentQuestion.value
|
const q = currentQuestion.value
|
||||||
|
|
||||||
if (q.type === 'single' || q.type === 'multiple') {
|
if (!q) {
|
||||||
const correctIndexes = q.options
|
console.error('checkObjectiveAnswer: currentQuestion 为空')
|
||||||
.map((opt: any, idx: number) => opt.isCorrect ? idx : -1)
|
return false
|
||||||
.filter((idx: number) => idx !== -1)
|
|
||||||
|
|
||||||
// 调试日志:显示正确答案索引和用户选择
|
|
||||||
console.log(`🔍 客观题判断 - 题目: "${q.title.substring(0, 30)}..."`)
|
|
||||||
console.log(` 选项详情:`, q.options.map((opt: any, idx: number) => ({
|
|
||||||
index: idx,
|
|
||||||
letter: String.fromCharCode(65 + idx),
|
|
||||||
isCorrect: opt.isCorrect,
|
|
||||||
content: opt.content?.substring(0, 20) + '...'
|
|
||||||
})))
|
|
||||||
console.log(` 正确答案索引: [${correctIndexes.join(', ')}]`)
|
|
||||||
console.log(` 用户选择索引: [${userAnswer.selected.join(', ')}]`)
|
|
||||||
|
|
||||||
const isCorrect = JSON.stringify(userAnswer.selected.sort()) === JSON.stringify(correctIndexes.sort())
|
|
||||||
console.log(` 判断结果: ${isCorrect ? '✅正确' : '❌错误'}`)
|
|
||||||
|
|
||||||
return isCorrect
|
|
||||||
} else if (q.type === 'judge') {
|
|
||||||
console.log(`🔍 判断题判断 - 正确答案: ${q.correctAnswer}, 用户答案: ${userAnswer.judge}`)
|
|
||||||
return userAnswer.judge === q.correctAnswer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
try {
|
||||||
|
if (q.type === 'single' || q.type === 'multiple') {
|
||||||
|
// 增加空值保护
|
||||||
|
if (!q.options || !Array.isArray(q.options)) {
|
||||||
|
console.error('checkObjectiveAnswer: options 无效', q.options)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const correctIndexes = q.options
|
||||||
|
.map((opt: any, idx: number) => opt?.isCorrect ? idx : -1)
|
||||||
|
.filter((idx: number) => idx !== -1)
|
||||||
|
|
||||||
|
// 调试日志:显示正确答案索引和用户选择
|
||||||
|
console.log(`🔍 客观题判断 - 题目: "${q.title?.substring(0, 30) || '无标题'}..."`)
|
||||||
|
console.log(` 选项详情:`, q.options.map((opt: any, idx: number) => ({
|
||||||
|
index: idx,
|
||||||
|
letter: String.fromCharCode(65 + idx),
|
||||||
|
isCorrect: opt?.isCorrect,
|
||||||
|
content: opt?.content?.substring(0, 20) + '...'
|
||||||
|
})))
|
||||||
|
console.log(` 正确答案索引: [${correctIndexes.join(', ')}]`)
|
||||||
|
console.log(` 用户选择索引: [${userAnswer.selected.join(', ')}]`)
|
||||||
|
|
||||||
|
const isCorrect = JSON.stringify([...userAnswer.selected].sort()) === JSON.stringify([...correctIndexes].sort())
|
||||||
|
console.log(` 判断结果: ${isCorrect ? '✅正确' : '❌错误'}`)
|
||||||
|
|
||||||
|
return isCorrect
|
||||||
|
} else if (q.type === 'judge') {
|
||||||
|
console.log(`🔍 判断题判断 - 正确答案: ${q.correctAnswer}, 用户答案: ${userAnswer.judge}`)
|
||||||
|
return userAnswer.judge === q.correctAnswer
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
} catch (error) {
|
||||||
|
console.error('checkObjectiveAnswer 出错:', error)
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -863,18 +879,29 @@ const checkSubjectiveAnswer = async (question: any): Promise<boolean> => {
|
|||||||
* 记录错题到数据库
|
* 记录错题到数据库
|
||||||
*/
|
*/
|
||||||
const recordWrongAnswer = async () => {
|
const recordWrongAnswer = async () => {
|
||||||
const q = currentQuestion.value
|
// 使用 dialogQuestion(已保存的题目快照)而不是 currentQuestion
|
||||||
|
const q = dialogQuestion.value || currentQuestion.value
|
||||||
|
|
||||||
|
if (!q) {
|
||||||
|
console.error('recordWrongAnswer: 题目数据为空')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 获取用户答案
|
// 获取用户答案
|
||||||
let userAnswerText = ''
|
let userAnswerText = ''
|
||||||
if (q.type === 'single' || q.type === 'multiple') {
|
try {
|
||||||
userAnswerText = userAnswer.selected.map(idx => String.fromCharCode(65 + idx)).join(',')
|
if (q.type === 'single' || q.type === 'multiple') {
|
||||||
} else if (q.type === 'judge') {
|
userAnswerText = userAnswer.selected.map(idx => String.fromCharCode(65 + idx)).join(',')
|
||||||
userAnswerText = userAnswer.judge ? '正确' : '错误'
|
} else if (q.type === 'judge') {
|
||||||
} else if (q.type === 'blank') {
|
userAnswerText = userAnswer.judge ? '正确' : '错误'
|
||||||
userAnswerText = userAnswer.blank
|
} else if (q.type === 'blank') {
|
||||||
} else if (q.type === 'essay') {
|
userAnswerText = userAnswer.blank || ''
|
||||||
userAnswerText = userAnswer.essay
|
} else if (q.type === 'essay') {
|
||||||
|
userAnswerText = userAnswer.essay || ''
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('获取用户答案失败:', e)
|
||||||
|
userAnswerText = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -883,10 +910,10 @@ const recordWrongAnswer = async () => {
|
|||||||
round: currentRound.value, // 记录当前轮次
|
round: currentRound.value, // 记录当前轮次
|
||||||
question_id: null, // AI生成的题目没有question_id
|
question_id: null, // AI生成的题目没有question_id
|
||||||
knowledge_point_id: q.knowledge_point_id || null,
|
knowledge_point_id: q.knowledge_point_id || null,
|
||||||
question_content: q.title,
|
question_content: q.title || '',
|
||||||
correct_answer: formatCorrectAnswer(q),
|
correct_answer: formatCorrectAnswer(q),
|
||||||
user_answer: userAnswerText,
|
user_answer: userAnswerText,
|
||||||
question_type: q.type // 新增:记录题型
|
question_type: q.type || '' // 新增:记录题型
|
||||||
})
|
})
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('记录错题失败:', error)
|
console.error('记录错题失败:', error)
|
||||||
@@ -1181,35 +1208,45 @@ const renderMarkdown = (content: string): string => {
|
|||||||
* 格式化正确答案
|
* 格式化正确答案
|
||||||
*/
|
*/
|
||||||
const formatCorrectAnswer = (question: any) => {
|
const formatCorrectAnswer = (question: any) => {
|
||||||
if (question.type === 'single' || question.type === 'multiple') {
|
if (!question) return ''
|
||||||
// 如果有correctAnswer字段(来自Dify的原始correct)
|
|
||||||
if (question.correctAnswer) {
|
try {
|
||||||
// 多选题格式优化:将 "A:xxx、B:xxx" 或 "A:xxx,B:xxx" 改为换行显示
|
if (question.type === 'single' || question.type === 'multiple') {
|
||||||
// 使用更精确的匹配:提取完整的选项格式 X:内容
|
// 如果有correctAnswer字段(来自Dify的原始correct)
|
||||||
const optionPattern = /([A-Za-z][::])([^A-Za-z]*?)(?=(?:[,、]?[A-Za-z][::])|$)/g
|
if (question.correctAnswer) {
|
||||||
const matches = [...question.correctAnswer.matchAll(optionPattern)]
|
// 多选题格式优化:将 "A:xxx、B:xxx" 或 "A:xxx,B:xxx" 改为换行显示
|
||||||
if (matches.length > 1) {
|
// 使用更精确的匹配:提取完整的选项格式 X:内容
|
||||||
// 多个选项,换行显示
|
const optionPattern = /([A-Za-z][::])([^A-Za-z]*?)(?=(?:[,、]?[A-Za-z][::])|$)/g
|
||||||
return matches.map(m => m[1] + m[2].trim()).join('\n')
|
const matches = [...String(question.correctAnswer).matchAll(optionPattern)]
|
||||||
|
if (matches.length > 1) {
|
||||||
|
// 多个选项,换行显示
|
||||||
|
return matches.map(m => m[1] + m[2].trim()).join('\n')
|
||||||
|
}
|
||||||
|
return question.correctAnswer
|
||||||
}
|
}
|
||||||
return question.correctAnswer
|
// 否则从options中提取(增加空值保护)
|
||||||
|
if (!question.options || !Array.isArray(question.options)) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
return question.options
|
||||||
|
.map((opt: any, idx: number) => opt?.isCorrect ? String.fromCharCode(65 + idx) : null)
|
||||||
|
.filter((v: any) => v)
|
||||||
|
.join('、')
|
||||||
|
} else if (question.type === 'judge') {
|
||||||
|
// 优先使用correctAnswerText(Dify原始值:"正确"或"错误")
|
||||||
|
if (question.correctAnswerText) {
|
||||||
|
return question.correctAnswerText
|
||||||
|
}
|
||||||
|
// 备用:从boolean转换
|
||||||
|
return question.correctAnswer ? '正确' : '错误'
|
||||||
|
} else if (question.type === 'blank' || question.type === 'essay') {
|
||||||
|
return question.correctAnswer || ''
|
||||||
}
|
}
|
||||||
// 否则从options中提取
|
return ''
|
||||||
return question.options
|
} catch (error) {
|
||||||
.map((opt: any, idx: number) => opt.isCorrect ? String.fromCharCode(65 + idx) : null)
|
console.error('formatCorrectAnswer 出错:', error, question)
|
||||||
.filter((v: any) => v)
|
|
||||||
.join('、')
|
|
||||||
} else if (question.type === 'judge') {
|
|
||||||
// 优先使用correctAnswerText(Dify原始值:"正确"或"错误")
|
|
||||||
if (question.correctAnswerText) {
|
|
||||||
return question.correctAnswerText
|
|
||||||
}
|
|
||||||
// 备用:从boolean转换
|
|
||||||
return question.correctAnswer ? '正确' : '错误'
|
|
||||||
} else if (question.type === 'blank' || question.type === 'essay') {
|
|
||||||
return question.correctAnswer || ''
|
return question.correctAnswer || ''
|
||||||
}
|
}
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user