// 初始化仪表盘面板 function initDashboardPanel() { // 加载统计数据 loadDashboardData(); } // 加载仪表盘数据 function loadDashboardData() { // 加载24小时统计数据 loadHourlyStats(); // 加载请求类型分布 loadRequestsDistribution(); // 加载最常屏蔽的域名 loadTopBlockedDomains(); // 加载最常解析的域名 loadTopResolvedDomains(); } // 加载24小时统计数据 function loadHourlyStats() { apiRequest('/api/hourly-stats') .then(data => { if (data && data.labels && data.data) { // 只使用一组数据(假设是屏蔽请求数) renderHourlyChart(data.labels, data.data, []); } }) .catch(error => { console.error('获取24小时统计失败:', error); }); } // 渲染24小时统计图表 function renderHourlyChart(hours, blocked, allowed) { const ctx = document.getElementById('hourly-chart'); if (!ctx) return; // 销毁现有图表 if (window.hourlyChart) { window.hourlyChart.destroy(); } // 创建新图表 window.hourlyChart = new Chart(ctx, { type: 'line', data: { labels: hours, datasets: [ { label: '屏蔽请求', data: blocked, borderColor: '#e74c3c', backgroundColor: 'rgba(231, 76, 60, 0.1)', borderWidth: 2, tension: 0.3, fill: true }, { label: '允许请求', data: allowed, borderColor: '#2ecc71', backgroundColor: 'rgba(46, 204, 113, 0.1)', borderWidth: 2, tension: 0.3, fill: true } ] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, title: { display: true, text: '请求数' } }, x: { title: { display: true, text: '时间(小时)' } } }, plugins: { legend: { position: 'top', }, tooltip: { mode: 'index', intersect: false } } } }); } // 加载请求类型分布 function loadRequestsDistribution() { apiRequest('/api/stats') .then(data => { if (data && data.dns) { // 构造饼图所需的数据 const labels = ['允许请求', '屏蔽请求', '错误请求']; const requestData = [ data.dns.Allowed || 0, data.dns.Blocked || 0, data.dns.Error || 0 ]; renderRequestsPieChart(labels, requestData); } }) .catch(error => { console.error('获取请求类型分布失败:', error); }); } // 渲染请求类型饼图 function renderRequestsPieChart(labels, data) { const ctx = document.getElementById('requests-pie-chart'); if (!ctx) return; // 销毁现有图表 if (window.requestsPieChart) { window.requestsPieChart.destroy(); } // 创建新图表 window.requestsPieChart = new Chart(ctx, { type: 'doughnut', data: { labels: labels, datasets: [{ data: data, backgroundColor: [ '#2ecc71', // 允许 '#e74c3c', // 屏蔽 '#f39c12', // 错误 '#9b59b6' // 其他 ], borderWidth: 2, borderColor: '#fff' }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'right', }, tooltip: { callbacks: { label: function(context) { const label = context.label || ''; const value = context.raw || 0; const total = context.dataset.data.reduce((a, b) => a + b, 0); const percentage = ((value / total) * 100).toFixed(1); return `${label}: ${value} (${percentage}%)`; } } } }, cutout: '60%' } }); } // 加载最常屏蔽的域名 function loadTopBlockedDomains() { apiRequest('/api/top-blocked') .then(data => { renderTopBlockedDomains(data); }) .catch(error => { console.error('获取最常屏蔽域名失败:', error); showError(document.getElementById('top-blocked-table').querySelector('tbody'), '获取数据失败'); }); } // 渲染最常屏蔽的域名表格 function renderTopBlockedDomains(domains) { const tbody = document.getElementById('top-blocked-table').querySelector('tbody'); if (!tbody) return; if (!domains || domains.length === 0) { showEmpty(tbody, '暂无屏蔽记录'); return; } tbody.innerHTML = ''; domains.forEach((domain, index) => { const row = document.createElement('tr'); row.innerHTML = `