diff --git a/components/admin/scoring-management.tsx b/components/admin/scoring-management.tsx index 12edb5a..0257a71 100644 --- a/components/admin/scoring-management.tsx +++ b/components/admin/scoring-management.tsx @@ -366,8 +366,8 @@ export function ScoringManagement() { const selectedParticipant = competitionParticipants.find(p => p.id === manualScoring.participantId) console.log('๐Ÿ” ้ธไธญ็š„ๅƒ่ณฝ่€…:', selectedParticipant); - // ็”ฑๆ–ผๆ‰€ๆœ‰ๅƒ่ณฝ่€…้ƒฝๆ˜ฏๅœ˜้šŠ็š„ app๏ผŒๆ‰€ไปฅ participantType ๆ‡‰่ฉฒๆ˜ฏ 'app' - const participantType = 'app' + // ๆ นๆ“šๅƒ่ณฝ่€…็š„ๅฏฆ้š›้กžๅž‹็ขบๅฎš participantType + const participantType = selectedParticipant?.type === 'team' ? 'team' : 'app' const requestData = { judgeId: manualScoring.judgeId, @@ -532,33 +532,18 @@ export function ScoringManagement() { } if (teamsData.success && teamsData.data && teamsData.data.teams) { - // ๅฐ‡ๆฏๅ€‹ๅœ˜้šŠ็š„ๆฏๅ€‹ app ไฝœ็‚บ็จ็ซ‹็š„ๅƒ่ณฝ้ …็›ฎ + // ๅฐ‡ๆฏๅ€‹ๅœ˜้šŠไฝœ็‚บ็จ็ซ‹็š„ๅƒ่ณฝ้ …็›ฎ๏ผˆ่€Œไธๆ˜ฏๅœ˜้šŠไธญ็š„ๆฏๅ€‹ app๏ผ‰ teamsData.data.teams.forEach((team: any) => { console.log('๐Ÿ” ่™•็†ๅœ˜้šŠ:', team); - if (team.apps && team.apps.length > 0) { - team.apps.forEach((app: any) => { - console.log('๐Ÿ” ่™•็†ๅœ˜้šŠ app:', app); - participants.push({ - id: app.id, // ไฝฟ็”จ app ็š„ ID - name: app.name, // app ๅ็จฑ - type: 'team', - teamName: team.name || 'ๆœช็Ÿฅๅœ˜้šŠ', // ๅœ˜้šŠๅ็จฑ - displayName: app.name, // ๅช้กฏ็คบ app ๅ็จฑ๏ผŒๅœ˜้šŠๅ็จฑ้€š้Ž teamName ๅฑฌๆ€ง็ฒๅ– - creator: team.members && team.members.find((m: any) => m.role === '้šŠ้•ท')?.name || 'ๆœช็Ÿฅ้šŠ้•ท', - teamId: team.id // ไฟๅญ˜ๅœ˜้šŠ ID - }) - }) - } else { - // ๅฆ‚ๆžœๅœ˜้šŠๆฒ’ๆœ‰ app๏ผŒไป็„ถ้กฏ็คบๅœ˜้šŠๆœฌ่บซ - participants.push({ - id: team.id, - name: team.name, - type: 'team', - teamName: team.name || 'ๆœช็Ÿฅๅœ˜้šŠ', - creator: team.members && team.members.find((m: any) => m.role === '้šŠ้•ท')?.name || 'ๆœช็Ÿฅ้šŠ้•ท', - teamId: team.id - }) - } + participants.push({ + id: team.id, // ไฝฟ็”จๅœ˜้šŠ็š„ ID + name: team.name, // ๅœ˜้šŠๅ็จฑ + type: 'team', + teamName: team.name || 'ๆœช็Ÿฅๅœ˜้šŠ', // ๅœ˜้šŠๅ็จฑ + displayName: team.name, // ้กฏ็คบๅœ˜้šŠๅ็จฑ + creator: team.members && team.members.find((m: any) => m.role === '้šŠ้•ท')?.name || 'ๆœช็Ÿฅ้šŠ้•ท', + teamId: team.id // ไฟๅญ˜ๅœ˜้šŠ ID + }) }) console.log('โœ… ๅœ˜้šŠๆ•ธๆ“š่ผ‰ๅ…ฅๆˆๅŠŸ:', teamsData.data.teams.length, 'ๅ€‹ๅœ˜้šŠ') } else { diff --git a/lib/services/database-service.ts b/lib/services/database-service.ts index 8b0e49f..566ca82 100644 --- a/lib/services/database-service.ts +++ b/lib/services/database-service.ts @@ -1006,9 +1006,9 @@ export class JudgeService extends DatabaseServiceBase { UNION ALL SELECT DISTINCT - a.id, - a.name, - 'app' as type, + t.id, + t.name, + 'team' as type, 'team' as participant_type, COALESCE(js.total_score, 0) as score, CASE @@ -1017,12 +1017,11 @@ export class JudgeService extends DatabaseServiceBase { END as status, js.submitted_at, t.name as team_name, - CONCAT(t.name, ' - ', a.name) as display_name - FROM apps a - INNER JOIN competition_teams ct ON a.team_id = ct.team_id - LEFT JOIN teams t ON a.team_id = t.id - LEFT JOIN app_judge_scores js ON a.id = js.app_id AND js.judge_id = ? - WHERE ct.competition_id = ? AND a.is_active = 1 + t.name as display_name + FROM teams t + INNER JOIN competition_teams ct ON t.id = ct.team_id + LEFT JOIN app_judge_scores js ON js.app_id = CONCAT('team_', t.id) AND js.judge_id = ? + WHERE ct.competition_id = ? AND t.is_active = 1 ORDER BY display_name `; @@ -3888,19 +3887,41 @@ export class ScoringService extends DatabaseServiceBase { const judgeCount = judgesResult[0]?.judge_count || 0; console.log('๐Ÿ” ่ฉ•ๅฏฉๆ•ธ้‡:', judgeCount); - // ็ฒๅ–็ซถ่ณฝ็š„ๅƒ่ณฝAPPๆ•ธ้‡ - const appsResult = await DatabaseServiceBase.safeQuery(` - SELECT COUNT(DISTINCT ca.app_id) as app_count - FROM competition_apps ca - WHERE ca.competition_id = ? + // ็ฒๅ–็ซถ่ณฝ้กžๅž‹ + const competitionResult = await DatabaseServiceBase.safeQuery(` + SELECT type FROM competitions WHERE id = ? `, [competitionId]); - const appCount = appsResult[0]?.app_count || 0; - console.log('๐Ÿ” ๅƒ่ณฝAPPๆ•ธ้‡:', appCount); + const competitionType = competitionResult[0]?.type || 'individual'; + console.log('๐Ÿ” ็ซถ่ณฝ้กžๅž‹:', competitionType); - // ๅฆ‚ๆžœๆฒ’ๆœ‰่ฉ•ๅฏฉๆˆ–APP้—œ่ฏ๏ผŒๅ˜—่ฉฆๅพžๅ…ถไป–ๆ–นๅผ็ฒๅ– + let participantCount = 0; + + if (competitionType === 'team') { + // ๅœ˜้šŠ็ซถ่ณฝ๏ผš็ฒๅ–ๅƒ่ณฝๅœ˜้šŠๆ•ธ้‡ + const teamsResult = await DatabaseServiceBase.safeQuery(` + SELECT COUNT(DISTINCT ct.team_id) as team_count + FROM competition_teams ct + WHERE ct.competition_id = ? + `, [competitionId]); + + participantCount = teamsResult[0]?.team_count || 0; + console.log('๐Ÿ” ๅƒ่ณฝๅœ˜้šŠๆ•ธ้‡:', participantCount); + } else { + // ๅ€‹ไบบ็ซถ่ณฝ๏ผš็ฒๅ–ๅƒ่ณฝAPPๆ•ธ้‡ + const appsResult = await DatabaseServiceBase.safeQuery(` + SELECT COUNT(DISTINCT ca.app_id) as app_count + FROM competition_apps ca + WHERE ca.competition_id = ? + `, [competitionId]); + + participantCount = appsResult[0]?.app_count || 0; + console.log('๐Ÿ” ๅƒ่ณฝAPPๆ•ธ้‡:', participantCount); + } + + // ๅฆ‚ๆžœๆฒ’ๆœ‰่ฉ•ๅฏฉๆˆ–ๅƒ่ณฝ่€…้—œ่ฏ๏ผŒๅ˜—่ฉฆๅพžๅ…ถไป–ๆ–นๅผ็ฒๅ– let finalJudgeCount = judgeCount; - let finalAppCount = appCount; + let finalParticipantCount = participantCount; if (judgeCount === 0) { // ๅ˜—่ฉฆๅพž judges ่กจ็ฒๅ–ๆ‰€ๆœ‰่ฉ•ๅฏฉ @@ -3909,25 +3930,60 @@ export class ScoringService extends DatabaseServiceBase { console.log('๐Ÿ” ไฝฟ็”จๆ‰€ๆœ‰่ฉ•ๅฏฉๆ•ธ้‡:', finalJudgeCount); } - if (appCount === 0) { - // ๅ˜—่ฉฆๅพž apps ่กจ็ฒๅ–ๆ‰€ๆœ‰APP - const allAppsResult = await DatabaseServiceBase.safeQuery('SELECT COUNT(*) as app_count FROM apps'); - finalAppCount = allAppsResult[0]?.app_count || 0; - console.log('๐Ÿ” ไฝฟ็”จๆ‰€ๆœ‰APPๆ•ธ้‡:', finalAppCount); + if (participantCount === 0) { + if (competitionType === 'team') { + // ๅ˜—่ฉฆๅพž teams ่กจ็ฒๅ–ๆ‰€ๆœ‰ๅœ˜้šŠ + const allTeamsResult = await DatabaseServiceBase.safeQuery('SELECT COUNT(*) as team_count FROM teams'); + finalParticipantCount = allTeamsResult[0]?.team_count || 0; + console.log('๐Ÿ” ไฝฟ็”จๆ‰€ๆœ‰ๅœ˜้šŠๆ•ธ้‡:', finalParticipantCount); + } else { + // ๅ˜—่ฉฆๅพž apps ่กจ็ฒๅ–ๆ‰€ๆœ‰APP + const allAppsResult = await DatabaseServiceBase.safeQuery('SELECT COUNT(*) as app_count FROM apps'); + finalParticipantCount = allAppsResult[0]?.app_count || 0; + console.log('๐Ÿ” ไฝฟ็”จๆ‰€ๆœ‰APPๆ•ธ้‡:', finalParticipantCount); + } } // ็ฒๅ–ๅทฒๅฎŒๆˆ็š„่ฉ•ๅˆ†ๆ•ธ้‡ - const completedResult = await DatabaseServiceBase.safeQuery(` - SELECT COUNT(*) as completed_count - FROM judge_scores js - WHERE js.competition_id = ? - `, [competitionId]); + let completedResult; + if (competitionType === 'team') { + // ๅœ˜้šŠ็ซถ่ณฝ๏ผšๆŸฅ่ฉขๅœ˜้šŠ่ฉ•ๅˆ†่จ˜้Œ„ + completedResult = await DatabaseServiceBase.safeQuery(` + SELECT COUNT(*) as completed_count + FROM app_judge_scores js + WHERE js.app_id LIKE 'team_%' + AND EXISTS ( + SELECT 1 FROM competition_teams ct + WHERE ct.competition_id = ? + AND js.app_id = CONCAT('team_', ct.team_id) + ) + `, [competitionId]); + } else { + // ๅ€‹ไบบ็ซถ่ณฝ๏ผšๆŸฅ่ฉขๆ‡‰็”จ่ฉ•ๅˆ†่จ˜้Œ„ + completedResult = await DatabaseServiceBase.safeQuery(` + SELECT COUNT(*) as completed_count + FROM app_judge_scores js + WHERE js.app_id NOT LIKE 'team_%' + AND EXISTS ( + SELECT 1 FROM competition_apps ca + WHERE ca.competition_id = ? + AND ca.app_id = js.app_id + ) + `, [competitionId]); + } const completed = completedResult[0]?.completed_count || 0; - const total = finalJudgeCount * finalAppCount; + const total = finalJudgeCount * finalParticipantCount; const percentage = total > 0 ? Math.min(Math.round((completed / total) * 100), 100) : 0; - console.log('๐Ÿ” ่ฉ•ๅˆ†้€ฒๅบฆ็ตๆžœ:', { completed, total, percentage }); + console.log('๐Ÿ” ่ฉ•ๅˆ†้€ฒๅบฆ็ตๆžœ:', { + completed, + total, + percentage, + judgeCount: finalJudgeCount, + participantCount: finalParticipantCount, + competitionType + }); return { completed,