You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.1 KiB

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);
}
};