exam11/background/db/paper.js
2025-09-14 11:24:26 +08:00

289 lines
9.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { getDbConnection } = require('./index.js');
// 添加缺少的getUserDbPath导入
const { getUserDbPath } = require('./path.js');
/**
* 查询所有考生试卷记录
* @returns {Promise<Array>} 试卷记录数组
*/
exports.getAllExamineePapers = async function getAllExamineePapers() {
try {
const db = await getDbConnection(getUserDbPath());
const sql = `
SELECT
ep.*,
e.examinee_name,
e.examinee_id_card,
e.examinee_admission_ticket,
-- 关联试卷问题
GROUP_CONCAT(DISTINCT pq.question_name) as question_names,
-- 计算选择题总数
(SELECT COUNT(*) FROM question_choices qc
JOIN paper_questions pq1 ON qc.question_id = pq1.id
WHERE pq1.paper_id = ep.id) as total_choices,
-- 计算填空题总数
(SELECT COUNT(*) FROM question_fill_blanks qfb
JOIN paper_questions pq1 ON qfb.question_id = pq1.id
WHERE pq1.paper_id = ep.id) as total_fill_blanks,
-- 计算已回答的选择题数
(SELECT COUNT(*) FROM question_choices qc
JOIN paper_questions pq1 ON qc.question_id = pq1.id
WHERE pq1.paper_id = ep.id AND qc.examinee_answers != '') as answered_choices,
-- 计算已回答的填空题数
(SELECT COUNT(*) FROM question_fill_blanks qfb
JOIN paper_questions pq1 ON qfb.question_id = pq1.id
WHERE pq1.paper_id = ep.id AND qfb.examinee_answers != '') as answered_fill_blanks
FROM examinee_papers ep
LEFT JOIN examinee e ON ep.examinee_id = e.id
LEFT JOIN paper_questions pq ON ep.id = pq.paper_id
GROUP BY ep.id
ORDER BY ep.paper_start_time DESC
`;
const papers = await db.allAsync(sql);
return papers;
} catch (error) {
console.error('查询所有考生试卷记录失败:', error);
throw error;
}
};
/**
* 根据试卷ID查询试卷详情
* @param {number} paperId - 试卷ID
* @returns {Promise<Object|null>} 试卷详情对象
*/
exports.getExamineePaperById = async function getExamineePaperById(paperId) {
try {
const db = await getDbConnection(getUserDbPath());
const sql = `
SELECT
ep.*,
e.examinee_name,
e.examinee_id_card,
e.examinee_admission_ticket,
-- 获取试卷问题详情
pq.*,
-- 获取选择题详情
qc.id as choice_id,
qc.question_id,
qc.choice_description,
qc.choice_type,
qc.choice_options,
qc.correct_answers,
qc.examinee_answers,
qc.score as choice_score,
qc.score_real as choice_score_real,
-- 获取填空题详情
qfb.id as blank_id,
qfb.question_id as blank_question_id,
qfb.blank_description,
qfb.blank_count,
qfb.correct_answers as blank_correct_answers,
qfb.examinee_answers as blank_examinee_answers,
qfb.score as blank_score,
qfb.score_real as blank_score_real
FROM examinee_papers ep
LEFT JOIN examinee e ON ep.examinee_id = e.id
LEFT JOIN paper_questions pq ON ep.id = pq.paper_id
LEFT JOIN question_choices qc ON pq.id = qc.question_id
LEFT JOIN question_fill_blanks qfb ON pq.id = qfb.question_id
WHERE ep.id = ?
`;
const papers = await db.allAsync(sql, [paperId]);
// 格式化结果将问题组织到paper对象中
if (papers.length > 0) {
const paper = {
...papers[0],
questions: [],
// 直接添加question_choices和question_fill_blanks数组方便前端使用
question_choices: [],
question_fill_blanks: []
};
// 提取唯一的问题并添加相关的选择题和填空题
const questionMap = new Map();
papers.forEach(row => {
if (row.question_name && !questionMap.has(row.question_id)) {
questionMap.set(row.question_id, {
id: row.question_id,
question_name: row.question_name,
question_description: row.question_description,
question_type: row.question_type,
question_choices: [],
question_fill_blanks: []
});
}
// 添加选择题
if (row.choice_id) {
const question = questionMap.get(row.question_id);
const choiceData = {
id: row.choice_id,
question_id: row.question_id,
question_content: row.question_description,
option_a: row.choice_options?.split('|')[0] || '',
option_b: row.choice_options?.split('|')[1] || '',
option_c: row.choice_options?.split('|')[2] || '',
option_d: row.choice_options?.split('|')[3] || '',
correct_answer: row.correct_answers,
user_answer: row.examinee_answers,
score: row.choice_score,
user_score: row.choice_score_real
};
// 添加检查确保question存在再push到question.question_choices
if (question) {
question.question_choices.push(choiceData);
}
// 同时添加到顶层的question_choices数组
paper.question_choices.push(choiceData);
}
// 添加填空题
if (row.blank_id) {
const question = questionMap.get(row.blank_question_id);
const blankData = {
id: row.blank_id,
question_id: row.blank_question_id,
question_content: row.question_description,
blank_count: row.blank_count,
correct_answers: row.blank_correct_answers ? JSON.parse(row.blank_correct_answers) : [],
user_answers: row.blank_examinee_answers ? JSON.parse(row.blank_examinee_answers) : [],
score: row.blank_score,
user_score: row.blank_score_real
};
if (question) {
question.question_fill_blanks.push(blankData);
}
// 同时添加到顶层的question_fill_blanks数组
paper.question_fill_blanks.push(blankData);
}
});
paper.questions = Array.from(questionMap.values());
return paper;
}
return null;
} catch (error) {
console.error(`根据ID查询试卷详情失败 (ID: ${paperId}):`, error);
throw error;
}
};
/**
* 查询考生的试卷记录
* @param {number} examineeId - 考生ID
* @returns {Promise<Array>} 该考生的试卷记录数组
*/
exports.getExamineePapersByExamineeId = async function getExamineePapersByExamineeId(examineeId) {
try {
const db = await getDbConnection(getUserDbPath());
const sql = `
SELECT
ep.*,
e.examinee_name,
e.examinee_id_card,
e.examinee_admission_ticket,
-- 关联试卷问题
GROUP_CONCAT(DISTINCT pq.question_name) as question_names,
-- 计算选择题总数
(SELECT COUNT(*) FROM question_choices qc
JOIN paper_questions pq1 ON qc.question_id = pq1.id
WHERE pq1.paper_id = ep.id) as total_choices,
-- 计算填空题总数
(SELECT COUNT(*) FROM question_fill_blanks qfb
JOIN paper_questions pq1 ON qfb.question_id = pq1.id
WHERE pq1.paper_id = ep.id) as total_fill_blanks,
-- 计算已回答的选择题数
(SELECT COUNT(*) FROM question_choices qc
JOIN paper_questions pq1 ON qc.question_id = pq1.id
WHERE pq1.paper_id = ep.id AND qc.examinee_answers != '') as answered_choices,
-- 计算已回答的填空题数
(SELECT COUNT(*) FROM question_fill_blanks qfb
JOIN paper_questions pq1 ON qfb.question_id = pq1.id
WHERE pq1.paper_id = ep.id AND qfb.examinee_answers != '') as answered_fill_blanks
FROM examinee_papers ep
LEFT JOIN examinee e ON ep.examinee_id = e.id
LEFT JOIN paper_questions pq ON ep.id = pq.paper_id
WHERE ep.examinee_id = ?
GROUP BY ep.id
ORDER BY ep.paper_start_time DESC
`;
const papers = await db.allAsync(sql, [examineeId]);
return papers;
} catch (error) {
console.error(`查询考生试卷记录失败 (ExamineeID: ${examineeId}):`, error);
throw error;
}
};
/**
* 根据状态查询试卷记录
* @param {number} status - 试卷状态
* @returns {Promise<Array>} 符合条件的试卷记录数组
*/
exports.getExamineePapersByStatus = async function getExamineePapersByStatus(status) {
try {
const db = await getDbConnection(getUserDbPath());
const sql = `
SELECT
ep.*,
e.examinee_name,
e.examinee_id_card,
e.examinee_admission_ticket,
-- 关联试卷问题
GROUP_CONCAT(DISTINCT pq.question_name) as question_names,
-- 计算选择题总数
(SELECT COUNT(*) FROM question_choices qc
JOIN paper_questions pq1 ON qc.question_id = pq1.id
WHERE pq1.paper_id = ep.id) as total_choices,
-- 计算填空题总数
(SELECT COUNT(*) FROM question_fill_blanks qfb
JOIN paper_questions pq1 ON qfb.question_id = pq1.id
WHERE pq1.paper_id = ep.id) as total_fill_blanks,
-- 计算已回答的选择题数
(SELECT COUNT(*) FROM question_choices qc
JOIN paper_questions pq1 ON qc.question_id = pq1.id
WHERE pq1.paper_id = ep.id AND qc.examinee_answers != '') as answered_choices,
-- 计算已回答的填空题数
(SELECT COUNT(*) FROM question_fill_blanks qfb
JOIN paper_questions pq1 ON qfb.question_id = pq1.id
WHERE pq1.paper_id = ep.id AND qfb.examinee_answers != '') as answered_fill_blanks
FROM examinee_papers ep
LEFT JOIN examinee e ON ep.examinee_id = e.id
LEFT JOIN paper_questions pq ON ep.id = pq.paper_id
WHERE ep.paper_status = ?
GROUP BY ep.id
ORDER BY ep.paper_start_time DESC
`;
const papers = await db.allAsync(sql, [status]);
return papers;
} catch (error) {
console.error(`根据状态查询试卷记录失败 (Status: ${status}):`, error);
throw error;
}
}