用户端页面构建完成---待测试

This commit is contained in:
2025-12-25 21:54:52 +08:00
parent de0c7377c9
commit 7b52abfea3
13 changed files with 539 additions and 113 deletions

View File

@@ -11,6 +11,15 @@ export interface ExamTask {
selectionConfig?: string; // JSON string
}
export interface UserExamTask extends ExamTask {
subjectName: string;
totalScore: number;
timeLimitMinutes: number;
usedAttempts: number;
maxAttempts: number;
bestScore: number;
}
export interface ExamTaskUser {
id: string;
taskId: string;
@@ -558,6 +567,13 @@ export class ExamTaskModel {
);
if (!isAssigned) throw new Error('用户未被分派到此任务');
const attemptRow = await get(
`SELECT COUNT(*) as count FROM quiz_records WHERE user_id = ? AND task_id = ?`,
[userId, taskId],
);
const usedAttempts = Number(attemptRow?.count) || 0;
if (usedAttempts >= 3) throw new Error('考试次数已用尽');
const subject = await import('./examSubject').then(({ ExamSubjectModel }) => ExamSubjectModel.findById(task.subjectId));
if (!subject) throw new Error('科目不存在');
@@ -705,27 +721,48 @@ export class ExamTaskModel {
};
}
static async getUserTasks(userId: string): Promise<ExamTask[]> {
static async getUserTasks(userId: string): Promise<UserExamTask[]> {
const now = new Date().toISOString();
const rows = await all(`
SELECT t.*, s.name as subjectName, s.totalScore, s.timeLimitMinutes
SELECT
t.id,
t.name,
t.subject_id as subjectId,
t.start_at as startAt,
t.end_at as endAt,
t.created_at as createdAt,
s.name as subjectName,
s.total_score as totalScore,
s.duration_minutes as timeLimitMinutes,
COALESCE(q.usedAttempts, 0) as usedAttempts,
3 as maxAttempts,
COALESCE(q.bestScore, 0) as bestScore
FROM exam_tasks t
INNER JOIN exam_task_users tu ON t.id = tu.task_id
INNER JOIN exam_subjects s ON t.subject_id = s.id
WHERE tu.user_id = ? AND t.start_at <= ?
ORDER BY t.start_at DESC
`, [userId, now]);
LEFT JOIN (
SELECT task_id, COUNT(*) as usedAttempts, MAX(total_score) as bestScore
FROM quiz_records
WHERE user_id = ?
GROUP BY task_id
) q ON q.task_id = t.id
WHERE tu.user_id = ? AND t.start_at <= ? AND t.end_at >= ?
ORDER BY t.start_at ASC, t.end_at ASC
`, [userId, userId, now, now]);
return rows.map(row => ({
id: row.id,
name: row.name,
subjectId: row.subject_id,
startAt: row.start_at,
endAt: row.end_at,
createdAt: row.created_at,
subjectId: row.subjectId,
startAt: row.startAt,
endAt: row.endAt,
createdAt: row.createdAt,
subjectName: row.subjectName,
totalScore: row.totalScore,
timeLimitMinutes: row.timeLimitMinutes
totalScore: Number(row.totalScore) || 0,
timeLimitMinutes: Number(row.timeLimitMinutes) || 0,
usedAttempts: Number(row.usedAttempts) || 0,
maxAttempts: Number(row.maxAttempts) || 3,
bestScore: Number(row.bestScore) || 0,
}));
}
}