统计面板继续迭代
This commit is contained in:
@@ -2,6 +2,12 @@ import { Request, Response } from 'express';
|
||||
import { SystemConfigModel } from '../models';
|
||||
import { query } from '../database';
|
||||
|
||||
const toPositiveInt = (value: unknown, defaultValue: number) => {
|
||||
const n = Number(value);
|
||||
if (!Number.isFinite(n) || n <= 0) return defaultValue;
|
||||
return Math.floor(n);
|
||||
};
|
||||
|
||||
export class AdminController {
|
||||
// 管理员登录
|
||||
static async login(req: Request, res: Response) {
|
||||
@@ -127,6 +133,125 @@ export class AdminController {
|
||||
}
|
||||
}
|
||||
|
||||
static async getHistoryTaskStats(req: Request, res: Response) {
|
||||
try {
|
||||
const page = toPositiveInt(req.query.page, 1);
|
||||
const limit = toPositiveInt(req.query.limit, 5);
|
||||
|
||||
const { ExamTaskModel } = await import('../models/examTask');
|
||||
const result = await ExamTaskModel.getHistoryTasksWithStatsPaged(page, limit);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data,
|
||||
pagination: {
|
||||
page,
|
||||
limit,
|
||||
total: result.total,
|
||||
pages: Math.ceil(result.total / limit),
|
||||
},
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('获取历史任务统计失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '获取历史任务统计失败',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static async getUpcomingTaskStats(req: Request, res: Response) {
|
||||
try {
|
||||
const page = toPositiveInt(req.query.page, 1);
|
||||
const limit = toPositiveInt(req.query.limit, 5);
|
||||
|
||||
const { ExamTaskModel } = await import('../models/examTask');
|
||||
const result = await ExamTaskModel.getUpcomingTasksWithStatsPaged(page, limit);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data,
|
||||
pagination: {
|
||||
page,
|
||||
limit,
|
||||
total: result.total,
|
||||
pages: Math.ceil(result.total / limit),
|
||||
},
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('获取未开始任务统计失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '获取未开始任务统计失败',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static async getDashboardOverview(req: Request, res: Response) {
|
||||
try {
|
||||
const { QuizModel } = await import('../models');
|
||||
const statistics = await QuizModel.getStatistics();
|
||||
|
||||
const now = new Date().toISOString();
|
||||
|
||||
const [categoryRows, activeSubjectRow, statusRow] = await Promise.all([
|
||||
query(
|
||||
`
|
||||
SELECT
|
||||
COALESCE(category, '未分类') as category,
|
||||
COUNT(*) as count
|
||||
FROM questions
|
||||
GROUP BY COALESCE(category, '未分类')
|
||||
ORDER BY count DESC
|
||||
`,
|
||||
),
|
||||
query(
|
||||
`
|
||||
SELECT COUNT(DISTINCT subject_id) as total
|
||||
FROM exam_tasks
|
||||
WHERE start_at <= ? AND end_at >= ?
|
||||
`,
|
||||
[now, now],
|
||||
).then((rows: any[]) => rows[0]),
|
||||
query(
|
||||
`
|
||||
SELECT
|
||||
SUM(CASE WHEN end_at < ? THEN 1 ELSE 0 END) as completed,
|
||||
SUM(CASE WHEN start_at <= ? AND end_at >= ? THEN 1 ELSE 0 END) as ongoing,
|
||||
SUM(CASE WHEN start_at > ? THEN 1 ELSE 0 END) as notStarted
|
||||
FROM exam_tasks
|
||||
`,
|
||||
[now, now, now, now],
|
||||
).then((rows: any[]) => rows[0]),
|
||||
]);
|
||||
|
||||
const questionCategoryStats = (categoryRows as any[]).map((r) => ({
|
||||
category: r.category,
|
||||
count: Number(r.count) || 0,
|
||||
}));
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
totalUsers: statistics.totalUsers,
|
||||
activeSubjectCount: Number(activeSubjectRow?.total) || 0,
|
||||
questionCategoryStats,
|
||||
taskStatusDistribution: {
|
||||
completed: Number(statusRow?.completed) || 0,
|
||||
ongoing: Number(statusRow?.ongoing) || 0,
|
||||
notStarted: Number(statusRow?.notStarted) || 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('获取仪表盘概览失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '获取仪表盘概览失败',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static async getUserStats(req: Request, res: Response) {
|
||||
try {
|
||||
const rows = await query(
|
||||
|
||||
Reference in New Issue
Block a user