修正分頁、Too many connection 問題
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
import { db } from '../database';
|
||||
import { dbSync } from '../database-sync';
|
||||
import { DatabaseServiceBase } from '../database-service-base';
|
||||
const { DatabaseSyncFixed } = require('../database-sync-fixed.js');
|
||||
import bcrypt from 'bcryptjs';
|
||||
import crypto from 'crypto';
|
||||
@@ -37,7 +38,7 @@ import type {
|
||||
// =====================================================
|
||||
// 用戶服務
|
||||
// =====================================================
|
||||
export class UserService {
|
||||
export class UserService extends DatabaseServiceBase {
|
||||
// 創建用戶
|
||||
async create(userData: Omit<User, 'id' | 'created_at' | 'updated_at'>): Promise<User> {
|
||||
const sql = `
|
||||
@@ -59,20 +60,20 @@ export class UserService {
|
||||
userData.last_login || null
|
||||
];
|
||||
|
||||
await db.insert(sql, params);
|
||||
await DatabaseServiceBase.safeInsert(sql, params);
|
||||
return await this.findByEmail(userData.email) as User;
|
||||
}
|
||||
|
||||
// 根據郵箱獲取用戶
|
||||
async findByEmail(email: string): Promise<User | null> {
|
||||
const sql = 'SELECT * FROM users WHERE email = ? AND status = "active"';
|
||||
return await db.queryOne<User>(sql, [email]);
|
||||
return await this.safeQueryOne<User>(sql, [email]);
|
||||
}
|
||||
|
||||
// 根據ID獲取用戶
|
||||
async findById(id: string): Promise<User | null> {
|
||||
const sql = 'SELECT * FROM users WHERE id = ? AND status = "active"';
|
||||
return await db.queryOne<User>(sql, [id]);
|
||||
return await this.safeQueryOne<User>(sql, [id]);
|
||||
}
|
||||
|
||||
// 更新用戶
|
||||
@@ -82,7 +83,7 @@ export class UserService {
|
||||
const values = fields.map(field => (updates as any)[field]);
|
||||
|
||||
const sql = `UPDATE users SET ${setClause}, updated_at = CURRENT_TIMESTAMP WHERE id = ?`;
|
||||
const result = await db.update(sql, [...values, id]);
|
||||
const result = await DatabaseServiceBase.safeUpdate(sql, [...values, id]);
|
||||
|
||||
if (result.affectedRows > 0) {
|
||||
return await this.findById(id);
|
||||
@@ -93,7 +94,7 @@ export class UserService {
|
||||
// 更新最後登入時間
|
||||
async updateLastLogin(id: string): Promise<boolean> {
|
||||
const sql = 'UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?';
|
||||
const result = await db.update(sql, [id]);
|
||||
const result = await DatabaseServiceBase.safeUpdate(sql, [id]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
@@ -112,7 +113,7 @@ export class UserService {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
} = {}): Promise<{ users: User[]; total: number }> {
|
||||
const { search, department, role, status, page = 1, limit = 10 } = filters;
|
||||
const { search, department, role, status, page = 1, limit = 5 } = filters;
|
||||
|
||||
// 構建查詢條件
|
||||
let whereConditions: string[] = [];
|
||||
@@ -150,7 +151,7 @@ export class UserService {
|
||||
|
||||
// 獲取總數
|
||||
const countSql = `SELECT COUNT(*) as total FROM users ${whereClause}`;
|
||||
const countResult = await this.query(countSql, params);
|
||||
const countResult = await DatabaseServiceBase.safeQuery(countSql, params);
|
||||
const total = countResult[0]?.total || 0;
|
||||
|
||||
// 獲取用戶列表
|
||||
@@ -164,7 +165,7 @@ export class UserService {
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ${offset}, ${limit}
|
||||
`;
|
||||
const users = await this.query<User>(usersSql, params);
|
||||
const users = await this.safeQuery<User>(usersSql, params);
|
||||
|
||||
return { users, total };
|
||||
}
|
||||
@@ -190,7 +191,7 @@ export class UserService {
|
||||
COUNT(CASE WHEN created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY) THEN 1 END) as new_this_month
|
||||
FROM users
|
||||
`;
|
||||
const result = await this.query(sql);
|
||||
const result = await DatabaseServiceBase.safeQuery(sql);
|
||||
const stats = result[0] || {};
|
||||
|
||||
return {
|
||||
@@ -823,7 +824,7 @@ export class UserService {
|
||||
// =====================================================
|
||||
// 評審服務
|
||||
// =====================================================
|
||||
export class JudgeService {
|
||||
export class JudgeService extends DatabaseServiceBase {
|
||||
// 安全解析 expertise 字段
|
||||
private static parseExpertise(expertise: any): string[] {
|
||||
if (!expertise) return [];
|
||||
@@ -847,7 +848,7 @@ export class JudgeService {
|
||||
}
|
||||
|
||||
// 創建評審
|
||||
static async createJudge(judgeData: Omit<Judge, 'id' | 'created_at' | 'updated_at'>): Promise<Judge> {
|
||||
async createJudge(judgeData: Omit<Judge, 'id' | 'created_at' | 'updated_at'>): Promise<Judge> {
|
||||
const sql = `
|
||||
INSERT INTO judges (id, name, title, department, expertise, avatar, is_active)
|
||||
VALUES (UUID(), ?, ?, ?, ?, ?, ?)
|
||||
@@ -861,8 +862,8 @@ export class JudgeService {
|
||||
judgeData.is_active
|
||||
];
|
||||
|
||||
await db.insert(sql, params);
|
||||
return await this.getJudgeByName(judgeData.name) as Judge;
|
||||
await DatabaseServiceBase.safeInsert(sql, params);
|
||||
return await JudgeService.getJudgeByName(judgeData.name) as Judge;
|
||||
}
|
||||
|
||||
// 根據姓名獲取評審
|
||||
@@ -916,7 +917,7 @@ export class JudgeService {
|
||||
console.log('執行 SQL:', sql);
|
||||
console.log('參數:', [...values, id]);
|
||||
|
||||
const result = await db.update(sql, [...values, id]);
|
||||
const result = await DatabaseServiceBase.safeUpdate(sql, [...values, id]);
|
||||
console.log('更新結果:', result);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
@@ -925,7 +926,7 @@ export class JudgeService {
|
||||
static async deleteJudge(id: string): Promise<boolean> {
|
||||
try {
|
||||
const sql = 'DELETE FROM judges WHERE id = ?';
|
||||
const result = await db.delete(sql, [id]);
|
||||
const result = await DatabaseServiceBase.safeDelete(sql, [id]);
|
||||
return result.affectedRows > 0;
|
||||
} catch (error) {
|
||||
console.error('刪除評審錯誤:', error);
|
||||
@@ -967,7 +968,7 @@ export class JudgeService {
|
||||
|
||||
sql += ' ORDER BY a.name';
|
||||
|
||||
const results = await db.query(sql, params);
|
||||
const results = await DatabaseServiceBase.safeQuery(sql, params);
|
||||
return results;
|
||||
}
|
||||
}
|
||||
@@ -975,7 +976,7 @@ export class JudgeService {
|
||||
// =====================================================
|
||||
// 團隊服務
|
||||
// =====================================================
|
||||
export class TeamService {
|
||||
export class TeamService extends DatabaseServiceBase {
|
||||
// 創建團隊
|
||||
static async createTeam(teamData: {
|
||||
name: string;
|
||||
@@ -998,7 +999,7 @@ export class TeamService {
|
||||
teamData.description || null
|
||||
];
|
||||
|
||||
const result = await db.insert(sql, params);
|
||||
const result = await DatabaseServiceBase.safeInsert(sql, params);
|
||||
console.log('團隊創建結果:', result);
|
||||
return id;
|
||||
}
|
||||
@@ -1017,7 +1018,7 @@ export class TeamService {
|
||||
GROUP BY t.id
|
||||
ORDER BY t.created_at DESC
|
||||
`;
|
||||
const results = await db.query(sql);
|
||||
const results = await DatabaseServiceBase.safeQuery(sql);
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -1031,7 +1032,7 @@ export class TeamService {
|
||||
LEFT JOIN users u ON t.leader_id = u.id
|
||||
WHERE t.id = ? AND t.is_active = TRUE
|
||||
`;
|
||||
const results = await db.query(sql, [id]);
|
||||
const results = await DatabaseServiceBase.safeQuery(sql, [id]);
|
||||
return results.length > 0 ? results[0] : null;
|
||||
}
|
||||
|
||||
@@ -1045,7 +1046,7 @@ export class TeamService {
|
||||
LEFT JOIN users u ON t.leader_id = u.id
|
||||
WHERE t.name = ? AND t.is_active = TRUE
|
||||
`;
|
||||
const results = await db.query(sql, [name]);
|
||||
const results = await DatabaseServiceBase.safeQuery(sql, [name]);
|
||||
return results.length > 0 ? results[0] : null;
|
||||
}
|
||||
|
||||
@@ -1072,7 +1073,7 @@ export class TeamService {
|
||||
const sql = `UPDATE teams SET ${setClause}, updated_at = CURRENT_TIMESTAMP WHERE id = ?`;
|
||||
|
||||
try {
|
||||
const result = await db.update(sql, values);
|
||||
const result = await DatabaseServiceBase.safeUpdate(sql, values);
|
||||
console.log('團隊更新結果:', result);
|
||||
return result.affectedRows > 0;
|
||||
} catch (error) {
|
||||
@@ -1085,7 +1086,7 @@ export class TeamService {
|
||||
static async deleteTeam(id: string): Promise<boolean> {
|
||||
try {
|
||||
const sql = 'UPDATE teams SET is_active = FALSE, updated_at = CURRENT_TIMESTAMP WHERE id = ?';
|
||||
const result = await db.update(sql, [id]);
|
||||
const result = await DatabaseServiceBase.safeUpdate(sql, [id]);
|
||||
return result.affectedRows > 0;
|
||||
} catch (error) {
|
||||
console.error('刪除團隊錯誤:', error);
|
||||
@@ -1097,7 +1098,7 @@ export class TeamService {
|
||||
static async hardDeleteTeam(id: string): Promise<boolean> {
|
||||
try {
|
||||
const sql = 'DELETE FROM teams WHERE id = ?';
|
||||
const result = await db.delete(sql, [id]);
|
||||
const result = await DatabaseServiceBase.safeDelete(sql, [id]);
|
||||
return result.affectedRows > 0;
|
||||
} catch (error) {
|
||||
console.error('硬刪除團隊錯誤:', error);
|
||||
@@ -1115,7 +1116,7 @@ export class TeamService {
|
||||
const params = [id, teamId, userId, role];
|
||||
|
||||
try {
|
||||
const result = await db.insert(sql, params);
|
||||
const result = await DatabaseServiceBase.safeInsert(sql, params);
|
||||
console.log('團隊成員添加結果:', result);
|
||||
return result.affectedRows > 0;
|
||||
} catch (error) {
|
||||
@@ -1133,7 +1134,7 @@ export class TeamService {
|
||||
WHERE tm.team_id = ? AND u.status = 'active'
|
||||
ORDER BY tm.joined_at ASC
|
||||
`;
|
||||
const results = await db.query(sql, [teamId]);
|
||||
const results = await DatabaseServiceBase.safeQuery(sql, [teamId]);
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -1141,7 +1142,7 @@ export class TeamService {
|
||||
static async removeTeamMember(teamId: string, userId: string): Promise<boolean> {
|
||||
try {
|
||||
const sql = 'DELETE FROM team_members WHERE team_id = ? AND user_id = ?';
|
||||
const result = await db.delete(sql, [teamId, userId]);
|
||||
const result = await DatabaseServiceBase.safeDelete(sql, [teamId, userId]);
|
||||
return result.affectedRows > 0;
|
||||
} catch (error) {
|
||||
console.error('移除團隊成員錯誤:', error);
|
||||
@@ -1153,7 +1154,7 @@ export class TeamService {
|
||||
static async updateTeamMemberRole(teamId: string, userId: string, role: string): Promise<boolean> {
|
||||
try {
|
||||
const sql = 'UPDATE team_members SET role = ? WHERE team_id = ? AND user_id = ?';
|
||||
const result = await db.update(sql, [role, teamId, userId]);
|
||||
const result = await DatabaseServiceBase.safeUpdate(sql, [role, teamId, userId]);
|
||||
return result.affectedRows > 0;
|
||||
} catch (error) {
|
||||
console.error('更新團隊成員角色錯誤:', error);
|
||||
@@ -1165,7 +1166,7 @@ export class TeamService {
|
||||
static async bindAppToTeam(teamId: string, appId: string): Promise<boolean> {
|
||||
try {
|
||||
const sql = 'UPDATE apps SET team_id = ? WHERE id = ? AND is_active = TRUE';
|
||||
const result = await db.update(sql, [teamId, appId]);
|
||||
const result = await DatabaseServiceBase.safeUpdate(sql, [teamId, appId]);
|
||||
return result.affectedRows > 0;
|
||||
} catch (error) {
|
||||
console.error('綁定應用到團隊錯誤:', error);
|
||||
@@ -1177,7 +1178,7 @@ export class TeamService {
|
||||
static async unbindAppFromTeam(appId: string): Promise<boolean> {
|
||||
try {
|
||||
const sql = 'UPDATE apps SET team_id = NULL WHERE id = ?';
|
||||
const result = await db.update(sql, [appId]);
|
||||
const result = await DatabaseServiceBase.safeUpdate(sql, [appId]);
|
||||
return result.affectedRows > 0;
|
||||
} catch (error) {
|
||||
console.error('解除應用與團隊綁定錯誤:', error);
|
||||
@@ -1200,7 +1201,7 @@ export class TeamService {
|
||||
`;
|
||||
console.log('📝 getTeamApps SQL:', sql);
|
||||
console.log('📝 getTeamApps 參數:', [teamId]);
|
||||
const results = await db.query(sql, [teamId]);
|
||||
const results = await DatabaseServiceBase.safeQuery(sql, [teamId]);
|
||||
console.log('📊 getTeamApps 結果:', results.length, '個應用');
|
||||
return results;
|
||||
}
|
||||
@@ -1220,7 +1221,7 @@ export class TeamService {
|
||||
GROUP BY t.id
|
||||
) as team_stats
|
||||
`;
|
||||
const results = await db.query(sql);
|
||||
const results = await DatabaseServiceBase.safeQuery(sql);
|
||||
return results[0] || { totalTeams: 0, activeTeams: 0, inactiveTeams: 0, avgMembersPerTeam: 0 };
|
||||
}
|
||||
}
|
||||
@@ -1228,7 +1229,7 @@ export class TeamService {
|
||||
// =====================================================
|
||||
// 競賽服務
|
||||
// =====================================================
|
||||
export class CompetitionService {
|
||||
export class CompetitionService extends DatabaseServiceBase {
|
||||
// 創建競賽
|
||||
static async createCompetition(competitionData: Omit<Competition, 'id' | 'created_at' | 'updated_at'>): Promise<Competition> {
|
||||
// 使用智能雙寫,每個資料庫生成自己的 ID
|
||||
@@ -1409,7 +1410,7 @@ export class CompetitionService {
|
||||
// 清除當前競賽
|
||||
static async clearCurrentCompetition(): Promise<boolean> {
|
||||
try {
|
||||
await db.update('UPDATE competitions SET is_current = FALSE');
|
||||
await DatabaseServiceBase.safeUpdate('UPDATE competitions SET is_current = FALSE');
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
@@ -1487,7 +1488,7 @@ export class CompetitionService {
|
||||
WHERE cj.competition_id = ? AND j.is_active = TRUE
|
||||
ORDER BY cj.assigned_at ASC
|
||||
`;
|
||||
return await db.query(sql, [competitionId]);
|
||||
return await DatabaseServiceBase.safeQuery(sql, [competitionId]);
|
||||
}
|
||||
|
||||
// 為競賽添加評審
|
||||
@@ -1496,7 +1497,7 @@ export class CompetitionService {
|
||||
const dbSyncFixed = new DatabaseSyncFixed();
|
||||
|
||||
// 先刪除現有的評審關聯
|
||||
await db.delete('DELETE FROM competition_judges WHERE competition_id = ?', [competitionId]);
|
||||
await DatabaseServiceBase.safeDelete('DELETE FROM competition_judges WHERE competition_id = ?', [competitionId]);
|
||||
|
||||
// 添加新的評審關聯
|
||||
if (judgeIds.length > 0) {
|
||||
@@ -1534,7 +1535,7 @@ export class CompetitionService {
|
||||
// 從競賽中移除評審
|
||||
static async removeCompetitionJudge(competitionId: string, judgeId: string): Promise<boolean> {
|
||||
const sql = 'DELETE FROM competition_judges WHERE competition_id = ? AND judge_id = ?';
|
||||
const result = await db.delete(sql, [competitionId, judgeId]);
|
||||
const result = await DatabaseServiceBase.safeDelete(sql, [competitionId, judgeId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
@@ -1548,7 +1549,7 @@ export class CompetitionService {
|
||||
WHERE ct.competition_id = ? AND t.is_active = TRUE
|
||||
ORDER BY ct.registered_at ASC
|
||||
`;
|
||||
return await db.query(sql, [competitionId]);
|
||||
return await DatabaseServiceBase.safeQuery(sql, [competitionId]);
|
||||
}
|
||||
|
||||
// 獲取競賽的應用列表
|
||||
@@ -1579,7 +1580,7 @@ export class CompetitionService {
|
||||
WHERE a.team_id IN (${placeholders}) AND a.is_active = TRUE
|
||||
ORDER BY a.created_at ASC
|
||||
`;
|
||||
apps = await db.query(sql, teamIds);
|
||||
apps = await DatabaseServiceBase.safeQuery(sql, teamIds);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1592,7 +1593,7 @@ export class CompetitionService {
|
||||
WHERE ca.competition_id = ? AND a.is_active = TRUE
|
||||
ORDER BY ca.submitted_at ASC
|
||||
`;
|
||||
apps = await db.query(sql, [competitionId]);
|
||||
apps = await DatabaseServiceBase.safeQuery(sql, [competitionId]);
|
||||
}
|
||||
|
||||
return apps;
|
||||
@@ -1604,7 +1605,7 @@ export class CompetitionService {
|
||||
const dbSyncFixed = new DatabaseSyncFixed();
|
||||
|
||||
// 先刪除現有的團隊關聯
|
||||
await db.delete('DELETE FROM competition_teams WHERE competition_id = ?', [competitionId]);
|
||||
await DatabaseServiceBase.safeDelete('DELETE FROM competition_teams WHERE competition_id = ?', [competitionId]);
|
||||
|
||||
// 添加新的團隊關聯
|
||||
if (teamIds.length > 0) {
|
||||
@@ -1642,7 +1643,7 @@ export class CompetitionService {
|
||||
// 從競賽中移除團隊
|
||||
static async removeCompetitionTeam(competitionId: string, teamId: string): Promise<boolean> {
|
||||
const sql = 'DELETE FROM competition_teams WHERE competition_id = ? AND team_id = ?';
|
||||
const result = await db.delete(sql, [competitionId, teamId]);
|
||||
const result = await DatabaseServiceBase.safeDelete(sql, [competitionId, teamId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
@@ -1652,7 +1653,7 @@ export class CompetitionService {
|
||||
const dbSyncFixed = new DatabaseSyncFixed();
|
||||
|
||||
// 先刪除現有的應用關聯
|
||||
await db.delete('DELETE FROM competition_apps WHERE competition_id = ?', [competitionId]);
|
||||
await DatabaseServiceBase.safeDelete('DELETE FROM competition_apps WHERE competition_id = ?', [competitionId]);
|
||||
|
||||
// 添加新的應用關聯
|
||||
if (appIds.length > 0) {
|
||||
@@ -1690,7 +1691,7 @@ export class CompetitionService {
|
||||
// 從競賽中移除應用
|
||||
static async removeCompetitionApp(competitionId: string, appId: string): Promise<boolean> {
|
||||
const sql = 'DELETE FROM competition_apps WHERE competition_id = ? AND app_id = ?';
|
||||
const result = await db.delete(sql, [competitionId, appId]);
|
||||
const result = await DatabaseServiceBase.safeDelete(sql, [competitionId, appId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
@@ -1702,7 +1703,7 @@ export class CompetitionService {
|
||||
WHERE cat.competition_id = ?
|
||||
ORDER BY cat.order_index ASC, cat.created_at ASC
|
||||
`;
|
||||
return await db.query(sql, [competitionId]);
|
||||
return await DatabaseServiceBase.safeQuery(sql, [competitionId]);
|
||||
}
|
||||
|
||||
// 為競賽添加獎項類型
|
||||
@@ -1711,7 +1712,7 @@ export class CompetitionService {
|
||||
const dbSyncFixed = new DatabaseSyncFixed();
|
||||
|
||||
// 先刪除現有的獎項類型
|
||||
await db.delete('DELETE FROM competition_award_types WHERE competition_id = ?', [competitionId]);
|
||||
await DatabaseServiceBase.safeDelete('DELETE FROM competition_award_types WHERE competition_id = ?', [competitionId]);
|
||||
|
||||
// 添加新的獎項類型
|
||||
if (awardTypes.length > 0) {
|
||||
@@ -1756,7 +1757,7 @@ export class CompetitionService {
|
||||
// 從競賽中移除獎項類型
|
||||
static async removeCompetitionAwardType(competitionId: string, awardTypeId: string): Promise<boolean> {
|
||||
const sql = 'DELETE FROM competition_award_types WHERE competition_id = ? AND id = ?';
|
||||
const result = await db.delete(sql, [competitionId, awardTypeId]);
|
||||
const result = await DatabaseServiceBase.safeDelete(sql, [competitionId, awardTypeId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
@@ -1767,7 +1768,7 @@ export class CompetitionService {
|
||||
const dbSyncFixed = new DatabaseSyncFixed();
|
||||
|
||||
// 先刪除現有的評分規則
|
||||
await db.delete('DELETE FROM competition_rules WHERE competition_id = ?', [competitionId]);
|
||||
await DatabaseServiceBase.safeDelete('DELETE FROM competition_rules WHERE competition_id = ?', [competitionId]);
|
||||
|
||||
// 添加新的評分規則
|
||||
if (rules.length > 0) {
|
||||
@@ -1811,7 +1812,7 @@ export class CompetitionService {
|
||||
// 從競賽中移除評分規則
|
||||
static async removeCompetitionRule(competitionId: string, ruleId: string): Promise<boolean> {
|
||||
const sql = 'DELETE FROM competition_rules WHERE competition_id = ? AND id = ?';
|
||||
const result = await db.delete(sql, [competitionId, ruleId]);
|
||||
const result = await DatabaseServiceBase.safeDelete(sql, [competitionId, ruleId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
@@ -1883,7 +1884,7 @@ export class CompetitionService {
|
||||
// =====================================================
|
||||
// 應用服務
|
||||
// =====================================================
|
||||
export class AppService {
|
||||
export class AppService extends DatabaseServiceBase {
|
||||
// 創建應用
|
||||
async createApp(appData: {
|
||||
name: string;
|
||||
@@ -3449,7 +3450,7 @@ export class AppService {
|
||||
// =====================================================
|
||||
// 評分服務
|
||||
// =====================================================
|
||||
export class ScoringService {
|
||||
export class ScoringService extends DatabaseServiceBase {
|
||||
// 獲取競賽規則
|
||||
static async getCompetitionRules(competitionId: string): Promise<any[]> {
|
||||
console.log('🔍 獲取競賽規則,competitionId:', competitionId);
|
||||
@@ -3462,7 +3463,7 @@ export class ScoringService {
|
||||
`;
|
||||
|
||||
try {
|
||||
const result = await db.query(sql, [competitionId]);
|
||||
const result = await DatabaseServiceBase.safeQuery(sql, [competitionId]);
|
||||
console.log('🔍 競賽規則查詢結果:', result);
|
||||
return result;
|
||||
} catch (error) {
|
||||
@@ -3478,7 +3479,7 @@ export class ScoringService {
|
||||
FROM competition_apps ca
|
||||
WHERE ca.app_id = ?
|
||||
`;
|
||||
const result = await db.query(sql, [appId]);
|
||||
const result = await DatabaseServiceBase.safeQuery(sql, [appId]);
|
||||
return result.length > 0 ? result[0].competition_id : null;
|
||||
}
|
||||
|
||||
@@ -3513,7 +3514,7 @@ export class ScoringService {
|
||||
console.log('🔍 編輯模式,使用記錄ID:', finalJudgeScoreId);
|
||||
} else {
|
||||
// 新增模式:檢查是否已存在評分記錄
|
||||
const existingScore = await db.query(
|
||||
const existingScore = await DatabaseServiceBase.safeQuery(
|
||||
'SELECT id FROM judge_scores WHERE judge_id = ? AND app_id = ?',
|
||||
[judge_id, app_id]
|
||||
);
|
||||
@@ -3530,14 +3531,14 @@ export class ScoringService {
|
||||
}
|
||||
|
||||
// 檢查記錄是否存在,決定是更新還是插入
|
||||
const existingRecord = await db.query(
|
||||
const existingRecord = await DatabaseServiceBase.safeQuery(
|
||||
'SELECT id FROM judge_scores WHERE id = ?',
|
||||
[finalJudgeScoreId]
|
||||
);
|
||||
|
||||
if (existingRecord.length > 0) {
|
||||
// 更新現有記錄
|
||||
await db.update(`
|
||||
await DatabaseServiceBase.safeUpdate(`
|
||||
UPDATE judge_scores
|
||||
SET total_score = ?, comments = ?, submitted_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
@@ -3545,7 +3546,7 @@ export class ScoringService {
|
||||
console.log('🔍 更新現有評分記錄');
|
||||
} else {
|
||||
// 檢查是否已有相同 judge_id + app_id + competition_id 的記錄
|
||||
const duplicateRecord = await db.query(
|
||||
const duplicateRecord = await DatabaseServiceBase.safeQuery(
|
||||
'SELECT id FROM judge_scores WHERE judge_id = ? AND app_id = ? AND competition_id = ?',
|
||||
[judge_id, app_id, competition_id]
|
||||
);
|
||||
@@ -3553,7 +3554,7 @@ export class ScoringService {
|
||||
if (duplicateRecord.length > 0) {
|
||||
// 更新現有記錄
|
||||
finalJudgeScoreId = duplicateRecord[0].id;
|
||||
await db.update(`
|
||||
await DatabaseServiceBase.safeUpdate(`
|
||||
UPDATE judge_scores
|
||||
SET total_score = ?, comments = ?, submitted_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
@@ -3561,7 +3562,7 @@ export class ScoringService {
|
||||
console.log('🔍 更新重複的評分記錄');
|
||||
} else {
|
||||
// 創建新記錄
|
||||
await db.insert(`
|
||||
await DatabaseServiceBase.safeInsert(`
|
||||
INSERT INTO judge_scores (id, judge_id, app_id, competition_id, total_score, comments)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`, [
|
||||
@@ -3581,7 +3582,7 @@ export class ScoringService {
|
||||
console.log('🔍 競賽規則:', rules);
|
||||
|
||||
// 3. 刪除現有的評分詳情
|
||||
await db.delete(
|
||||
await DatabaseServiceBase.safeDelete(
|
||||
'DELETE FROM judge_score_details WHERE judge_score_id = ?',
|
||||
[finalJudgeScoreId]
|
||||
);
|
||||
@@ -3605,7 +3606,7 @@ export class ScoringService {
|
||||
weight: rule.weight
|
||||
});
|
||||
|
||||
await db.insert(`
|
||||
await DatabaseServiceBase.safeInsert(`
|
||||
INSERT INTO judge_score_details (id, judge_score_id, rule_id, rule_name, score, weight)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`, [
|
||||
@@ -3646,7 +3647,7 @@ export class ScoringService {
|
||||
GROUP BY js.id
|
||||
`;
|
||||
|
||||
const result = await db.query(sql, [judgeScoreId]);
|
||||
const result = await DatabaseServiceBase.safeQuery(sql, [judgeScoreId]);
|
||||
return result.length > 0 ? result[0] : null;
|
||||
}
|
||||
|
||||
@@ -3660,7 +3661,7 @@ export class ScoringService {
|
||||
console.log('🔍 獲取競賽評分進度,competitionId:', competitionId);
|
||||
|
||||
// 獲取競賽的評審數量
|
||||
const judgesResult = await db.query(`
|
||||
const judgesResult = await DatabaseServiceBase.safeQuery(`
|
||||
SELECT COUNT(DISTINCT cj.judge_id) as judge_count
|
||||
FROM competition_judges cj
|
||||
WHERE cj.competition_id = ?
|
||||
@@ -3670,7 +3671,7 @@ export class ScoringService {
|
||||
console.log('🔍 評審數量:', judgeCount);
|
||||
|
||||
// 獲取競賽的參賽APP數量
|
||||
const appsResult = await db.query(`
|
||||
const appsResult = await DatabaseServiceBase.safeQuery(`
|
||||
SELECT COUNT(DISTINCT ca.app_id) as app_count
|
||||
FROM competition_apps ca
|
||||
WHERE ca.competition_id = ?
|
||||
@@ -3685,20 +3686,20 @@ export class ScoringService {
|
||||
|
||||
if (judgeCount === 0) {
|
||||
// 嘗試從 judges 表獲取所有評審
|
||||
const allJudgesResult = await db.query('SELECT COUNT(*) as judge_count FROM judges');
|
||||
const allJudgesResult = await DatabaseServiceBase.safeQuery('SELECT COUNT(*) as judge_count FROM judges');
|
||||
finalJudgeCount = allJudgesResult[0]?.judge_count || 0;
|
||||
console.log('🔍 使用所有評審數量:', finalJudgeCount);
|
||||
}
|
||||
|
||||
if (appCount === 0) {
|
||||
// 嘗試從 apps 表獲取所有APP
|
||||
const allAppsResult = await db.query('SELECT COUNT(*) as app_count FROM apps');
|
||||
const allAppsResult = await DatabaseServiceBase.safeQuery('SELECT COUNT(*) as app_count FROM apps');
|
||||
finalAppCount = allAppsResult[0]?.app_count || 0;
|
||||
console.log('🔍 使用所有APP數量:', finalAppCount);
|
||||
}
|
||||
|
||||
// 獲取已完成的評分數量
|
||||
const completedResult = await db.query(`
|
||||
const completedResult = await DatabaseServiceBase.safeQuery(`
|
||||
SELECT COUNT(*) as completed_count
|
||||
FROM judge_scores js
|
||||
WHERE js.competition_id = ?
|
||||
@@ -3755,7 +3756,7 @@ export class ScoringService {
|
||||
console.log('🔍 獲取評分完成度匯總,competitionId:', competitionId);
|
||||
|
||||
// 獲取競賽的評審列表 - 先嘗試從關聯表獲取,如果沒有則獲取所有評審
|
||||
let judgesResult = await db.query(`
|
||||
let judgesResult = await DatabaseServiceBase.safeQuery(`
|
||||
SELECT j.id, j.name
|
||||
FROM judges j
|
||||
LEFT JOIN competition_judges cj ON j.id = cj.judge_id
|
||||
@@ -3765,13 +3766,13 @@ export class ScoringService {
|
||||
|
||||
// 如果沒有關聯的評審,獲取所有評審
|
||||
if (judgesResult.length === 0) {
|
||||
judgesResult = await db.query(`
|
||||
judgesResult = await DatabaseServiceBase.safeQuery(`
|
||||
SELECT id, name FROM judges ORDER BY name
|
||||
`);
|
||||
}
|
||||
|
||||
// 獲取競賽的APP列表 - 先嘗試從關聯表獲取,如果沒有則獲取所有APP
|
||||
let appsResult = await db.query(`
|
||||
let appsResult = await DatabaseServiceBase.safeQuery(`
|
||||
SELECT a.id, a.name, t.name as team_name
|
||||
FROM apps a
|
||||
LEFT JOIN competition_apps ca ON a.id = ca.app_id
|
||||
@@ -3782,7 +3783,7 @@ export class ScoringService {
|
||||
|
||||
// 如果沒有關聯的APP,獲取所有APP
|
||||
if (appsResult.length === 0) {
|
||||
appsResult = await db.query(`
|
||||
appsResult = await DatabaseServiceBase.safeQuery(`
|
||||
SELECT a.id, a.name, t.name as team_name
|
||||
FROM apps a
|
||||
LEFT JOIN teams t ON a.team_id = t.id
|
||||
@@ -3791,7 +3792,7 @@ export class ScoringService {
|
||||
}
|
||||
|
||||
// 獲取已完成的評分記錄
|
||||
const scoresResult = await db.query(`
|
||||
const scoresResult = await DatabaseServiceBase.safeQuery(`
|
||||
SELECT js.judge_id, js.app_id, js.total_score, js.submitted_at,
|
||||
j.name as judge_name, a.name as app_name
|
||||
FROM judge_scores js
|
||||
@@ -3928,7 +3929,7 @@ export class ScoringService {
|
||||
scoreData.comments || null
|
||||
];
|
||||
|
||||
await db.insert(sql, params);
|
||||
await DatabaseServiceBase.safeInsert(sql, params);
|
||||
return await this.getProposalScore(scoreData.judge_id, scoreData.proposal_id) as ProposalJudgeScore;
|
||||
}
|
||||
|
||||
@@ -4028,7 +4029,7 @@ export class ScoringService {
|
||||
|
||||
ORDER BY submitted_at DESC
|
||||
`;
|
||||
return await db.query(sql, [competitionId, competitionId, competitionId]);
|
||||
return await DatabaseServiceBase.safeQuery(sql, [competitionId, competitionId, competitionId]);
|
||||
}
|
||||
|
||||
// 提交團隊評分(使用應用評分表,但標記為團隊類型)
|
||||
@@ -4062,7 +4063,7 @@ export class ScoringService {
|
||||
scoreData.comments || null
|
||||
];
|
||||
|
||||
await db.insert(sql, params);
|
||||
await DatabaseServiceBase.safeInsert(sql, params);
|
||||
return await this.getAppScore(scoreData.judge_id, virtualAppId) as AppJudgeScore;
|
||||
}
|
||||
|
||||
@@ -4180,14 +4181,14 @@ export class ScoringService {
|
||||
|
||||
sql += ' ORDER BY submitted_at DESC';
|
||||
|
||||
return await db.query(sql, params);
|
||||
return await DatabaseServiceBase.safeQuery(sql, params);
|
||||
}
|
||||
|
||||
// 刪除評分記錄
|
||||
static async deleteScore(scoreId: string, scoreType: 'app' | 'proposal'): Promise<boolean> {
|
||||
const tableName = scoreType === 'app' ? 'app_judge_scores' : 'proposal_judge_scores';
|
||||
const sql = `DELETE FROM ${tableName} WHERE id = ?`;
|
||||
const result = await db.delete(sql, [scoreId]);
|
||||
const result = await DatabaseServiceBase.safeDelete(sql, [scoreId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
@@ -4206,7 +4207,7 @@ export class ScoringService {
|
||||
const values = fields.map(field => (updates as any)[field]);
|
||||
|
||||
const sql = `UPDATE app_judge_scores SET ${setClause}, submitted_at = CURRENT_TIMESTAMP WHERE id = ?`;
|
||||
const result = await db.update(sql, [...values, scoreId]);
|
||||
const result = await DatabaseServiceBase.safeUpdate(sql, [...values, scoreId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
@@ -4225,7 +4226,7 @@ export class ScoringService {
|
||||
const values = fields.map(field => (updates as any)[field]);
|
||||
|
||||
const sql = `UPDATE proposal_judge_scores SET ${setClause}, submitted_at = CURRENT_TIMESTAMP WHERE id = ?`;
|
||||
const result = await db.update(sql, [...values, scoreId]);
|
||||
const result = await DatabaseServiceBase.safeUpdate(sql, [...values, scoreId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
}
|
||||
@@ -4233,7 +4234,7 @@ export class ScoringService {
|
||||
// =====================================================
|
||||
// 獎項服務
|
||||
// =====================================================
|
||||
export class AwardService {
|
||||
export class AwardService extends DatabaseServiceBase {
|
||||
// 創建獎項
|
||||
static async createAward(awardData: Omit<Award, 'id' | 'created_at'>): Promise<Award> {
|
||||
const sql = `
|
||||
@@ -4261,7 +4262,7 @@ export class AwardService {
|
||||
awardData.category
|
||||
];
|
||||
|
||||
await db.insert(sql, params);
|
||||
await DatabaseServiceBase.safeInsert(sql, params);
|
||||
return await this.getAwardByCompetitionAndCreator(awardData.competition_id, awardData.creator) as Award;
|
||||
}
|
||||
|
||||
@@ -4287,7 +4288,7 @@ export class AwardService {
|
||||
// =====================================================
|
||||
// 系統設定服務
|
||||
// =====================================================
|
||||
export class SystemSettingService {
|
||||
export class SystemSettingService extends DatabaseServiceBase {
|
||||
// 獲取設定值
|
||||
static async getSetting(key: string): Promise<string | null> {
|
||||
const sql = 'SELECT value FROM system_settings WHERE `key` = ?';
|
||||
@@ -4309,7 +4310,7 @@ export class SystemSettingService {
|
||||
`;
|
||||
const params = [key, value, description || null, category, isPublic];
|
||||
|
||||
const result = await db.insert(sql, params);
|
||||
const result = await DatabaseServiceBase.safeInsert(sql, params);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user