新增文本题库导入功能,题目新增“解析”字段

This commit is contained in:
2025-12-25 00:15:14 +08:00
parent e2a1555b46
commit dc9fc169ec
30 changed files with 1386 additions and 165 deletions

View File

@@ -318,6 +318,89 @@ export class ExamTaskModel {
return { data, total };
}
static async getAllTasksWithStatsPaged(
input: {
page: number;
limit: number;
status?: 'completed' | 'ongoing' | 'notStarted';
endAtStart?: string;
endAtEnd?: string;
},
): Promise<{ data: Array<ActiveTaskStat & { status: '已完成' | '进行中' | '未开始' }>; total: number }> {
const nowIso = new Date().toISOString();
const nowMs = Date.now();
const offset = (input.page - 1) * input.limit;
const whereParts: string[] = [];
const params: any[] = [];
if (input.status === 'completed') {
whereParts.push('t.end_at < ?');
params.push(nowIso);
} else if (input.status === 'ongoing') {
whereParts.push('t.start_at <= ? AND t.end_at >= ?');
params.push(nowIso, nowIso);
} else if (input.status === 'notStarted') {
whereParts.push('t.start_at > ?');
params.push(nowIso);
}
if (input.endAtStart) {
whereParts.push('t.end_at >= ?');
params.push(input.endAtStart);
}
if (input.endAtEnd) {
whereParts.push('t.end_at <= ?');
params.push(input.endAtEnd);
}
const whereClause = whereParts.length > 0 ? `WHERE ${whereParts.join(' AND ')}` : '';
const totalRow = await get(`SELECT COUNT(*) as total FROM exam_tasks t ${whereClause}`, params);
const total = Number(totalRow?.total || 0);
const tasks = await all(
`
SELECT
t.id, t.name as taskName, s.name as subjectName, s.total_score as totalScore,
t.start_at as startAt, t.end_at as endAt
FROM exam_tasks t
JOIN exam_subjects s ON t.subject_id = s.id
${whereClause}
ORDER BY t.end_at DESC
LIMIT ? OFFSET ?
`,
[...params, input.limit, offset],
);
const data: Array<ActiveTaskStat & { status: '已完成' | '进行中' | '未开始' }> = [];
for (const task of tasks) {
const report = await this.getReport(task.id);
const stat = this.buildActiveTaskStat({
taskId: task.id,
taskName: task.taskName,
subjectName: task.subjectName,
totalScore: Number(task.totalScore) || 0,
startAt: task.startAt,
endAt: task.endAt,
report,
});
const startMs = new Date(task.startAt).getTime();
const endMs = new Date(task.endAt).getTime();
const status: '已完成' | '进行中' | '未开始' =
Number.isFinite(endMs) && endMs < nowMs
? '已完成'
: Number.isFinite(startMs) && startMs > nowMs
? '未开始'
: '进行中';
data.push({ ...stat, status });
}
return { data, total };
}
static async findById(id: string): Promise<ExamTask | null> {
const sql = `SELECT id, name, subject_id as subjectId, start_at as startAt, end_at as endAt, created_at as createdAt, selection_config as selectionConfig FROM exam_tasks WHERE id = ?`;
const row = await get(sql, [id]);