169 lines
6.8 KiB
TypeScript
169 lines
6.8 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { EvaluationService } from '@/lib/services/database';
|
|
|
|
export async function GET(
|
|
request: NextRequest,
|
|
{ params }: { params: { id: string } }
|
|
) {
|
|
try {
|
|
const evaluationId = parseInt(params.id);
|
|
|
|
if (isNaN(evaluationId)) {
|
|
return NextResponse.json(
|
|
{ success: false, error: '無效的評審ID' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
console.log(`📊 開始獲取評審詳細數據: ID=${evaluationId}`);
|
|
|
|
// 獲取評審詳細數據
|
|
const evaluationWithDetails = await EvaluationService.findWithDetails(evaluationId);
|
|
|
|
if (!evaluationWithDetails) {
|
|
return NextResponse.json(
|
|
{ success: false, error: '找不到指定的評審記錄' },
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
|
|
console.log(`✅ 成功獲取評審數據: 專案=${evaluationWithDetails.project?.title}`);
|
|
|
|
// 處理反饋數據,按類型分組
|
|
const feedbackByType = {
|
|
criteria: evaluationWithDetails.feedback?.filter(f => f.feedback_type === 'criteria') || [],
|
|
strength: evaluationWithDetails.feedback?.filter(f => f.feedback_type === 'strength') || [],
|
|
improvement: evaluationWithDetails.feedback?.filter(f => f.feedback_type === 'improvement') || [],
|
|
overall: evaluationWithDetails.feedback?.filter(f => f.feedback_type === 'overall') || []
|
|
};
|
|
|
|
// 為每個評分標準獲取對應的 AI 評語、優點和改進建議
|
|
const criteriaWithFeedback = evaluationWithDetails.scores?.map(score => {
|
|
const criteriaId = score.criteria_item_id;
|
|
const criteriaName = score.criteria_item_name || '未知項目';
|
|
|
|
// 獲取該評分標準的 AI 評語
|
|
const criteriaFeedback = feedbackByType.criteria
|
|
.filter(f => f.criteria_item_id === criteriaId)
|
|
.map(f => f.content)
|
|
.filter((content, index, arr) => arr.indexOf(content) === index); // 去重
|
|
|
|
// 獲取該評分標準的優點
|
|
const strengths = feedbackByType.strength
|
|
.filter(f => f.criteria_item_id === criteriaId)
|
|
.map(f => f.content)
|
|
.filter((content, index, arr) => arr.indexOf(content) === index); // 去重
|
|
|
|
// 獲取該評分標準的改進建議
|
|
const improvements = feedbackByType.improvement
|
|
.filter(f => f.criteria_item_id === criteriaId)
|
|
.map(f => f.content)
|
|
.filter((content, index, arr) => arr.indexOf(content) === index); // 去重
|
|
|
|
return {
|
|
name: criteriaName,
|
|
score: Number(score.score) || 0,
|
|
maxScore: Number(score.max_score) || 10,
|
|
weight: Number(score.weight) || 1,
|
|
weightedScore: Number(score.weighted_score) || 0,
|
|
percentage: Number(score.percentage) || 0,
|
|
feedback: criteriaFeedback[0] || '無評語', // 使用第一個評語
|
|
strengths: strengths,
|
|
improvements: improvements
|
|
};
|
|
}) || [];
|
|
|
|
// 生成圖表數據
|
|
const chartData = {
|
|
// 各項目得分 - 使用 evaluation_scores 的 score 資料
|
|
barChart: criteriaWithFeedback.map(criteria => ({
|
|
name: criteria.name,
|
|
score: criteria.score
|
|
})),
|
|
|
|
// 權重分布 - 使用 evaluation_scores 的 weighted_score 資料
|
|
pieChart: criteriaWithFeedback.map(criteria => ({
|
|
name: criteria.name,
|
|
value: criteria.weightedScore,
|
|
weight: criteria.weight
|
|
})),
|
|
|
|
// 能力雷達圖 - 使用 evaluation_scores 的 score 資料
|
|
radarChart: criteriaWithFeedback.map(criteria => ({
|
|
subject: criteria.name,
|
|
score: criteria.score,
|
|
fullMark: criteria.maxScore
|
|
}))
|
|
};
|
|
|
|
// 轉換數據格式以符合前端需求
|
|
const formattedData = {
|
|
projectTitle: evaluationWithDetails.project?.title || '未知專案',
|
|
overallScore: Number(evaluationWithDetails.overall_score) || 0,
|
|
totalPossible: Number(evaluationWithDetails.max_possible_score) || 100,
|
|
grade: evaluationWithDetails.grade || 'N/A',
|
|
performanceStatus: evaluationWithDetails.performance_status || 'N/A',
|
|
recommendedStars: evaluationWithDetails.recommended_stars || 0,
|
|
analysisDate: evaluationWithDetails.created_at ? new Date(evaluationWithDetails.created_at).toISOString().split('T')[0] : new Date().toISOString().split('T')[0],
|
|
criteria: criteriaWithFeedback,
|
|
overview: {
|
|
excellentItems: evaluationWithDetails.excellent_items || 0,
|
|
improvementItems: evaluationWithDetails.improvement_items || 0,
|
|
overallPerformance: Number(evaluationWithDetails.overall_score) || 0
|
|
},
|
|
detailedAnalysis: {
|
|
summary: feedbackByType.overall[0]?.content || '無詳細分析',
|
|
keyFindings: feedbackByType.overall.map(f => f.content).filter((content, index, arr) => arr.indexOf(content) === index) // 去重
|
|
},
|
|
improvementSuggestions: {
|
|
// 整體改進建議 - evaluation_feedback 的第一筆 overall
|
|
overallSuggestions: feedbackByType.overall[0]?.content || '無改進建議',
|
|
|
|
// 繼續保持的優勢 - evaluation_feedback 的 strength
|
|
maintainStrengths: feedbackByType.strength
|
|
.filter(f => f.criteria_item_id) // 只取有 criteria_item_id 的
|
|
.map(f => ({
|
|
title: f.criteria_item_name || '優勢',
|
|
description: f.content || '無描述'
|
|
}))
|
|
.filter((item, index, arr) => arr.findIndex(i => i.title === item.title) === index), // 去重
|
|
|
|
// 重點改進方向 - evaluation_feedback 的 improvement (除了最後3筆)
|
|
keyImprovements: feedbackByType.improvement
|
|
.filter(f => f.criteria_item_id) // 只取有 criteria_item_id 的
|
|
.slice(0, -3) // 排除最後3筆
|
|
.map(f => ({
|
|
title: f.criteria_item_name || '改進項目',
|
|
description: f.content || '無描述',
|
|
suggestions: [f.content || '無建議']
|
|
}))
|
|
.filter((item, index, arr) => arr.findIndex(i => i.title === item.title) === index), // 去重
|
|
|
|
// 下一步行動計劃 - evaluation_feedback 的 improvement 最後3筆
|
|
actionPlan: feedbackByType.improvement
|
|
.filter(f => f.criteria_item_id) // 只取有 criteria_item_id 的
|
|
.slice(-3) // 取最後3筆
|
|
.map((f, index) => ({
|
|
phase: `階段 ${index + 1}`,
|
|
description: f.content || '無描述'
|
|
}))
|
|
},
|
|
chartData: chartData
|
|
};
|
|
|
|
console.log(`📋 評審數據格式化完成: 專案=${formattedData.projectTitle}, 分數=${formattedData.overallScore}`);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
data: formattedData
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('❌ 獲取評審詳細數據失敗:', error);
|
|
return NextResponse.json(
|
|
{ success: false, error: '獲取評審詳細數據失敗' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|