From b6e4f307126270ac0e6e1665d89f1919d39c3b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B3=E4=BD=A9=E5=BA=AD?= Date: Tue, 23 Sep 2025 18:15:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20AI=20=E7=94=A2=E5=87=BA?= =?UTF-8?q?=E7=B5=90=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/layout.tsx | 8 ++ app/results/page.tsx | 173 +++++++++++++++++++---------- app/upload/page.tsx | 4 +- components/sidebar.tsx | 2 +- database/README.md | 4 +- lib/services/gemini.ts | 66 +++++++---- package.json | 4 +- public/artificial-intelligence.png | Bin 0 -> 5092 bytes public/favicon.ico | Bin 0 -> 5092 bytes 9 files changed, 177 insertions(+), 84 deletions(-) create mode 100644 public/artificial-intelligence.png create mode 100644 public/favicon.ico diff --git a/app/layout.tsx b/app/layout.tsx index fef0ad3..1aec0e4 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -16,6 +16,14 @@ export const metadata: Metadata = { title: "AI 評審系統", description: "智能評審平台 - 上傳 PPT、影片和網站連結,獲得專業評分結果", generator: "v0.app", + icons: { + icon: [ + { url: "/artificial-intelligence.png", type: "image/png" }, + { url: "/favicon.ico", sizes: "any" } + ], + shortcut: "/artificial-intelligence.png", + apple: "/artificial-intelligence.png", + }, } export default function RootLayout({ diff --git a/app/results/page.tsx b/app/results/page.tsx index 89c2af7..8f39ed7 100644 --- a/app/results/page.tsx +++ b/app/results/page.tsx @@ -27,65 +27,97 @@ import { import { Download, Share2, TrendingUp, AlertCircle, CheckCircle, Star } from "lucide-react" import { useToast } from "@/hooks/use-toast" -// 模擬評分結果數據 +// 模擬評分結果數據 - 使用您提到的例子:8, 7, 6, 8, 4,平均 = 6.6 +const mockCriteria = [ + { + name: "內容品質", + score: 8, + maxScore: 10, + weight: 25, + weightedScore: 20, + feedback: "內容結構清晰,資訊豐富且準確。建議增加更多實際案例來支撐論點。", + strengths: ["邏輯清晰", "資料準確", "結構完整"], + improvements: ["增加案例", "深化分析"], + }, + { + name: "視覺設計", + score: 7, + maxScore: 10, + weight: 20, + weightedScore: 14, + feedback: "整體設計風格統一,色彩搭配合理。部分頁面文字密度過高,影響閱讀體驗。", + strengths: ["風格統一", "色彩協調", "版面整潔"], + improvements: ["減少文字密度", "增加視覺元素"], + }, + { + name: "邏輯結構", + score: 6, + maxScore: 10, + weight: 20, + weightedScore: 12, + feedback: "邏輯架構清晰,各章節銜接自然,論述層次分明。", + strengths: ["邏輯清晰", "結構完整", "銜接自然"], + improvements: ["可增加總結回顧"], + }, + { + name: "創新性", + score: 8, + maxScore: 10, + weight: 15, + weightedScore: 12, + feedback: "內容具有一定創新性,但可以更大膽地提出獨特觀點和解決方案。", + strengths: ["思路新穎", "角度獨特"], + improvements: ["增加創新元素", "提出獨特見解"], + }, + { + name: "實用性", + score: 4, + maxScore: 10, + weight: 20, + weightedScore: 8, + feedback: "內容實用性有待提升,提供的解決方案需要更具可操作性。", + strengths: ["實用性強", "可操作性好", "價值明確"], + improvements: ["增加實施步驟"], + }, +]; + +// 計算 mock 數據的 overview - 基於平均分作為閾值 +const calculateMockOverview = (criteria: any[]) => { + if (!criteria || criteria.length === 0) { + return { + excellentItems: 0, + improvementItems: 0, + overallPerformance: 0 + }; + } + + // 計算所有項目的平均分數(不考慮權重) + const totalScore = criteria.reduce((sum, item) => sum + item.score, 0); + const averageScore = totalScore / criteria.length; + + // 以平均分作為閾值 + // ≥ 平均分 = 優秀項目,< 平均分 = 待改進項目 + const excellentItems = 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)); + + return { + excellentItems, + improvementItems, + overallPerformance + }; +}; + const mockResults = { projectTitle: "產品介紹簡報", overallScore: 82, totalPossible: 100, grade: "B+", analysisDate: "2024-01-15", - criteria: [ - { - name: "內容品質", - score: 8.5, - maxScore: 10, - weight: 25, - weightedScore: 21.25, - feedback: "內容結構清晰,資訊豐富且準確。建議增加更多實際案例來支撐論點。", - strengths: ["邏輯清晰", "資料準確", "結構完整"], - improvements: ["增加案例", "深化分析"], - }, - { - name: "視覺設計", - score: 7.8, - maxScore: 10, - weight: 20, - weightedScore: 15.6, - feedback: "整體設計風格統一,色彩搭配合理。部分頁面文字密度過高,影響閱讀體驗。", - strengths: ["風格統一", "色彩協調", "版面整潔"], - improvements: ["減少文字密度", "增加視覺元素"], - }, - { - name: "邏輯結構", - score: 8.8, - maxScore: 10, - weight: 20, - weightedScore: 17.6, - feedback: "邏輯架構非常清晰,各章節銜接自然,論述層次分明。", - strengths: ["邏輯清晰", "結構完整", "銜接自然"], - improvements: ["可增加總結回顧"], - }, - { - name: "創新性", - score: 7.2, - maxScore: 10, - weight: 15, - weightedScore: 10.8, - feedback: "內容具有一定創新性,但可以更大膽地提出獨特觀點和解決方案。", - strengths: ["思路新穎", "角度獨特"], - improvements: ["增加創新元素", "提出獨特見解"], - }, - { - name: "實用性", - score: 8.3, - maxScore: 10, - weight: 20, - weightedScore: 16.6, - feedback: "內容實用性強,提供的解決方案具有可操作性,對目標受眾有實際價值。", - strengths: ["實用性強", "可操作性好", "價值明確"], - improvements: ["增加實施步驟"], - }, - ], + criteria: mockCriteria, + overview: calculateMockOverview(mockCriteria), } // 圖表數據將在組件內部動態生成 @@ -166,14 +198,39 @@ export default function ResultsPage() { // 使用真實數據或回退到模擬數據 const results = evaluationData.evaluation?.fullData || mockResults + // 計算統計數據 - 基於 criteria_items 的平均分作為閾值 + const calculateOverview = (criteria: any[]) => { + if (!criteria || criteria.length === 0) { + return { + excellentItems: 0, + improvementItems: 0, + overallPerformance: 0 + }; + } + + // 計算所有項目的平均分數(不考慮權重) + const totalScore = criteria.reduce((sum, item) => sum + item.score, 0); + const averageScore = totalScore / criteria.length; + + // 以平均分作為閾值 + // ≥ 平均分 = 優秀項目,< 平均分 = 待改進項目 + const excellentItems = 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)); + + return { + excellentItems, + improvementItems, + overallPerformance + }; + }; + // 確保所有必要的數據結構存在 const safeResults = { ...results, - overview: results.overview || { - excellentItems: 0, - improvementItems: 0, - overallPerformance: 0 - }, + overview: results.overview || calculateOverview(results.criteria || []), chartData: results.chartData || { barChart: [], pieChart: [], diff --git a/app/upload/page.tsx b/app/upload/page.tsx index 7faf7eb..28e92d3 100644 --- a/app/upload/page.tsx +++ b/app/upload/page.tsx @@ -226,7 +226,7 @@ export default function UploadPage() {
- +
- +