完成評審評分機制
This commit is contained in:
166
app/api/admin/scoring/[id]/route.ts
Normal file
166
app/api/admin/scoring/[id]/route.ts
Normal file
@@ -0,0 +1,166 @@
|
||||
// =====================================================
|
||||
// 評分記錄管理 API
|
||||
// =====================================================
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { ScoringService } from '@/lib/services/database-service';
|
||||
|
||||
// 更新評分記錄
|
||||
export async function PUT(request: NextRequest, { params }: { params: { id: string } }) {
|
||||
try {
|
||||
const { id } = await params;
|
||||
const body = await request.json();
|
||||
const {
|
||||
participantType,
|
||||
scores,
|
||||
comments
|
||||
} = body;
|
||||
|
||||
// 驗證必填欄位
|
||||
if (!participantType || !scores) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '缺少必填欄位',
|
||||
error: 'participantType, scores 為必填欄位'
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
// 驗證評分類型
|
||||
if (!['app', 'proposal'].includes(participantType)) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '無效的參賽者類型',
|
||||
error: 'participantType 必須是 "app" 或 "proposal"'
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
let result;
|
||||
|
||||
if (participantType === 'app') {
|
||||
// 驗證應用評分格式
|
||||
const requiredScores = ['innovation_score', 'technical_score', 'usability_score', 'presentation_score', 'impact_score'];
|
||||
const missingScores = requiredScores.filter(score => !(score in scores) || scores[score] < 1 || scores[score] > 10);
|
||||
|
||||
if (missingScores.length > 0) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '評分格式無效',
|
||||
error: `缺少或無效的評分項目: ${missingScores.join(', ')}`
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
// 計算總分
|
||||
const totalScore = (
|
||||
scores.innovation_score +
|
||||
scores.technical_score +
|
||||
scores.usability_score +
|
||||
scores.presentation_score +
|
||||
scores.impact_score
|
||||
) / 5;
|
||||
|
||||
result = await ScoringService.updateAppScore(id, {
|
||||
innovation_score: scores.innovation_score,
|
||||
technical_score: scores.technical_score,
|
||||
usability_score: scores.usability_score,
|
||||
presentation_score: scores.presentation_score,
|
||||
impact_score: scores.impact_score,
|
||||
total_score: totalScore,
|
||||
comments: comments || null
|
||||
});
|
||||
} else {
|
||||
// 驗證提案評分格式
|
||||
const requiredScores = ['problem_identification_score', 'solution_feasibility_score', 'innovation_score', 'impact_score', 'presentation_score'];
|
||||
const missingScores = requiredScores.filter(score => !(score in scores) || scores[score] < 1 || scores[score] > 10);
|
||||
|
||||
if (missingScores.length > 0) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '評分格式無效',
|
||||
error: `缺少或無效的評分項目: ${missingScores.join(', ')}`
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
// 計算總分
|
||||
const totalScore = (
|
||||
scores.problem_identification_score +
|
||||
scores.solution_feasibility_score +
|
||||
scores.innovation_score +
|
||||
scores.impact_score +
|
||||
scores.presentation_score
|
||||
) / 5;
|
||||
|
||||
result = await ScoringService.updateProposalScore(id, {
|
||||
problem_identification_score: scores.problem_identification_score,
|
||||
solution_feasibility_score: scores.solution_feasibility_score,
|
||||
innovation_score: scores.innovation_score,
|
||||
impact_score: scores.impact_score,
|
||||
presentation_score: scores.presentation_score,
|
||||
total_score: totalScore,
|
||||
comments: comments || null
|
||||
});
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '評分更新失敗',
|
||||
error: '找不到指定的評分記錄或更新失敗'
|
||||
}, { status: 404 });
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '評分更新成功',
|
||||
data: { updated: true }
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('更新評分失敗:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '更新評分失敗',
|
||||
error: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// 刪除評分記錄
|
||||
export async function DELETE(request: NextRequest, { params }: { params: { id: string } }) {
|
||||
try {
|
||||
const { id } = await params;
|
||||
const { searchParams } = new URL(request.url);
|
||||
const participantType = searchParams.get('type');
|
||||
|
||||
if (!participantType || !['app', 'proposal'].includes(participantType)) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '缺少或無效的參賽者類型',
|
||||
error: 'type 參數必須是 "app" 或 "proposal"'
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
const result = await ScoringService.deleteScore(id, participantType as 'app' | 'proposal');
|
||||
|
||||
if (!result) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '評分刪除失敗',
|
||||
error: '找不到指定的評分記錄或刪除失敗'
|
||||
}, { status: 404 });
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '評分刪除成功',
|
||||
data: { deleted: true }
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('刪除評分失敗:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '刪除評分失敗',
|
||||
error: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user