// Dashboard Home Module - 仪表板首页相关方法 Object.assign(TSPDashboard.prototype, { async loadDashboardData() { try { const [sessionsResponse, alertsResponse, workordersResponse, knowledgeResponse] = await Promise.all([ fetch('/api/chat/sessions'), fetch('/api/alerts?per_page=1000'), fetch('/api/workorders'), fetch('/api/knowledge/stats') ]); const sessions = await sessionsResponse.json(); const alerts = await alertsResponse.json(); const workorders = await workordersResponse.json(); const knowledge = await knowledgeResponse.json(); document.getElementById('total-sessions').textContent = sessions.sessions?.length || 0; document.getElementById('total-alerts').textContent = alerts.alerts?.length || 0; document.getElementById('total-workorders').textContent = workorders.workorders?.filter(w => w.status === 'open').length || 0; document.getElementById('knowledge-count').textContent = knowledge.total_entries || 0; if (alerts.alerts) { this.updateAlertStatistics(alerts.alerts); } document.getElementById('knowledge-total').textContent = knowledge.total_entries || 0; document.getElementById('knowledge-active').textContent = knowledge.active_entries || 0; const confidencePercent = Math.round((knowledge.average_confidence || 0) * 100); document.getElementById('knowledge-confidence-bar').style.width = `${confidencePercent}%`; document.getElementById('knowledge-confidence-bar').setAttribute('aria-valuenow', confidencePercent); document.getElementById('knowledge-confidence-bar').textContent = `${confidencePercent}%`; await this.updatePerformanceChart(sessions, alerts, workorders); await this.updateSystemHealth(); await this.loadAnalytics(); } catch (error) { console.error('加载仪表板数据失败:', error); } }, initCharts() { const performanceCtx = document.getElementById('performanceChart'); if (performanceCtx) { this.charts.performance = new Chart(performanceCtx, { type: 'line', data: { labels: [], datasets: [{ label: '工单数量', data: [], borderColor: '#007bff', backgroundColor: 'rgba(0, 123, 255, 0.1)', tension: 0.4 }, { label: '预警数量', data: [], borderColor: '#dc3545', backgroundColor: 'rgba(220, 53, 69, 0.1)', tension: 0.4 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true } } } }); } const analyticsCtx = document.getElementById('analyticsChart'); if (analyticsCtx) { this.charts.analytics = new Chart(analyticsCtx, { type: 'line', data: { labels: [], datasets: [{ label: '满意度', data: [], borderColor: '#28a745', backgroundColor: 'rgba(40, 167, 69, 0.1)', tension: 0.4 }, { label: '解决时间(小时)', data: [], borderColor: '#ffc107', backgroundColor: 'rgba(255, 193, 7, 0.1)', tension: 0.4 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true } } } }); } const categoryCtx = document.getElementById('categoryChart'); if (categoryCtx) { this.charts.category = new Chart(categoryCtx, { type: 'doughnut', data: { labels: [], datasets: [{ data: [], backgroundColor: [ '#007bff', '#28a745', '#ffc107', '#dc3545', '#17a2b8' ] }] }, options: { responsive: true, maintainAspectRatio: false } }); } }, async updatePerformanceChart(sessions, alerts, workorders) { if (!this.charts.performance) return; try { const response = await fetch('/api/analytics?days=7&dimension=performance'); const analyticsData = await response.json(); if (analyticsData.trend && analyticsData.trend.length > 0) { const labels = analyticsData.trend.map(item => { const date = new Date(item.date); return `${date.getMonth() + 1}/${date.getDate()}`; }); const workorderData = analyticsData.trend.map(item => item.workorders || 0); const alertData = analyticsData.trend.map(item => item.alerts || 0); this.charts.performance.data.labels = labels; this.charts.performance.data.datasets[0].data = workorderData; this.charts.performance.data.datasets[1].data = alertData; this.charts.performance.update(); } else { this.charts.performance.data.labels = ['暂无数据']; this.charts.performance.data.datasets[0].data = [0]; this.charts.performance.data.datasets[1].data = [0]; this.charts.performance.update(); } } catch (error) { console.error('获取性能趋势数据失败:', error); this.charts.performance.data.labels = ['数据加载失败']; this.charts.performance.data.datasets[0].data = [0]; this.charts.performance.data.datasets[1].data = [0]; this.charts.performance.update(); } }, async updateSystemHealth() { try { const response = await fetch('/api/settings'); const settings = await response.json(); const healthScore = Math.max(0, 100 - (settings.memory_usage_percent || 0) - (settings.cpu_usage_percent || 0)); const healthProgress = document.getElementById('health-progress'); const healthDot = document.getElementById('system-health-dot'); const healthText = document.getElementById('system-health-text'); if (healthProgress) { healthProgress.style.width = `${healthScore}%`; healthProgress.setAttribute('aria-valuenow', healthScore); } if (healthDot) { healthDot.className = 'health-dot'; if (healthScore >= 80) healthDot.classList.add('excellent'); else if (healthScore >= 60) healthDot.classList.add('good'); else if (healthScore >= 40) healthDot.classList.add('fair'); else if (healthScore >= 20) healthDot.classList.add('poor'); else healthDot.classList.add('critical'); } if (healthText) { const statusText = healthScore >= 80 ? '优秀' : healthScore >= 60 ? '良好' : healthScore >= 40 ? '一般' : healthScore >= 20 ? '较差' : '严重'; healthText.textContent = `${statusText} (${healthScore}%)`; } const memoryProgress = document.getElementById('memory-progress'); if (memoryProgress && settings.memory_usage_percent !== undefined) { memoryProgress.style.width = `${settings.memory_usage_percent}%`; memoryProgress.setAttribute('aria-valuenow', settings.memory_usage_percent); } const cpuProgress = document.getElementById('cpu-progress'); if (cpuProgress && settings.cpu_usage_percent !== undefined) { cpuProgress.style.width = `${settings.cpu_usage_percent}%`; cpuProgress.setAttribute('aria-valuenow', settings.cpu_usage_percent); } } catch (error) { console.error('更新系统健康状态失败:', error); } }, async loadHealth() { try { const response = await fetch('/api/health'); const data = await response.json(); this.updateHealthDisplay(data); } catch (error) { console.error('加载健康状态失败:', error); } }, updateHealthDisplay(health) { const healthScore = health.health_score || 0; const healthStatus = health.status || 'unknown'; const healthDot = document.getElementById('health-dot'); const healthStatusText = document.getElementById('health-status'); const systemHealthDot = document.getElementById('system-health-dot'); const systemHealthText = document.getElementById('system-health-text'); const healthProgress = document.getElementById('health-progress'); if (healthDot) { healthDot.className = `health-dot ${healthStatus}`; } if (healthStatusText) { healthStatusText.textContent = this.getHealthStatusText(healthStatus); } if (systemHealthDot) { systemHealthDot.className = `health-dot ${healthStatus}`; } if (systemHealthText) { systemHealthText.textContent = this.getHealthStatusText(healthStatus); } if (healthProgress) { healthProgress.style.width = `${healthScore * 100}%`; healthProgress.className = `progress-bar ${this.getHealthColor(healthScore)}`; } const memoryUsage = health.memory_usage || 0; const memoryProgress = document.getElementById('memory-progress'); if (memoryProgress) { memoryProgress.style.width = `${memoryUsage}%`; } const cpuUsage = health.cpu_usage || 0; const cpuProgress = document.getElementById('cpu-progress'); if (cpuProgress) { cpuProgress.style.width = `${cpuUsage}%`; } }, getHealthStatusText(status) { const statusMap = { 'excellent': '优秀', 'good': '良好', 'fair': '一般', 'poor': '较差', 'critical': '严重', 'unknown': '未知' }; return statusMap[status] || status; }, getHealthColor(score) { if (score >= 0.8) return 'bg-success'; if (score >= 0.6) return 'bg-info'; if (score >= 0.4) return 'bg-warning'; return 'bg-danger'; } });