更新web显示

This commit is contained in:
Alex Yang
2025-11-23 18:51:08 +08:00
parent 15c87a9d94
commit 63a95f7463

View File

@@ -508,10 +508,25 @@
}
.status-info {
background-color: var(--gray-50);
margin-top: 2rem;
padding: 1.5rem;
background-color: var(--gray-50);
border-radius: var(--border-radius-lg);
border-left: 4px solid var(--info-color);
box-shadow: var(--shadow);
}
.status-info h3 {
margin-bottom: 1rem;
}
.status-info p {
margin: 0.5rem 0;
line-height: 1.6;
}
.status-info .stat-card {
border-top: 4px solid var(--primary-color);
}
.status-info p {
@@ -659,25 +674,20 @@
<!-- 概览面板 -->
<div id="dashboard" class="tab-content active">
<h2 style="margin-bottom: 1.5rem;">服务器状态</h2>
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.5rem;">
<h2>服务器状态</h2>
<div style="display: flex; gap: 1rem;">
<div style="background-color: white; padding: 0.5rem 1rem; border-radius: var(--border-radius-md); box-shadow: var(--shadow); display: flex; align-items: center; gap: 0.5rem;">
<i class="fas fa-ban" style="color: var(--primary-color);"></i>
<span style="font-size: 1rem; font-weight: 600;">规则: <span id="rules-count-inline">--</span></span>
</div>
<div style="background-color: white; padding: 0.5rem 1rem; border-radius: var(--border-radius-md); box-shadow: var(--shadow); display: flex; align-items: center; gap: 0.5rem;">
<i class="fas fa-file-alt" style="color: var(--primary-color);"></i>
<span style="font-size: 1rem; font-weight: 600;">Hosts: <span id="hosts-count-inline">--</span></span>
</div>
</div>
</div>
<div class="stats-grid">
<div class="stat-card">
<i class="fas fa-ban"></i>
<div class="stat-value" id="rules-count">--</div>
<div class="stat-label">屏蔽规则数</div>
<div class="mini-chart-container">
<canvas id="rules-chart"></canvas>
</div>
</div>
<div class="stat-card">
<i class="fas fa-file-alt"></i>
<div class="stat-value" id="hosts-count">--</div>
<div class="stat-label">Hosts条目数</div>
<div class="mini-chart-container">
<canvas id="hosts-chart"></canvas>
</div>
</div>
<div class="stat-card">
<i class="fas fa-question-circle"></i>
<div class="stat-value" id="query-count">--</div>
@@ -739,6 +749,24 @@
</div>
<div class="status-info">
<h3 style="margin-bottom: 1rem; font-size: 1.25rem; color: var(--gray-700);">服务器信息</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1rem; margin-bottom: 1.5rem;">
<div class="stat-card">
<i class="fas fa-ban"></i>
<div class="stat-value" id="rules-count">--</div>
<div class="stat-label">屏蔽规则数</div>
<div class="mini-chart-container">
<canvas id="rules-chart"></canvas>
</div>
</div>
<div class="stat-card">
<i class="fas fa-file-alt"></i>
<div class="stat-value" id="hosts-count">--</div>
<div class="stat-label">Hosts条目数</div>
<div class="mini-chart-container">
<canvas id="hosts-chart"></canvas>
</div>
</div>
</div>
<p><strong>服务器地址:</strong> <span id="server-address">--</span></p>
<p><strong>当前时间:</strong> <span id="current-time">--</span></p>
<p><strong>运行状态:</strong> <span class="badge badge-success">正常运行</span></p>
@@ -994,7 +1022,19 @@
display: false
},
tooltip: {
enabled: false
enabled: true,
backgroundColor: 'rgba(0, 0, 0, 0.7)',
titleColor: '#fff',
bodyColor: '#fff',
borderColor: '#333',
borderWidth: 1,
cornerRadius: 4,
displayColors: false,
callbacks: {
label: function(context) {
return context.dataset.label + ': ' + context.parsed.y;
}
}
}
},
scales: {
@@ -1006,7 +1046,11 @@
beginAtZero: true
}
},
animation: false
animation: false,
interaction: {
intersect: false,
mode: 'index'
}
}
});
});
@@ -1073,29 +1117,52 @@
document.getElementById('current-time').textContent = new Date().toLocaleString('zh-CN');
fetch('/api/stats')
.then(response => response.json())
.then(response => {
if (!response.ok) {
throw new Error('HTTP error! status: ' + response.status);
}
return response.json();
})
.then(data => {
// 检查数据是否有变动
if (isDataChanged(data, previousFullData)) {
console.log('数据有变动,正在更新页面...');
console.log('获取到统计数据:', data);
// 确保数据结构正确
if (!data || !data.shield) {
console.error('返回的数据结构不正确缺少shield字段');
// 即使数据结构不正确,也尝试更新服务器地址
document.getElementById('server-address').textContent = window.location.hostname + ':8080';
return;
}
// 获取各项统计数据
const rulesCount = (data.shield && (data.shield.domainRules + data.shield.regexRules)) || 0;
const hostsCount = (data.shield && data.shield.hostsRules) || 0;
const domainRules = data.shield.domainRules || 0;
const regexRules = data.shield.regexRules || 0;
const rulesCount = domainRules + regexRules;
const hostsCount = data.shield.hostsRules || 0;
const queryCount = (data.dns && data.dns.Queries) || 0;
const blockedCount = (data.dns && data.dns.Blocked) || 0;
// 检查数据变化并添加动画
checkAndAnimate('rules-count', rulesCount);
checkAndAnimate('hosts-count', hostsCount);
checkAndAnimate('query-count', queryCount);
checkAndAnimate('blocked-count', blockedCount);
console.log(`规则统计: 域名规则=${domainRules}, 正则规则=${regexRules}, 总计=${rulesCount}`);
console.log(`Hosts统计: 条目数=${hostsCount}`);
// 更新显示
// 直接更新显示,同时更新顶部状态区域和统计卡片
document.getElementById('rules-count').textContent = rulesCount;
document.getElementById('hosts-count').textContent = hostsCount;
document.getElementById('query-count').textContent = queryCount;
document.getElementById('blocked-count').textContent = blockedCount;
// 更新顶部服务器状态区域的数据
document.getElementById('rules-count-inline').textContent = rulesCount;
document.getElementById('hosts-count-inline').textContent = hostsCount;
// 更新屏蔽次数显示,包含百分比
const blockedPercentage = queryCount > 0 ? Math.round((blockedCount / queryCount) * 100) : 0;
const blockedElement = document.getElementById('blocked-count');
if (blockedElement) {
blockedElement.innerHTML = blockedCount +
'<span style="position: absolute; top: -10px; right: -20px; ' +
'background-color: #ff6b6b; color: white; border-radius: 50%; padding: 2px 6px; ' +
'font-size: 0.7rem; font-weight: bold;">' + blockedPercentage + '%</span>';
}
document.getElementById('server-address').textContent = window.location.hostname + ':8080';
// 更新数据历史记录
@@ -1113,14 +1180,23 @@
// 更新完整数据缓存
previousFullData = JSON.parse(JSON.stringify(data));
// 数据有变动时才加载其他相关数据
// 加载其他相关数据
loadChartData();
loadTopDomains();
} else {
console.log('数据无变动,不更新页面');
}
})
.catch(error => console.error('加载统计数据失败:', error));
.catch(error => {
console.error('加载统计数据失败:', error);
// 即使出错,也尝试更新服务器地址
document.getElementById('server-address').textContent = window.location.hostname + ':8080';
// 尝试直接从本地文件加载规则和hosts数量备用方案
try {
console.log('尝试备用方案加载规则和hosts数量...');
// 这里可以添加从其他接口或本地缓存获取数据的逻辑
} catch (e) {
console.error('备用方案也失败:', e);
}
});
}
// 保存上一次的图表数据,用于检测图表数据是否变化
@@ -1177,10 +1253,32 @@ function renderBlockChart(labels, data) {
plugins: {
legend: {
position: 'top',
labels: {
padding: 20,
font: {
size: 14
}
}
},
tooltip: {
mode: 'index',
intersect: false,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
titleColor: '#fff',
bodyColor: '#fff',
borderColor: '#333',
borderWidth: 1,
cornerRadius: 6,
padding: 12,
displayColors: false,
callbacks: {
title: function(tooltipItems) {
return tooltipItems[0].label + ' 时';
},
label: function(context) {
return '屏蔽次数: ' + context.parsed.y;
}
}
}
},
scales: {
@@ -1188,6 +1286,9 @@ function renderBlockChart(labels, data) {
beginAtZero: true,
ticks: {
precision: 0
},
grid: {
color: 'rgba(0, 0, 0, 0.05)'
}
},
x: {