diff --git a/static/js/dashboard.js b/static/js/dashboard.js
index 43236e6..795d299 100644
--- a/static/js/dashboard.js
+++ b/static/js/dashboard.js
@@ -16,7 +16,9 @@ const COLOR_CONFIG = window.COLOR_CONFIG || {};
// 初始化仪表盘
async function initDashboard() {
try {
- // 加载初始数据
+ console.log('页面打开时强制刷新数据...');
+
+ // 优先加载初始数据,确保页面显示最新信息
await loadDashboardData();
// 初始化图表
@@ -342,31 +344,94 @@ function updateStatsCards(stats) {
activeIPsPercentage = stats[0].activeIPsPercentage || 0;
}
- // 更新数量显示
- document.getElementById('total-queries').textContent = formatNumber(totalQueries);
- document.getElementById('blocked-queries').textContent = formatNumber(blockedQueries);
- document.getElementById('allowed-queries').textContent = formatNumber(allowedQueries);
- document.getElementById('error-queries').textContent = formatNumber(errorQueries);
- document.getElementById('active-ips').textContent = formatNumber(activeIPs);
+ // 为数字元素添加平滑过渡效果和光晕效果的函数
+ function animateValue(elementId, newValue) {
+ const element = document.getElementById(elementId);
+ if (!element) return;
+
+ const oldValue = parseInt(element.textContent.replace(/,/g, '')) || 0;
+ const formattedNewValue = formatNumber(newValue);
+
+ // 如果值没有变化,不执行动画
+ if (oldValue === newValue && element.textContent === formattedNewValue) {
+ return;
+ }
+
+ // 添加淡入淡出动画和光晕效果
+ // 先移除可能存在的光晕效果类
+ element.classList.remove('number-glow');
+
+ // 添加淡入淡出动画
+ element.style.opacity = '0';
+ element.style.transition = 'opacity 200ms ease-out';
+
+ setTimeout(() => {
+ element.textContent = formattedNewValue;
+ element.style.opacity = '1';
+
+ // 添加光晕效果
+ // 根据父级卡片类型确定光晕颜色
+ const card = element.closest('.stat-card, .bg-blue-50, .bg-red-50, .bg-green-50, .bg-yellow-50');
+ if (card) {
+ // 设置光晕颜色类
+ if (card.classList.contains('bg-blue-50') || card.id.includes('total')) {
+ element.classList.add('number-glow-blue');
+ } else if (card.classList.contains('bg-red-50') || card.id.includes('blocked')) {
+ element.classList.add('number-glow-red');
+ } else if (card.classList.contains('bg-green-50') || card.id.includes('allowed')) {
+ element.classList.add('number-glow-green');
+ } else if (card.classList.contains('bg-yellow-50') || card.id.includes('error')) {
+ element.classList.add('number-glow-yellow');
+ }
+ } else {
+ // 默认光晕效果
+ element.classList.add('number-glow');
+ }
+
+ // 2秒后移除光晕效果
+ setTimeout(() => {
+ element.classList.remove('number-glow', 'number-glow-blue', 'number-glow-red', 'number-glow-green', 'number-glow-yellow');
+ }, 2000);
+ }, 200);
+ }
- // 更新最常查询类型
- document.getElementById('top-query-type').textContent = topQueryType;
- document.getElementById('query-type-percentage').textContent = `${Math.round(queryTypePercentage)}%`;
+ // 更新百分比元素的函数
+ function updatePercentage(elementId, value) {
+ const element = document.getElementById(elementId);
+ if (!element) return;
+
+ element.style.opacity = '0';
+ element.style.transition = 'opacity 200ms ease-out';
+
+ setTimeout(() => {
+ element.textContent = value;
+ element.style.opacity = '1';
+ }, 200);
+ }
- // 更新活跃来源IP百分比
- document.getElementById('active-ips-percent').textContent = `${Math.round(activeIPsPercentage)}%`;
+ // 平滑更新数量显示
+ animateValue('total-queries', totalQueries);
+ animateValue('blocked-queries', blockedQueries);
+ animateValue('allowed-queries', allowedQueries);
+ animateValue('error-queries', errorQueries);
+ animateValue('active-ips', activeIPs);
- // 计算并更新百分比
+ // 平滑更新文本和百分比
+ updatePercentage('top-query-type', topQueryType);
+ updatePercentage('query-type-percentage', `${Math.round(queryTypePercentage)}%`);
+ updatePercentage('active-ips-percent', `${Math.round(activeIPsPercentage)}%`);
+
+ // 计算并平滑更新百分比
if (totalQueries > 0) {
- document.getElementById('blocked-percent').textContent = `${Math.round((blockedQueries / totalQueries) * 100)}%`;
- document.getElementById('allowed-percent').textContent = `${Math.round((allowedQueries / totalQueries) * 100)}%`;
- document.getElementById('error-percent').textContent = `${Math.round((errorQueries / totalQueries) * 100)}%`;
- document.getElementById('queries-percent').textContent = `100%`;
+ updatePercentage('blocked-percent', `${Math.round((blockedQueries / totalQueries) * 100)}%`);
+ updatePercentage('allowed-percent', `${Math.round((allowedQueries / totalQueries) * 100)}%`);
+ updatePercentage('error-percent', `${Math.round((errorQueries / totalQueries) * 100)}%`);
+ updatePercentage('queries-percent', '100%');
} else {
- document.getElementById('queries-percent').textContent = '---';
- document.getElementById('blocked-percent').textContent = '---';
- document.getElementById('allowed-percent').textContent = '---';
- document.getElementById('error-percent').textContent = '---';
+ updatePercentage('queries-percent', '---');
+ updatePercentage('blocked-percent', '---');
+ updatePercentage('allowed-percent', '---');
+ updatePercentage('error-percent', '---');
}
}