From c923243493fc1c6bc46c23fceac84260b3b693f4 Mon Sep 17 00:00:00 2001 From: maoshen Date: Tue, 14 Apr 2026 12:28:01 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=A4=9A=E7=BB=B4?= =?UTF-8?q?=E5=BA=A6=E8=AF=84=E5=88=86=E7=BB=9F=E8=AE=A1=E9=9D=A2=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/index.html | 112 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/frontend/index.html b/frontend/index.html index 6fa0c05..115edc7 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -22,6 +22,51 @@ gap: 20px; margin-bottom: 30px; } + .rating-stats { + background: white; + border-radius: 10px; + padding: 15px; + margin-bottom: 30px; + box-shadow: 0 4px 6px rgba(0,0,0,0.1); + } + .rating-stats h3 { + color: #333; + font-size: 1.1em; + margin-bottom: 15px; + display: flex; + align-items: center; + gap: 8px; + } + .rating-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 15px; + } + .rating-item { + background: linear-gradient(135deg, #fafaff, #f0f0ff); + padding: 12px; + border-radius: 8px; + border-left: 4px solid #667eea; + } + .rating-item .label { + font-size: 0.85em; + color: #666; + margin-bottom: 5px; + } + .rating-item .value { + font-size: 1.5em; + font-weight: bold; + color: #667eea; + } + .rating-item .value.quality { color: #10b981; } + .rating-item .value.efficiency { color: #3b82f6; } + .rating-item .value.creativity { color: #8b5cf6; } + .rating-item .value.learning { color: #f59e0b; } + .rating-item .count { + font-size: 0.8em; + color: #999; + margin-top: 5px; + } .stat-card { background: white; padding: 15px; @@ -276,6 +321,7 @@ allEntries: [], allExperiences: [], taskStats: {}, + ratingStats: {}, showCommentForm: null, commentContent: '', scores: { quality: '', efficiency: '', creativity: '', learning: '' } @@ -318,6 +364,9 @@ exp.comments = await loadComments('experience', exp.id); } + // 计算评分统计 + calculateRatingStats(); + render(); } catch (error) { document.getElementById('app').innerHTML = `
加载失败:${error.message}
`; @@ -563,10 +612,73 @@

${state.taskStats.completion_rate || 0}%

完成率

${state.expStats.total_experiences || 0}

经验

+ ${renderRatingStats()} ${content} `; } + function calculateRatingStats() { + const allComments = [ + ...state.allEntries.flatMap(e => e.comments || []), + ...state.allTasks.flatMap(t => t.comments || []), + ...state.allExperiences.flatMap(e => e.comments || []) + ]; + + const stats = { + quality: { sum: 0, count: 0 }, + efficiency: { sum: 0, count: 0 }, + creativity: { sum: 0, count: 0 }, + learning: { sum: 0, count: 0 } + }; + + allComments.forEach(c => { + if (c.quality) { stats.quality.sum += c.quality; stats.quality.count++; } + if (c.efficiency) { stats.efficiency.sum += c.efficiency; stats.efficiency.count++; } + if (c.creativity) { stats.creativity.sum += c.creativity; stats.creativity.count++; } + if (c.learning) { stats.learning.sum += c.learning; stats.learning.count++; } + }); + + state.ratingStats = { + quality: stats.quality.count > 0 ? (stats.quality.sum / stats.quality.count).toFixed(1) : '-', + efficiency: stats.efficiency.count > 0 ? (stats.efficiency.sum / stats.efficiency.count).toFixed(1) : '-', + creativity: stats.creativity.count > 0 ? (stats.creativity.sum / stats.creativity.count).toFixed(1) : '-', + learning: stats.learning.count > 0 ? (stats.learning.sum / stats.learning.count).toFixed(1) : '-', + totalComments: allComments.length + }; + } + + function renderRatingStats() { + if (state.ratingStats.totalComments === 0) return ''; + + return ` +
+

📊 多维度评分统计

+
+
+
📐 完成质量
+
${state.ratingStats.quality}
+
${state.ratingStats.totalComments} 条评价
+
+
+
⚡ 效率
+
${state.ratingStats.efficiency}
+
${state.ratingStats.totalComments} 条评价
+
+
+
💡 创新性
+
${state.ratingStats.creativity}
+
${state.ratingStats.totalComments} 条评价
+
+
+
📚 学习价值
+
${state.ratingStats.learning}
+
${state.ratingStats.totalComments} 条评价
+
+
+
+ `; + } + function switchTab(tab) { state.currentTab = tab; state.selectedTask = null; render(); } function selectTask(taskId) { state.selectedTask = state.allTasks.find(t => t.id === taskId); render(); }