Files
ai-showcase-platform/app/api/admin/competitions/stats/route.ts

87 lines
3.8 KiB
TypeScript

// =====================================================
// 競賽統計 API
// =====================================================
import { NextRequest, NextResponse } from 'next/server';
import { CompetitionService } from '@/lib/services/database-service';
// 獲取競賽統計數據
export async function GET(request: NextRequest) {
try {
const competitions = await CompetitionService.getAllCompetitions();
// 動態計算每個競賽的狀態
const now = new Date();
const competitionsWithCalculatedStatus = await Promise.all(competitions.map(async (competition) => {
const startDate = new Date(competition.start_date);
const endDate = new Date(competition.end_date);
let calculatedStatus = competition.status;
// 確保日期比較的準確性,使用 UTC 時間避免時區問題
const nowUTC = new Date(now.getTime() + now.getTimezoneOffset() * 60000);
const startDateUTC = new Date(startDate.getTime() + startDate.getTimezoneOffset() * 60000);
const endDateUTC = new Date(endDate.getTime() + endDate.getTimezoneOffset() * 60000);
// 根據實際日期計算狀態
if (nowUTC < startDateUTC) {
calculatedStatus = 'upcoming'; // 即將開始
} else if (nowUTC >= startDateUTC && nowUTC <= endDateUTC) {
calculatedStatus = 'active'; // 進行中
} else if (nowUTC > endDateUTC) {
// 競賽結束後,檢查評分進度
try {
const { ScoringService } = await import('@/lib/services/database-service');
const scoringProgress = await ScoringService.getCompetitionScoringProgress(competition.id);
if (scoringProgress.percentage >= 100) {
calculatedStatus = 'completed'; // 評分完成,競賽完成
} else {
calculatedStatus = 'judging'; // 評分未完成,仍在評審中
}
} catch (error) {
console.error('獲取評分進度失敗,使用預設狀態:', error);
calculatedStatus = 'judging'; // 無法獲取進度時,預設為評審中
}
}
return {
...competition,
status: calculatedStatus
};
}));
// 計算統計數據
const stats = {
total: competitionsWithCalculatedStatus.length,
upcoming: competitionsWithCalculatedStatus.filter(c => c.status === 'upcoming').length,
active: competitionsWithCalculatedStatus.filter(c => c.status === 'active' || c.status === 'ongoing').length,
ongoing: competitionsWithCalculatedStatus.filter(c => c.status === 'ongoing').length,
judging: competitionsWithCalculatedStatus.filter(c => c.status === 'judging').length,
completed: competitionsWithCalculatedStatus.filter(c => c.status === 'completed').length,
individual: competitionsWithCalculatedStatus.filter(c => c.type === 'individual').length,
team: competitionsWithCalculatedStatus.filter(c => c.type === 'team').length,
mixed: competitionsWithCalculatedStatus.filter(c => c.type === 'mixed').length,
proposal: competitionsWithCalculatedStatus.filter(c => c.type === 'proposal').length,
currentYear: competitionsWithCalculatedStatus.filter(c => c.year === new Date().getFullYear()).length,
thisMonth: competitionsWithCalculatedStatus.filter(c =>
c.year === new Date().getFullYear() &&
c.month === new Date().getMonth() + 1
).length
};
return NextResponse.json({
success: true,
message: '競賽統計獲取成功',
data: stats
});
} catch (error) {
console.error('獲取競賽統計失敗:', error);
return NextResponse.json({
success: false,
message: '獲取競賽統計失敗',
error: error instanceof Error ? error.message : '未知錯誤'
}, { status: 500 });
}
}