修正評審評分清單失敗問題

This commit is contained in:
2025-09-21 01:30:26 +08:00
parent 049b53fa43
commit a36ab3c98d
17 changed files with 251 additions and 274 deletions

View File

@@ -613,14 +613,41 @@ export class UserService extends DatabaseServiceBase {
`;
const reviewStats = await this.queryOne(reviewStatsSql);
// 競賽統計
const competitionStatsSql = `
SELECT
COUNT(*) as total_competitions,
COUNT(CASE WHEN status = 'active' OR status = 'ongoing' THEN 1 END) as active_competitions
FROM competitions
`;
const competitionStats = await this.queryOne(competitionStatsSql);
// 競賽統計 - 使用動態計算的狀態
const competitions = await CompetitionService.getAllCompetitions();
// 動態計算每個競賽的狀態
const now = new Date();
const competitionsWithCalculatedStatus = competitions.map(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) {
calculatedStatus = 'completed'; // 已完成
}
return {
...competition,
status: calculatedStatus
};
});
const competitionStats = {
total_competitions: competitionsWithCalculatedStatus.length,
active_competitions: competitionsWithCalculatedStatus.filter(c => c.status === 'active').length
};
// 計算增長率(與上個月比較)
const lastMonthUsersSql = `
@@ -903,7 +930,6 @@ export class JudgeService extends DatabaseServiceBase {
const fields = Object.keys(updates).filter(key => key !== 'id' && key !== 'created_at');
if (fields.length === 0) {
console.log('沒有字段需要更新');
return true; // 沒有需要更新的字段,視為成功
}
@@ -916,11 +942,7 @@ export class JudgeService extends DatabaseServiceBase {
});
const sql = `UPDATE judges SET ${setClause}, updated_at = CURRENT_TIMESTAMP WHERE id = ?`;
console.log('執行 SQL:', sql);
console.log('參數:', [...values, id]);
const result = await DatabaseServiceBase.safeUpdate(sql, [...values, id]);
console.log('更新結果:', result);
return result.affectedRows > 0;
}
@@ -938,38 +960,59 @@ export class JudgeService extends DatabaseServiceBase {
// 獲取評審的評分任務
static async getJudgeScoringTasks(judgeId: string, competitionId?: string): Promise<any[]> {
let sql = `
SELECT DISTINCT
a.id,
a.name,
'app' as type,
'individual' as participant_type,
COALESCE(js.total_score, 0) as score,
CASE
WHEN js.total_score > 0 THEN 'completed'
ELSE 'pending'
END as status,
js.submitted_at,
t.name as team_name,
CONCAT(COALESCE(t.name, '未知團隊'), ' - ', a.name) as display_name
FROM apps a
LEFT JOIN teams t ON a.team_id = t.id
LEFT JOIN competition_apps ca ON a.id = ca.app_id
LEFT JOIN judge_scores js ON a.id = js.app_id AND js.judge_id = ?
WHERE ca.competition_id = ?
`;
const params = [judgeId];
let sql: string;
let params: any[];
if (competitionId) {
params.push(competitionId);
// 獲取特定競賽的評分任務
sql = `
SELECT DISTINCT
a.id,
a.name,
'app' as type,
'individual' as participant_type,
COALESCE(js.total_score, 0) as score,
CASE
WHEN js.total_score > 0 THEN 'completed'
ELSE 'pending'
END as status,
js.submitted_at,
t.name as team_name,
a.name as display_name
FROM apps a
LEFT JOIN teams t ON a.team_id = t.id
LEFT JOIN competition_apps ca ON a.id = ca.app_id
LEFT JOIN judge_scores js ON a.id = js.app_id AND js.judge_id = ?
WHERE ca.competition_id = ?
ORDER BY a.name
`;
params = [judgeId, competitionId];
} else {
// 如果沒有指定競賽,獲取所有競賽的任務
sql = sql.replace('WHERE ca.competition_id = ?', 'WHERE ca.competition_id IS NOT NULL');
// 獲取所有競賽的任務
sql = `
SELECT DISTINCT
a.id,
a.name,
'app' as type,
'individual' as participant_type,
COALESCE(js.total_score, 0) as score,
CASE
WHEN js.total_score > 0 THEN 'completed'
ELSE 'pending'
END as status,
js.submitted_at,
t.name as team_name,
a.name as display_name
FROM apps a
LEFT JOIN teams t ON a.team_id = t.id
LEFT JOIN competition_apps ca ON a.id = ca.app_id
LEFT JOIN judge_scores js ON a.id = js.app_id AND js.judge_id = ?
WHERE ca.competition_id IS NOT NULL
ORDER BY a.name
`;
params = [judgeId];
}
sql += ' ORDER BY a.name';
const results = await DatabaseServiceBase.safeQuery(sql, params);
return results;
}
@@ -1002,7 +1045,6 @@ export class TeamService extends DatabaseServiceBase {
];
const result = await DatabaseServiceBase.safeInsert(sql, params);
console.log('團隊創建結果:', result);
return id;
}
@@ -1025,13 +1067,6 @@ export class TeamService extends DatabaseServiceBase {
ORDER BY t.created_at DESC
`;
const results = await DatabaseServiceBase.safeQuery(sql);
console.log('🔍 getAllTeams 查詢結果:', results.slice(0, 2).map(r => ({
id: r.id,
name: r.name,
leader_name: r.leader_name,
member_count: r.member_count,
submissionDate: r.submissionDate
})));
return results;
}
@@ -1291,10 +1326,7 @@ export class TeamService extends DatabaseServiceBase {
WHERE a.team_id = ? AND a.is_active = 1
ORDER BY a.created_at DESC
`;
console.log('📝 getTeamApps SQL:', sql);
console.log('📝 getTeamApps 參數:', [teamId]);
const results = await DatabaseServiceBase.safeQuery(sql, [teamId]);
console.log('📊 getTeamApps 結果:', results.length, '個應用');
return results;
}
@@ -1933,15 +1965,6 @@ export class CompetitionService extends DatabaseServiceBase {
const startDateUTC = new Date(startDate.getTime() + startDate.getTimezoneOffset() * 60000);
const endDateUTC = new Date(endDate.getTime() + endDate.getTimezoneOffset() * 60000);
console.log('🔍 競賽狀態計算:', {
competitionId,
name: competition.name,
now: nowUTC.toISOString(),
startDate: startDateUTC.toISOString(),
endDate: endDateUTC.toISOString(),
originalStatus: competition.status
});
// 根據實際日期計算狀態
if (nowUTC < startDateUTC) {
calculatedStatus = 'upcoming'; // 即將開始
@@ -1950,8 +1973,6 @@ export class CompetitionService extends DatabaseServiceBase {
} else if (nowUTC > endDateUTC) {
calculatedStatus = 'completed'; // 已完成
}
console.log('🔍 計算後的狀態:', calculatedStatus);
// 轉換字段名稱以匹配前端期望的格式
return {
@@ -2977,14 +2998,41 @@ export class AppService extends DatabaseServiceBase {
`;
const reviewStats = await this.queryOne(reviewStatsSql);
// 競賽統計
const competitionStatsSql = `
SELECT
COUNT(*) as total_competitions,
COUNT(CASE WHEN status = 'active' OR status = 'ongoing' THEN 1 END) as active_competitions
FROM competitions
`;
const competitionStats = await this.queryOne(competitionStatsSql);
// 競賽統計 - 使用動態計算的狀態
const competitions = await CompetitionService.getAllCompetitions();
// 動態計算每個競賽的狀態
const now = new Date();
const competitionsWithCalculatedStatus = competitions.map(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) {
calculatedStatus = 'completed'; // 已完成
}
return {
...competition,
status: calculatedStatus
};
});
const competitionStats = {
total_competitions: competitionsWithCalculatedStatus.length,
active_competitions: competitionsWithCalculatedStatus.filter(c => c.status === 'active').length
};
// 計算增長率(與上個月比較)
const lastMonthUsersSql = `
@@ -3004,8 +3052,6 @@ export class AppService extends DatabaseServiceBase {
totalUsers: userStats.totalUsers,
activeUsers: userStats.activeUsers,
totalApps: appStats?.total_apps || 0,
activeApps: appStats?.active_apps || 0,
inactiveApps: appStats?.inactive_apps || 0,
totalCompetitions: competitionStats?.total_competitions || 0,
totalReviews: reviewStats?.total_reviews || 0,
totalViews: appStats?.total_views || 0,
@@ -3578,7 +3624,6 @@ export class ScoringService extends DatabaseServiceBase {
try {
const result = await DatabaseServiceBase.safeQuery(sql, [competitionId]);
console.log('🔍 競賽規則查詢結果:', result);
return result;
} catch (error) {
console.error('❌ 獲取競賽規則失敗:', error);
@@ -3867,7 +3912,6 @@ export class ScoringService extends DatabaseServiceBase {
};
}> {
try {
console.log('🔍 獲取評分完成度匯總competitionId:', competitionId);
// 獲取競賽的評審列表 - 先嘗試從關聯表獲取,如果沒有則獲取所有評審
let judgesResult = await DatabaseServiceBase.safeQuery(`