修正總分語細項不統一的問題
This commit is contained in:
@@ -263,7 +263,7 @@ export async function POST(request: NextRequest) {
|
|||||||
score: score,
|
score: score,
|
||||||
max_score: maxScore,
|
max_score: maxScore,
|
||||||
weight: criteriaItem.weight,
|
weight: criteriaItem.weight,
|
||||||
weighted_score: (score / maxScore) * criteriaItem.weight,
|
weighted_score: (score / maxScore) * (criteriaItem.weight / 100),
|
||||||
percentage: (score / maxScore) * 100
|
percentage: (score / maxScore) * 100
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ export async function POST(request: NextRequest) {
|
|||||||
score: score,
|
score: score,
|
||||||
max_score: maxScore,
|
max_score: maxScore,
|
||||||
weight: criteriaItem.weight,
|
weight: criteriaItem.weight,
|
||||||
weighted_score: (score / maxScore) * criteriaItem.weight,
|
weighted_score: (score / maxScore) * (criteriaItem.weight / 100),
|
||||||
percentage: (score / maxScore) * 100
|
percentage: (score / maxScore) * 100
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -85,7 +85,7 @@ export async function GET(
|
|||||||
overview: {
|
overview: {
|
||||||
excellentItems: evaluationWithDetails.excellent_items || 0,
|
excellentItems: evaluationWithDetails.excellent_items || 0,
|
||||||
improvementItems: evaluationWithDetails.improvement_items || 0,
|
improvementItems: evaluationWithDetails.improvement_items || 0,
|
||||||
overallPerformance: Number(evaluationWithDetails.overall_score) || 0
|
overallPerformance: Math.round(Number(evaluationWithDetails.overall_score) || 0)
|
||||||
},
|
},
|
||||||
improvementSuggestions: {
|
improvementSuggestions: {
|
||||||
overallSuggestions: feedbackByType.overall[0]?.content || '無詳細分析',
|
overallSuggestions: feedbackByType.overall[0]?.content || '無詳細分析',
|
||||||
|
@@ -109,7 +109,7 @@ export async function GET(
|
|||||||
overview: {
|
overview: {
|
||||||
excellentItems: evaluationWithDetails.excellent_items || 0,
|
excellentItems: evaluationWithDetails.excellent_items || 0,
|
||||||
improvementItems: evaluationWithDetails.improvement_items || 0,
|
improvementItems: evaluationWithDetails.improvement_items || 0,
|
||||||
overallPerformance: Number(evaluationWithDetails.overall_score) || 0
|
overallPerformance: Math.round(Number(evaluationWithDetails.overall_score) || 0)
|
||||||
},
|
},
|
||||||
detailedAnalysis: {
|
detailedAnalysis: {
|
||||||
summary: feedbackByType.overall[0]?.content || '無詳細分析',
|
summary: feedbackByType.overall[0]?.content || '無詳細分析',
|
||||||
|
@@ -103,7 +103,7 @@ const calculateMockOverview = (criteria: any[]) => {
|
|||||||
const improvementItems = criteria.filter(item => item.score < averageScore).length;
|
const improvementItems = criteria.filter(item => item.score < averageScore).length;
|
||||||
|
|
||||||
// 整體表現:基於權重的加權平均分數
|
// 整體表現:基於權重的加權平均分數
|
||||||
const overallPerformance = Math.round(criteria.reduce((sum, item) => sum + (item.score / item.maxScore) * item.weight, 0));
|
const overallPerformance = Math.round(criteria.reduce((sum, item) => sum + (item.score / item.maxScore) * (item.weight / 100), 0));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
excellentItems,
|
excellentItems,
|
||||||
@@ -254,7 +254,7 @@ export default function ResultsContent() {
|
|||||||
const improvementItems = criteria.filter(item => item.score < averageScore).length;
|
const improvementItems = criteria.filter(item => item.score < averageScore).length;
|
||||||
|
|
||||||
// 整體表現:基於權重的加權平均分數
|
// 整體表現:基於權重的加權平均分數
|
||||||
const overallPerformance = Math.round(criteria.reduce((sum, item) => sum + (item.score / item.maxScore) * item.weight, 0));
|
const overallPerformance = Math.round(criteria.reduce((sum, item) => sum + (item.score / item.maxScore) * (item.weight / 100), 0) * 10) / 10;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
excellentItems,
|
excellentItems,
|
||||||
@@ -263,9 +263,24 @@ export default function ResultsContent() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 重新計算基於權重的總分
|
||||||
|
const calculateWeightedTotalScore = (criteria: any[]): number => {
|
||||||
|
if (!criteria || criteria.length === 0) return 0;
|
||||||
|
|
||||||
|
const totalScore = criteria.reduce((sum, item) => {
|
||||||
|
const weightedScore = (item.score / item.maxScore) * (item.weight / 100);
|
||||||
|
return sum + weightedScore;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
// 將小數轉換為100分制的分數,保留一位小數
|
||||||
|
return Math.round(totalScore * 100 * 10) / 10; // 保留一位小數
|
||||||
|
};
|
||||||
|
|
||||||
// 確保所有必要的數據結構存在
|
// 確保所有必要的數據結構存在
|
||||||
const safeResults = {
|
const safeResults = {
|
||||||
...results,
|
...results,
|
||||||
|
// 重新計算總分
|
||||||
|
overallScore: calculateWeightedTotalScore(results.criteria || []),
|
||||||
overview: results.overview || calculateOverview(results.criteria || []),
|
overview: results.overview || calculateOverview(results.criteria || []),
|
||||||
chartData: results.chartData || {
|
chartData: results.chartData || {
|
||||||
barChart: [],
|
barChart: [],
|
||||||
|
@@ -145,7 +145,17 @@ ${criteriaList}
|
|||||||
**評分要求:**
|
**評分要求:**
|
||||||
1. 請對每個評分項目給出 0 到滿分的分數,要敢於給出極高分(9-10分)和極低分(1-3分)
|
1. 請對每個評分項目給出 0 到滿分的分數,要敢於給出極高分(9-10分)和極低分(1-3分)
|
||||||
2. 為每個項目提供具體的評分理由、優點和改進建議
|
2. 為每個項目提供具體的評分理由、優點和改進建議
|
||||||
3. 計算總分(各項目分數 × 權重比例)
|
3. **重要:計算總分時,請嚴格按照以下步驟:**
|
||||||
|
- 步驟1:計算每個項目的加權分數 = (該項目得分 ÷ 該項目滿分) × 該項目權重百分比
|
||||||
|
- 步驟2:將所有項目的加權分數相加得到總分
|
||||||
|
- 步驟3:檢查計算結果是否正確
|
||||||
|
- **計算範例:**
|
||||||
|
* 應用實務性:8/10 × 30% = 0.8 × 30 = 24分
|
||||||
|
* 創新性:6/10 × 15% = 0.6 × 15 = 9分
|
||||||
|
* 成效與效益:9/10 × 25% = 0.9 × 25 = 22.5分
|
||||||
|
* 擴散與可複用性:7/10 × 20% = 0.7 × 20 = 14分
|
||||||
|
* 簡報與表達:8/10 × 10% = 0.8 × 10 = 8分
|
||||||
|
* **總分 = 24 + 9 + 22.5 + 14 + 8 = 77.5分**
|
||||||
4. 提供整體評價和建議
|
4. 提供整體評價和建議
|
||||||
5. 分析優秀項目和待改進項目的數量
|
5. 分析優秀項目和待改進項目的數量
|
||||||
6. 給出等級評比 (S、A+、A、A-、B+、B、B-、C、D)
|
6. 給出等級評比 (S、A+、A、A-、B+、B、B-、C、D)
|
||||||
@@ -156,7 +166,7 @@ ${criteriaList}
|
|||||||
**回應格式 (請嚴格按照以下 JSON 格式回應):**
|
**回應格式 (請嚴格按照以下 JSON 格式回應):**
|
||||||
{
|
{
|
||||||
"projectTitle": "專案標題",
|
"projectTitle": "專案標題",
|
||||||
"overallScore": 總分數字,
|
"overallScore": 總分數字(必須是根據加權公式計算的正確總分,請仔細計算每個項目的加權分數後相加,例如:77.5),
|
||||||
"totalPossible": 100,
|
"totalPossible": 100,
|
||||||
"grade": "等級評比",
|
"grade": "等級評比",
|
||||||
"performanceStatus": "表現狀態",
|
"performanceStatus": "表現狀態",
|
||||||
@@ -239,6 +249,12 @@ ${criteriaList}
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
**重要提醒:在回應前,請務必檢查以下計算:**
|
||||||
|
1. 列出每個項目的得分和權重
|
||||||
|
2. 計算每個項目的加權分數:(得分÷滿分) × 權重百分比
|
||||||
|
3. 將所有加權分數相加得到總分
|
||||||
|
4. 確認總分是否正確
|
||||||
|
|
||||||
請確保回應是有效的 JSON 格式,不要包含任何其他文字。
|
請確保回應是有效的 JSON 格式,不要包含任何其他文字。
|
||||||
`.trim();
|
`.trim();
|
||||||
}
|
}
|
||||||
@@ -308,8 +324,8 @@ ${criteriaList}
|
|||||||
console.log(' 優秀項目 (≥' + averageScore + '):', excellentItems);
|
console.log(' 優秀項目 (≥' + averageScore + '):', excellentItems);
|
||||||
console.log(' 待改進項目 (<' + averageScore + '):', improvementItems);
|
console.log(' 待改進項目 (<' + averageScore + '):', improvementItems);
|
||||||
|
|
||||||
// 整體表現:基於權重的加權平均分數
|
// 整體表現:基於權重的加權平均分數(百分比)
|
||||||
const overallPerformance = Math.round(criteria.reduce((sum, item) => sum + (item.score / item.maxScore) * item.weight, 0));
|
const overallPerformance = Math.round(criteria.reduce((sum, item) => sum + (item.score / item.maxScore) * (item.weight / 100), 0) * 100);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
excellentItems,
|
excellentItems,
|
||||||
@@ -331,7 +347,7 @@ ${criteriaList}
|
|||||||
})),
|
})),
|
||||||
pieChart: criteria.map(item => ({
|
pieChart: criteria.map(item => ({
|
||||||
name: item.name,
|
name: item.name,
|
||||||
value: item.weightedScore || (item.score / item.maxScore) * item.weight,
|
value: item.weightedScore || (item.score / item.maxScore) * (item.weight / 100),
|
||||||
weight: item.weight
|
weight: item.weight
|
||||||
})),
|
})),
|
||||||
radarChart: criteria.map(item => ({
|
radarChart: criteria.map(item => ({
|
||||||
@@ -387,14 +403,25 @@ ${criteriaList}
|
|||||||
private static convertToProjectEvaluation(parsed: any, criteria: CriteriaItem[]): ProjectEvaluation {
|
private static convertToProjectEvaluation(parsed: any, criteria: CriteriaItem[]): ProjectEvaluation {
|
||||||
console.log('🔄 轉換完整格式回應...');
|
console.log('🔄 轉換完整格式回應...');
|
||||||
|
|
||||||
// 計算總分
|
// 計算總分 - 總是重新計算,不直接使用 AI 的 overallScore
|
||||||
let totalScore = 0;
|
let totalScore = 0;
|
||||||
if (parsed.overallScore) {
|
if (parsed.criteria && Array.isArray(parsed.criteria)) {
|
||||||
totalScore = Number(parsed.overallScore);
|
// 使用權重重新計算總分
|
||||||
} else if (parsed.criteria && Array.isArray(parsed.criteria)) {
|
|
||||||
totalScore = parsed.criteria.reduce((sum: number, item: any) => {
|
totalScore = parsed.criteria.reduce((sum: number, item: any) => {
|
||||||
return sum + (Number(item.weightedScore) || 0);
|
const score = Number(item.score) || 0;
|
||||||
|
const maxScore = Number(item.maxScore) || 10;
|
||||||
|
const weight = Number(item.weight) || 0;
|
||||||
|
const weightedScore = (score / maxScore) * (weight / 100);
|
||||||
|
console.log(` ${item.name}: ${score}/${maxScore} × ${weight}% = ${weightedScore.toFixed(2)}`);
|
||||||
|
return sum + weightedScore;
|
||||||
}, 0);
|
}, 0);
|
||||||
|
// 轉換為 100 分制
|
||||||
|
totalScore = totalScore * 100;
|
||||||
|
console.log(`📊 重新計算的總分: ${totalScore.toFixed(1)}/100`);
|
||||||
|
} else if (parsed.overallScore) {
|
||||||
|
// 如果沒有 criteria 數據,才使用 AI 的 overallScore
|
||||||
|
totalScore = Number(parsed.overallScore);
|
||||||
|
console.log(`📊 使用 AI 的總分: ${totalScore}/100`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 轉換評分結果
|
// 轉換評分結果
|
||||||
@@ -410,7 +437,7 @@ ${criteriaList}
|
|||||||
return {
|
return {
|
||||||
projectTitle: parsed.projectTitle || '',
|
projectTitle: parsed.projectTitle || '',
|
||||||
projectDescription: '',
|
projectDescription: '',
|
||||||
totalScore: Math.round(totalScore * 100) / 100,
|
totalScore: Math.round(totalScore * 10) / 10, // 保留一位小數(100分制)
|
||||||
maxTotalScore: 100,
|
maxTotalScore: 100,
|
||||||
results,
|
results,
|
||||||
overallFeedback: parsed.detailedAnalysis?.summary || parsed.overallFeedback || '整體評價',
|
overallFeedback: parsed.detailedAnalysis?.summary || parsed.overallFeedback || '整體評價',
|
||||||
@@ -570,7 +597,7 @@ ${criteriaList}
|
|||||||
totalScore = results.reduce((sum, result) => {
|
totalScore = results.reduce((sum, result) => {
|
||||||
const criteriaItem = criteria.find(c => c.id === result.criteriaId);
|
const criteriaItem = criteria.find(c => c.id === result.criteriaId);
|
||||||
const weight = criteriaItem ? criteriaItem.weight : 0;
|
const weight = criteriaItem ? criteriaItem.weight : 0;
|
||||||
const weightedScore = (result.score / result.maxScore) * weight;
|
const weightedScore = (result.score / result.maxScore) * (weight / 100);
|
||||||
console.log(` ${result.criteriaName}: ${result.score}/${result.maxScore} × ${weight}% = ${weightedScore.toFixed(2)}`);
|
console.log(` ${result.criteriaName}: ${result.score}/${result.maxScore} × ${weight}% = ${weightedScore.toFixed(2)}`);
|
||||||
return sum + weightedScore;
|
return sum + weightedScore;
|
||||||
}, 0);
|
}, 0);
|
||||||
@@ -587,8 +614,8 @@ ${criteriaList}
|
|||||||
return {
|
return {
|
||||||
projectTitle: '',
|
projectTitle: '',
|
||||||
projectDescription: '',
|
projectDescription: '',
|
||||||
totalScore: Math.round(totalScore * 100) / 100, // 四捨五入到小數點後兩位
|
totalScore: Math.round(totalScore * 10) / 10, // 四捨五入到小數點後一位
|
||||||
maxTotalScore: Math.round(maxTotalScore * 100) / 100,
|
maxTotalScore: Math.round(maxTotalScore * 10) / 10,
|
||||||
results,
|
results,
|
||||||
overallFeedback: parsed.overallFeedback || '基於資料庫評分標準的整體評價'
|
overallFeedback: parsed.overallFeedback || '基於資料庫評分標準的整體評價'
|
||||||
};
|
};
|
||||||
@@ -621,7 +648,7 @@ ${criteriaList}
|
|||||||
totalScore = results.reduce((sum, result) => {
|
totalScore = results.reduce((sum, result) => {
|
||||||
const criteriaItem = criteria.find(c => c.id === result.criteriaId);
|
const criteriaItem = criteria.find(c => c.id === result.criteriaId);
|
||||||
const weight = criteriaItem ? criteriaItem.weight : 0;
|
const weight = criteriaItem ? criteriaItem.weight : 0;
|
||||||
return sum + ((result.score / result.maxScore) * weight);
|
return sum + ((result.score / result.maxScore) * (weight / 100));
|
||||||
}, 0);
|
}, 0);
|
||||||
} else {
|
} else {
|
||||||
const rawTotal = results.reduce((sum, result) => sum + result.score, 0);
|
const rawTotal = results.reduce((sum, result) => sum + result.score, 0);
|
||||||
@@ -632,8 +659,8 @@ ${criteriaList}
|
|||||||
return {
|
return {
|
||||||
projectTitle: '',
|
projectTitle: '',
|
||||||
projectDescription: '',
|
projectDescription: '',
|
||||||
totalScore: Math.round(totalScore * 100) / 100,
|
totalScore: Math.round(totalScore * 10) / 10, // 四捨五入到小數點後一位
|
||||||
maxTotalScore: Math.round(maxTotalScore * 100) / 100,
|
maxTotalScore: Math.round(maxTotalScore * 10) / 10,
|
||||||
results,
|
results,
|
||||||
overallFeedback: '由於技術問題,無法完成完整的 AI 分析。建議檢查文件格式或重新上傳。'
|
overallFeedback: '由於技術問題,無法完成完整的 AI 分析。建議檢查文件格式或重新上傳。'
|
||||||
};
|
};
|
||||||
|
BIN
uploads/projects/30/1758644704994_cm3863nuv.pptx
Normal file
BIN
uploads/projects/30/1758644704994_cm3863nuv.pptx
Normal file
Binary file not shown.
Reference in New Issue
Block a user