const Exam = require('../models/Exam'); // 获取所有考试 exports.getExams = async (req, res, next) => { try { const exams = await Exam.find({ isActive: true }) .select('-questions.answer') // 不返回答案 .populate('createdBy', 'username'); res.json(exams); } catch (err) { next(err); } }; // 获取单个考试详情 exports.getExam = async (req, res, next) => { try { const exam = await Exam.findById(req.params.id) .select('-questions.answer') // 不返回答案 .populate('createdBy', 'username'); if (!exam) { return res.status(404).json({ message: 'Exam not found' }); } res.json(exam); } catch (err) { next(err); } }; // 创建新考试 (教师/管理员) exports.createExam = async (req, res, next) => { try { const { title, description, duration, questions } = req.body; const exam = new Exam({ title, description, duration, questions, createdBy: req.user.id }); await exam.save(); res.status(201).json(exam); } catch (err) { next(err); } }; // 验证考试答案 exports.validateAnswers = async (req, res, next) => { try { const { answers } = req.body; // 获取考试(包含正确答案) const exam = await Exam.findById(req.params.id); if (!exam) { return res.status(404).json({ message: 'Exam not found' }); } // 计算分数 let totalScore = 0; const results = exam.questions.map(question => { const userAnswer = answers[question._id]; let isCorrect = false; let score = 0; if (question.type === 'text') { // 简答题默认给一半分 if (userAnswer && userAnswer.trim().length > 0) { isCorrect = true; score = question.score / 2; } } else if (Array.isArray(question.answer)) { // 多选题 const correctAnswers = [...question.answer].sort().toString(); const userAns = [...userAnswer].sort().toString(); isCorrect = correctAnswers === userAns; score = isCorrect ? question.score : 0; } else { // 单选题 isCorrect = userAnswer === question.answer; score = isCorrect ? question.score : 0; } totalScore += score; return { questionId: question._id, question: question.question, userAnswer, correctAnswer: question.answer, isCorrect, score }; }); res.json({ examId: exam._id, totalScore, maxScore: exam.questions.reduce((sum, q) => sum + q.score, 0), results }); } catch (err) { next(err); } };