diff --git a/BACKEND_STAGE1_REPORT.md b/BACKEND_STAGE1_REPORT.md new file mode 100644 index 0000000..3af54e0 --- /dev/null +++ b/BACKEND_STAGE1_REPORT.md @@ -0,0 +1,109 @@ +# AI Showcase Platform - Backend Stage 1 完成報告 + +## ✅ 第一階段功能清單 + +- [x] .env 檔案配置 +- [x] Next.js API Routes 架構 +- [x] CORS/中間件/錯誤處理 +- [x] 日誌系統(lib/logger.ts) +- [x] 認證與授權系統(JWT, bcrypt, 角色權限) +- [x] 登入/登出 API +- [x] 密碼加密與驗證 +- [x] 角色權限控制 (user/developer/admin) +- [x] 密碼重設 API(含驗證碼流程) +- [x] 用戶註冊 API +- [x] 用戶資料查詢/更新 API +- [x] 用戶列表 API(管理員用) +- [x] 用戶統計 API + +--- + +## 🛠️ 主要 API 路徑 + +| 路徑 | 方法 | 權限 | 說明 | +|------|------|------|------| +| `/api` | GET | 公開 | 健康檢查 | +| `/api/auth/register` | POST | 公開 | 用戶註冊 | +| `/api/auth/login` | POST | 公開 | 用戶登入(回傳 JWT) | +| `/api/auth/me` | GET | 登入 | 取得當前用戶資料 | +| `/api/auth/reset-password/request` | POST | 公開 | 密碼重設請求(產生驗證碼) | +| `/api/auth/reset-password/confirm` | POST | 公開 | 密碼重設確認(驗證碼+新密碼) | +| `/api/users` | GET | 管理員 | 用戶列表(分頁) | +| `/api/users/stats` | GET | 管理員 | 用戶統計資料 | + +--- + +## 👤 測試用帳號 + +- 管理員帳號: + - Email: `admin@theaken.com` + - 密碼: `Admin@2025`(已重設) + - 角色: `admin` + +- 測試用戶: + - Email: `test@theaken.com` / `test@example.com` + - 密碼: `Test@2024` + - 角色: `user` + +--- + +## 🧪 自動化測試腳本與結果 + +### 1. 健康檢查 API +``` +GET /api +→ 200 OK +{"message":"AI Platform API is running", ...} +``` + +### 2. 註冊 API +``` +POST /api/auth/register { name, email, password, department } +→ 409 已註冊(重複測試) +``` + +### 3. 登入 API +``` +POST /api/auth/login { email, password } +→ 200 OK, 回傳 JWT +``` + +### 4. 取得當前用戶 +``` +GET /api/auth/me (需 JWT) +→ 200 OK, 回傳用戶資料 +``` + +### 5. 用戶列表(管理員) +``` +GET /api/users (需管理員 JWT) +→ 200 OK, 回傳用戶列表與分頁 +``` + +### 6. 密碼重設流程 +``` +POST /api/auth/reset-password/request { email } +→ 200 OK, 回傳驗證碼 +POST /api/auth/reset-password/confirm { email, code, newPassword } +→ 200 OK, 密碼重設成功 +``` + +### 7. 用戶統計 +``` +GET /api/users/stats (需管理員 JWT) +→ 200 OK, { total, admin, developer, user, today } +``` + +--- + +## 📝 測試結果摘要 + +- 所有 API 路徑皆可正常運作,權限驗證正確。 +- 密碼重設流程可用(驗證碼測試用直接回傳)。 +- 用戶列表、統計、註冊、登入、查詢皆通過。 +- 日誌系統可記錄 API 請求與錯誤。 + +--- + +> 本報告可作為雙方確認第一階段後端功能完成度與測試依據。 +> 完成後可刪除本 MD。 \ No newline at end of file diff --git a/CHATBOT_ANALYSIS.md b/CHATBOT_ANALYSIS.md index 468ada2..07a76d7 100644 --- a/CHATBOT_ANALYSIS.md +++ b/CHATBOT_ANALYSIS.md @@ -45,7 +45,7 @@ const [isLoading, setIsLoading] = useState(false) // 載入狀態 ### 2.3 API整合 ```typescript // DeepSeek API 配置 -const DEEPSEEK_API_KEY = "sk-3640dcff23fe4a069a64f536ac538d75" +const DEEPSEEK_API_KEY = "your_api_key_here" const DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions" // API 調用函數 diff --git a/DATABASE_GUIDE.md b/DATABASE_GUIDE.md new file mode 100644 index 0000000..6713ada --- /dev/null +++ b/DATABASE_GUIDE.md @@ -0,0 +1,379 @@ +# 🗄️ AI展示平台資料庫指南 + +## 📋 資料庫概述 + +AI展示平台使用 **MySQL** 作為主要資料庫,支援完整的競賽管理、用戶認證、評審系統和AI助手功能。 + +### 🔗 連接資訊 +- **主機**: mysql.theaken.com +- **埠號**: 33306 +- **資料庫**: db_AI_Platform +- **用戶**: AI_Platform +- **密碼**: Aa123456 + +## 🏗️ 資料庫結構 + +### 📊 核心資料表 (18個) + +#### 1. 用戶管理 +- **users** - 用戶基本資料 +- **user_favorites** - 用戶收藏 +- **user_likes** - 用戶按讚記錄 + +#### 2. 競賽系統 +- **competitions** - 競賽基本資料 +- **competition_participants** - 競賽參與者 +- **competition_judges** - 競賽評審分配 + +#### 3. 團隊管理 +- **teams** - 團隊基本資料 +- **team_members** - 團隊成員 + +#### 4. 作品管理 +- **apps** - AI應用程式 +- **proposals** - 提案作品 + +#### 5. 評審系統 +- **judges** - 評審基本資料 +- **judge_scores** - 評審評分 + +#### 6. 獎項系統 +- **awards** - 獎項記錄 + +#### 7. AI助手 +- **chat_sessions** - 聊天會話 +- **chat_messages** - 聊天訊息 +- **ai_assistant_configs** - AI配置 + +#### 8. 系統管理 +- **system_settings** - 系統設定 +- **activity_logs** - 活動日誌 + +## 🚀 快速開始 + +### 1. 環境設定 + +```bash +# 複製環境變數範例 +cp env.example .env.local + +# 編輯環境變數 +nano .env.local +``` + +### 2. 安裝依賴 + +```bash +# 安裝新依賴 +pnpm install +``` + +### 3. 建立資料庫 + +```bash +# 建立資料庫和資料表 +pnpm run db:setup +``` + +### 4. 測試連接 + +```bash +# 測試資料庫連接 +pnpm run db:test +``` + +## 📊 資料表詳細說明 + +### users 表 +```sql +CREATE TABLE users ( + id VARCHAR(36) PRIMARY KEY, + name VARCHAR(100) NOT NULL, + email VARCHAR(255) UNIQUE NOT NULL, + password_hash VARCHAR(255) NOT NULL, + avatar VARCHAR(500), + department VARCHAR(100) NOT NULL, + role ENUM('user', 'developer', 'admin') DEFAULT 'user', + join_date DATE NOT NULL, + total_likes INT DEFAULT 0, + total_views INT DEFAULT 0, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +); +``` + +**用途**: 儲存所有用戶資料 +**角色**: +- `user`: 一般用戶 (瀏覽、投票) +- `developer`: 開發者 (提交作品、參賽) +- `admin`: 管理員 (系統管理、數據分析) + +### competitions 表 +```sql +CREATE TABLE competitions ( + id VARCHAR(36) PRIMARY KEY, + name VARCHAR(200) NOT NULL, + year INT NOT NULL, + month INT NOT NULL, + start_date DATE NOT NULL, + end_date DATE NOT NULL, + status ENUM('upcoming', 'active', 'judging', 'completed') DEFAULT 'upcoming', + description TEXT, + type ENUM('individual', 'team', 'mixed', 'proposal') NOT NULL, + evaluation_focus TEXT, + max_team_size INT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +); +``` + +**競賽狀態流程**: `upcoming` → `active` → `judging` → `completed` +**競賽類型**: +- `individual`: 個人賽 +- `team`: 團隊賽 +- `mixed`: 混合賽 +- `proposal`: 提案賽 + +### judge_scores 表 +```sql +CREATE TABLE judge_scores ( + id VARCHAR(36) PRIMARY KEY, + judge_id VARCHAR(36) NOT NULL, + app_id VARCHAR(36), + proposal_id VARCHAR(36), + scores JSON NOT NULL, + comments TEXT, + submitted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +**評分維度** (JSON格式): +```json +{ + "innovation": 8, // 創新性 (1-10) + "technical": 7, // 技術性 (1-10) + "usability": 9, // 實用性 (1-10) + "presentation": 8, // 展示效果 (1-10) + "impact": 7 // 影響力 (1-10) +} +``` + +## 🔍 查詢範例 + +### 1. 獲取用戶統計 +```sql +SELECT + u.name, + u.department, + u.role, + COUNT(DISTINCT a.id) as total_apps, + COUNT(DISTINCT f.app_id) as total_favorites, + u.total_likes, + u.total_views +FROM users u +LEFT JOIN apps a ON u.id = a.creator_id +LEFT JOIN user_favorites f ON u.id = f.user_id +GROUP BY u.id; +``` + +### 2. 獲取競賽統計 +```sql +SELECT + c.name, + c.status, + c.type, + COUNT(DISTINCT cp.user_id) as participant_count, + COUNT(DISTINCT cp.team_id) as team_count, + COUNT(DISTINCT cp.app_id) as app_count +FROM competitions c +LEFT JOIN competition_participants cp ON c.id = cp.competition_id +GROUP BY c.id; +``` + +### 3. 獲取應用排行榜 +```sql +SELECT + a.name, + u.name as creator_name, + t.name as team_name, + a.likes_count, + a.views_count, + a.rating, + ROW_NUMBER() OVER (ORDER BY a.likes_count DESC) as popularity_rank +FROM apps a +LEFT JOIN users u ON a.creator_id = u.id +LEFT JOIN teams t ON a.team_id = t.id; +``` + +## 🛠️ 存儲過程 + +### GetUserPermissions +```sql +CALL GetUserPermissions('user@example.com'); +``` +**用途**: 獲取用戶權限和基本資料 + +### GetCompetitionStats +```sql +CALL GetCompetitionStats('comp-2025-01'); +``` +**用途**: 獲取競賽統計資料 + +### CalculateAwardRankings +```sql +CALL CalculateAwardRankings('comp-2025-01'); +``` +**用途**: 計算獎項排名 + +## 👁️ 視圖 (Views) + +### user_statistics +顯示用戶統計資料,包含作品數、收藏數、按讚數等 + +### competition_statistics +顯示競賽統計資料,包含參與者數、團隊數、作品數等 + +### app_rankings +顯示應用排行榜,包含人氣排名和評分排名 + +## 🔧 觸發器 (Triggers) + +### update_user_total_likes +當用戶按讚時,自動更新用戶總按讚數 + +### update_app_likes_count +當應用被按讚時,自動更新應用按讚數 + +### update_user_total_views +當應用瀏覽數更新時,自動更新用戶總瀏覽數 + +## 📈 索引優化 + +### 主要索引 +- `users.email` - 用戶郵箱查詢 +- `users.role` - 角色權限查詢 +- `competitions.status` - 競賽狀態查詢 +- `apps.likes_count` - 人氣排序 +- `apps.rating` - 評分排序 + +### 複合索引 +- `competitions.year, competitions.month` - 時間範圍查詢 +- `competitions.start_date, competitions.end_date` - 日期範圍查詢 + +## 🔒 安全性 + +### 密碼加密 +使用 bcrypt 進行密碼雜湊,鹽值輪數為 10 + +### 外鍵約束 +所有關聯表都設定了適當的外鍵約束,確保資料完整性 + +### 唯一約束 +- 用戶郵箱唯一 +- 用戶每日按讚限制 +- 評審對同一作品只能評分一次 + +## 📊 性能監控 + +### 查詢統計 +```sql +-- 查看慢查詢 +SHOW VARIABLES LIKE 'slow_query_log'; +SHOW VARIABLES LIKE 'long_query_time'; + +-- 查看連接數 +SHOW STATUS LIKE 'Threads_connected'; +SHOW STATUS LIKE 'Max_used_connections'; +``` + +### 資料表大小 +```sql +SELECT + table_name, + ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)' +FROM information_schema.tables +WHERE table_schema = 'db_AI_Platform' +ORDER BY (data_length + index_length) DESC; +``` + +## 🚨 故障排除 + +### 常見問題 + +#### 1. 連接失敗 +```bash +# 檢查網路連接 +ping mysql.theaken.com + +# 檢查埠號 +telnet mysql.theaken.com 33306 +``` + +#### 2. 權限錯誤 +```sql +-- 檢查用戶權限 +SHOW GRANTS FOR 'AI_Platform'@'%'; +``` + +#### 3. 資料表不存在 +```bash +# 重新執行建立腳本 +pnpm run db:setup +``` + +#### 4. 密碼錯誤 +```bash +# 檢查環境變數 +echo $DB_PASSWORD +``` + +## 📝 維護指南 + +### 定期備份 +```bash +# 建立備份 +mysqldump -h mysql.theaken.com -P 33306 -u AI_Platform -p db_AI_Platform > backup_$(date +%Y%m%d).sql +``` + +### 資料清理 +```sql +-- 清理過期的活動日誌 (保留30天) +DELETE FROM activity_logs WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY); + +-- 清理過期的聊天會話 (保留7天) +DELETE FROM chat_sessions WHERE updated_at < DATE_SUB(NOW(), INTERVAL 7 DAY); +``` + +### 性能優化 +```sql +-- 分析資料表 +ANALYZE TABLE users, competitions, apps; + +-- 優化資料表 +OPTIMIZE TABLE users, competitions, apps; +``` + +## 🔄 版本更新 + +### 新增欄位 +```sql +-- 範例:為 users 表新增欄位 +ALTER TABLE users ADD COLUMN phone VARCHAR(20) AFTER email; +``` + +### 修改欄位 +```sql +-- 範例:修改欄位類型 +ALTER TABLE users MODIFY COLUMN department VARCHAR(150); +``` + +### 新增索引 +```sql +-- 範例:新增複合索引 +CREATE INDEX idx_user_department_role ON users(department, role); +``` + +--- + +**最後更新**: 2025年1月 +**維護者**: AI展示平台開發團隊 \ No newline at end of file diff --git a/DATABASE_SETUP_COMPLETE.md b/DATABASE_SETUP_COMPLETE.md new file mode 100644 index 0000000..b841612 --- /dev/null +++ b/DATABASE_SETUP_COMPLETE.md @@ -0,0 +1,186 @@ +# 🎉 AI展示平台資料庫建立完成! + +## 📊 建立結果總結 + +### ✅ 成功建立的資料表 (18個) + +| 序號 | 資料表名稱 | 狀態 | 記錄數 | +|------|------------|------|--------| +| 1 | users | ✅ | 1 | +| 2 | competitions | ✅ | 2 | +| 3 | judges | ✅ | 3 | +| 4 | teams | ✅ | 0 | +| 5 | team_members | ✅ | 0 | +| 6 | apps | ✅ | 0 | +| 7 | proposals | ✅ | 0 | +| 8 | judge_scores | ✅ | 0 | +| 9 | awards | ✅ | 0 | +| 10 | chat_sessions | ✅ | 0 | +| 11 | chat_messages | ✅ | 0 | +| 12 | ai_assistant_configs | ✅ | 1 | +| 13 | user_favorites | ✅ | 0 | +| 14 | user_likes | ✅ | 0 | +| 15 | competition_participants | ✅ | 0 | +| 16 | competition_judges | ✅ | 0 | +| 17 | system_settings | ✅ | 8 | +| 18 | activity_logs | ✅ | 0 | + +### 📈 初始數據統計 + +- **管理員用戶**: 1 筆 (admin@theaken.com) +- **預設評審**: 3 筆 (張教授、李經理、王工程師) +- **預設競賽**: 2 筆 (2025年AI創新競賽、2025年提案競賽) +- **AI助手配置**: 1 筆 +- **系統設定**: 8 筆 (包含各種系統參數) + +## 🔗 資料庫連接資訊 + +- **主機**: mysql.theaken.com +- **埠號**: 33306 +- **資料庫**: db_AI_Platform +- **用戶**: AI_Platform +- **密碼**: Aa123456 +- **MySQL版本**: 9.3.0 + +## 🛠️ 建立的腳本文件 + +1. **`database_setup.sql`** - 完整版SQL腳本 (包含觸發器和存儲過程) +2. **`database_setup_simple.sql`** - 簡化版SQL腳本 (僅基本資料表) +3. **`scripts/setup-database.js`** - 自動化建立腳本 +4. **`scripts/setup-database-manual.js`** - 手動建立腳本 +5. **`scripts/fix-tables.js`** - 修復資料表腳本 +6. **`scripts/fix-user-likes.js`** - 修復user_likes表腳本 +7. **`database_connection_test.js`** - 連接測試腳本 +8. **`lib/database.ts`** - 資料庫操作工具類 + +## 📋 可用的npm腳本 + +```bash +# 建立資料庫 +pnpm run db:setup + +# 測試連接 +pnpm run db:test + +# 手動建立 (推薦) +node scripts/setup-database-manual.js + +# 修復資料表 +node scripts/fix-tables.js +``` + +## 🔧 資料庫功能特色 + +### 🏗️ 完整的資料結構 +- **18個核心資料表** 支援所有平台功能 +- **完整的外鍵約束** 確保資料完整性 +- **優化的索引設計** 提升查詢效能 +- **JSON欄位支援** 儲存複雜資料結構 + +### 🔒 安全性設計 +- **密碼加密**: 使用bcrypt進行密碼雜湊 +- **唯一約束**: 防止重複資料 +- **外鍵約束**: 確保資料關聯完整性 +- **索引優化**: 提升查詢效能 + +### 📊 初始數據 +- **預設管理員**: admin@theaken.com (密碼: admin123) +- **預設評審**: 3位不同專業領域的評審 +- **預設競賽**: 2個不同類型的競賽 +- **系統設定**: 8個核心系統參數 + +## 🚀 下一步開發計劃 + +### 1. 後端API開發 +```bash +# 建議的API端點 +/api/auth/login # 用戶登入 +/api/auth/register # 用戶註冊 +/api/competitions # 競賽管理 +/api/users # 用戶管理 +/api/judges # 評審管理 +/api/apps # 應用管理 +/api/teams # 團隊管理 +/api/awards # 獎項管理 +``` + +### 2. 前端整合 +```bash +# 替換Mock數據 +- 更新 auth-context.tsx 使用真實API +- 更新 competition-context.tsx 使用真實API +- 實現真實的用戶認證 +- 連接資料庫進行CRUD操作 +``` + +### 3. 環境配置 +```bash +# 複製環境變數 +cp env.example .env.local + +# 編輯環境變數 +nano .env.local +``` + +## 📝 使用指南 + +### 1. 連接資料庫 +```typescript +import { db } from '@/lib/database' + +// 查詢用戶 +const users = await db.query('SELECT * FROM users') + +// 插入數據 +const userId = await db.insert('users', { + id: 'user-001', + name: '測試用戶', + email: 'test@example.com', + password_hash: 'hashed_password', + department: '技術部', + role: 'user', + join_date: '2025-01-01' +}) +``` + +### 2. 用戶認證 +```typescript +// 登入驗證 +const user = await db.queryOne( + 'SELECT * FROM users WHERE email = ? AND password_hash = ?', + [email, hashedPassword] +) +``` + +### 3. 競賽管理 +```typescript +// 獲取競賽列表 +const competitions = await db.query( + 'SELECT * FROM competitions ORDER BY created_at DESC' +) +``` + +## 🎯 專案狀態 + +- ✅ **資料庫設計**: 完成 +- ✅ **資料表建立**: 完成 +- ✅ **初始數據**: 完成 +- ✅ **連接測試**: 完成 +- 🔄 **後端API**: 待開發 +- 🔄 **前端整合**: 待開發 +- 🔄 **部署配置**: 待開發 + +## 📞 技術支援 + +如果遇到問題,請檢查: + +1. **連接問題**: 確認主機、埠號、用戶名、密碼 +2. **權限問題**: 確認用戶有足夠的資料庫權限 +3. **語法錯誤**: 檢查SQL語句語法 +4. **依賴問題**: 確認已安裝所有必要依賴 + +--- + +**建立時間**: 2025年1月 +**建立者**: AI展示平台開發團隊 +**狀態**: ✅ 完成 \ No newline at end of file diff --git a/README.md b/README.md index ce13c6f..2259bcc 100644 --- a/README.md +++ b/README.md @@ -74,8 +74,7 @@ ai-showcase-platform/ ├── app/ # Next.js App Router │ ├── admin/ # 管理員頁面 │ │ ├── page.tsx # 管理員主頁 -│ │ ├── scoring/ # 評分管理 -│ │ └── scoring-test/ # 評分測試 +│ │ └── scoring/ # 評分管理 │ ├── competition/ # 競賽頁面 │ ├── judge-scoring/ # 評審評分頁面 │ ├── register/ # 註冊頁面 diff --git a/SECURITY_CHECKLIST.md b/SECURITY_CHECKLIST.md new file mode 100644 index 0000000..8303907 --- /dev/null +++ b/SECURITY_CHECKLIST.md @@ -0,0 +1,73 @@ +# 🔒 安全檢查清單 + +## ✅ 已清理的敏感資訊 + +### 1. 測試帳號資訊 +- ✅ 移除 `components/auth/login-dialog.tsx` 中的測試帳號顯示 +- ✅ 清理測試帳號:`zhang@panjit.com` +- ✅ 清理測試密碼:`password123` + +### 2. API 金鑰 +- ✅ 移除 `components/chat-bot.tsx` 中的硬編碼 API 金鑰 +- ✅ 清理 `CHATBOT_ANALYSIS.md` 中的示例 API 金鑰 +- ✅ 使用環境變數管理 API 金鑰 + +### 3. 測試頁面 +- ✅ 刪除 `app/admin/scoring-test/page.tsx` +- ✅ 刪除 `app/admin/scoring-form-test/page.tsx` +- ✅ 更新 README.md 中的目錄結構 + +### 4. 測試功能 +- ✅ 修改 `components/admin/system-settings.tsx` 中的測試郵件功能 +- ✅ 添加安全註釋到認證邏輯中 + +## 🔍 安全檢查項目 + +### 環境變數 +- [ ] 確保 `.env.local` 檔案已加入 `.gitignore` +- [ ] 檢查是否有硬編碼的 API 金鑰 +- [ ] 驗證所有敏感資訊都使用環境變數 + +### 認證系統 +- [ ] 生產環境應使用真實的認證服務 +- [ ] 移除所有測試帳號和密碼 +- [ ] 實施適當的密碼加密 + +### 代碼安全 +- [ ] 移除所有測試和調試代碼 +- [ ] 檢查是否有敏感資訊洩露 +- [ ] 確保錯誤訊息不包含敏感資訊 + +## 🚨 生產環境注意事項 + +1. **API 金鑰管理** + - 使用環境變數存儲所有 API 金鑰 + - 定期輪換 API 金鑰 + - 監控 API 使用情況 + +2. **認證系統** + - 實施真實的用戶認證 + - 使用安全的密碼加密 + - 實施適當的會話管理 + +3. **數據安全** + - 加密敏感數據 + - 實施適當的訪問控制 + - 定期備份數據 + +4. **監控和日誌** + - 實施安全事件監控 + - 記錄所有認證嘗試 + - 監控異常活動 + +## 📝 更新記錄 + +- **2025-01-XX**: 初始安全清理 + - 移除測試帳號資訊 + - 清理硬編碼 API 金鑰 + - 刪除測試頁面 + - 更新文檔 + +--- + +**注意**: 此清單應定期更新,確保系統安全性。 \ No newline at end of file diff --git a/app/admin/scoring-form-test/page.tsx b/app/admin/scoring-form-test/page.tsx deleted file mode 100644 index 5eb433e..0000000 --- a/app/admin/scoring-form-test/page.tsx +++ /dev/null @@ -1,195 +0,0 @@ -"use client" - -import { useState } from "react" -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" -import { Button } from "@/components/ui/button" -import { Label } from "@/components/ui/label" -import { Textarea } from "@/components/ui/textarea" -import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog" -import { CheckCircle, Edit, Loader2 } from "lucide-react" - -export default function ScoringFormTestPage() { - const [showScoringForm, setShowScoringForm] = useState(false) - const [manualScoring, setManualScoring] = useState({ - judgeId: "judge1", - participantId: "app1", - scores: { - "創新性": 0, - "技術性": 0, - "實用性": 0, - "展示效果": 0, - "影響力": 0 - }, - comments: "" - }) - const [isLoading, setIsLoading] = useState(false) - - const scoringRules = [ - { name: "創新性", description: "技術創新程度和獨特性", weight: 25 }, - { name: "技術性", description: "技術實現的複雜度和穩定性", weight: 20 }, - { name: "實用性", description: "實際應用價值和用戶體驗", weight: 25 }, - { name: "展示效果", description: "演示效果和表達能力", weight: 15 }, - { name: "影響力", description: "對行業和社會的潛在影響", weight: 15 } - ] - - const calculateTotalScore = (scores: Record): number => { - let totalScore = 0 - let totalWeight = 0 - - scoringRules.forEach(rule => { - const score = scores[rule.name] || 0 - const weight = rule.weight || 1 - totalScore += score * weight - totalWeight += weight - }) - - return totalWeight > 0 ? Math.round(totalScore / totalWeight) : 0 - } - - const handleSubmitScore = async () => { - setIsLoading(true) - // 模擬提交 - setTimeout(() => { - setIsLoading(false) - setShowScoringForm(false) - }, 2000) - } - - return ( -
-
-

評分表單測試

-

測試完整的評分表單功能

-
- - - - 評分表單演示 - 點擊按鈕查看完整的評分表單 - - - - - - - - - - - - 評分表單 - - - 為參賽者進行評分,請根據各項指標進行評分 - - - -
- {/* 評分項目 */} -
-

評分項目

- {scoringRules.map((rule, index) => ( -
-
-
- -

{rule.description}

-

權重:{rule.weight}%

-
-
- - {manualScoring.scores[rule.name] || 0} / 10 - -
-
- - {/* 評分按鈕 */} -
- {Array.from({ length: 10 }, (_, i) => i + 1).map((score) => ( - - ))} -
-
- ))} -
- - {/* 總分顯示 */} -
-
-
- 總分 -

根據權重計算的綜合評分

-
-
- - {calculateTotalScore(manualScoring.scores)} - - / 10 -
-
-
- - {/* 評審意見 */} -
- -