页面数据更新优化
This commit is contained in:
@@ -51,6 +51,94 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- 数字光晕效果样式 -->
|
||||||
|
<style>
|
||||||
|
/* 数字光晕效果基础样式 */
|
||||||
|
.number-glow {
|
||||||
|
animation: glow-pulse 2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 蓝色光晕效果 */
|
||||||
|
.number-glow-blue {
|
||||||
|
animation: glow-blue 2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 红色光晕效果 */
|
||||||
|
.number-glow-red {
|
||||||
|
animation: glow-red 2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 绿色光晕效果 */
|
||||||
|
.number-glow-green {
|
||||||
|
animation: glow-green 2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 黄色光晕效果 */
|
||||||
|
.number-glow-yellow {
|
||||||
|
animation: glow-yellow 2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 光晕动画定义 */
|
||||||
|
@keyframes glow-pulse {
|
||||||
|
0% {
|
||||||
|
text-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
text-shadow: 0 0 20px rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
text-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes glow-blue {
|
||||||
|
0% {
|
||||||
|
text-shadow: 0 0 5px rgba(59, 130, 246, 0.3);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
text-shadow: 0 0 20px rgba(59, 130, 246, 0.7);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
text-shadow: 0 0 5px rgba(59, 130, 246, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes glow-red {
|
||||||
|
0% {
|
||||||
|
text-shadow: 0 0 5px rgba(239, 68, 68, 0.3);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
text-shadow: 0 0 20px rgba(239, 68, 68, 0.7);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
text-shadow: 0 0 5px rgba(239, 68, 68, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes glow-green {
|
||||||
|
0% {
|
||||||
|
text-shadow: 0 0 5px rgba(16, 185, 129, 0.3);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
text-shadow: 0 0 20px rgba(16, 185, 129, 0.7);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
text-shadow: 0 0 5px rgba(16, 185, 129, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes glow-yellow {
|
||||||
|
0% {
|
||||||
|
text-shadow: 0 0 5px rgba(250, 204, 21, 0.3);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
text-shadow: 0 0 20px rgba(250, 204, 21, 0.7);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
text-shadow: 0 0 5px rgba(250, 204, 21, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-gray-50 text-dark font-sans">
|
<body class="bg-gray-50 text-dark font-sans">
|
||||||
<div class="flex h-screen overflow-hidden">
|
<div class="flex h-screen overflow-hidden">
|
||||||
@@ -140,7 +228,7 @@
|
|||||||
<!-- 统计卡片 -->
|
<!-- 统计卡片 -->
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||||
<!-- 查询总量卡片 -->
|
<!-- 查询总量卡片 -->
|
||||||
<div class="bg-white rounded-lg p-6 card-shadow relative overflow-hidden">
|
<div class="bg-blue-50 rounded-lg p-6 card-shadow relative overflow-hidden">
|
||||||
<!-- 颜色蒙版 -->
|
<!-- 颜色蒙版 -->
|
||||||
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-primary opacity-10"></div>
|
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-primary opacity-10"></div>
|
||||||
<div class="relative z-10">
|
<div class="relative z-10">
|
||||||
@@ -166,7 +254,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 屏蔽数量卡片 -->
|
<!-- 屏蔽数量卡片 -->
|
||||||
<div class="bg-white rounded-lg p-6 card-shadow relative overflow-hidden">
|
<div class="bg-red-50 rounded-lg p-6 card-shadow relative overflow-hidden">
|
||||||
<!-- 颜色蒙版 -->
|
<!-- 颜色蒙版 -->
|
||||||
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-danger opacity-10"></div>
|
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-danger opacity-10"></div>
|
||||||
<div class="relative z-10">
|
<div class="relative z-10">
|
||||||
@@ -192,7 +280,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 正常解析卡片 -->
|
<!-- 正常解析卡片 -->
|
||||||
<div class="bg-white rounded-lg p-6 card-shadow relative overflow-hidden">
|
<div class="bg-green-50 rounded-lg p-6 card-shadow relative overflow-hidden">
|
||||||
<!-- 颜色蒙版 -->
|
<!-- 颜色蒙版 -->
|
||||||
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-success opacity-10"></div>
|
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-success opacity-10"></div>
|
||||||
<div class="relative z-10">
|
<div class="relative z-10">
|
||||||
@@ -218,7 +306,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 错误数量卡片 -->
|
<!-- 错误数量卡片 -->
|
||||||
<div class="bg-white rounded-lg p-6 card-shadow relative overflow-hidden">
|
<div class="bg-yellow-50 rounded-lg p-6 card-shadow relative overflow-hidden">
|
||||||
<!-- 颜色蒙版 -->
|
<!-- 颜色蒙版 -->
|
||||||
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-warning opacity-10"></div>
|
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-warning opacity-10"></div>
|
||||||
<div class="relative z-10">
|
<div class="relative z-10">
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ const COLOR_CONFIG = window.COLOR_CONFIG || {};
|
|||||||
// 初始化仪表盘
|
// 初始化仪表盘
|
||||||
async function initDashboard() {
|
async function initDashboard() {
|
||||||
try {
|
try {
|
||||||
// 加载初始数据
|
console.log('页面打开时强制刷新数据...');
|
||||||
|
|
||||||
|
// 优先加载初始数据,确保页面显示最新信息
|
||||||
await loadDashboardData();
|
await loadDashboardData();
|
||||||
|
|
||||||
// 初始化图表
|
// 初始化图表
|
||||||
@@ -342,31 +344,94 @@ function updateStatsCards(stats) {
|
|||||||
activeIPsPercentage = stats[0].activeIPsPercentage || 0;
|
activeIPsPercentage = stats[0].activeIPsPercentage || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新数量显示
|
// 为数字元素添加平滑过渡效果和光晕效果的函数
|
||||||
document.getElementById('total-queries').textContent = formatNumber(totalQueries);
|
function animateValue(elementId, newValue) {
|
||||||
document.getElementById('blocked-queries').textContent = formatNumber(blockedQueries);
|
const element = document.getElementById(elementId);
|
||||||
document.getElementById('allowed-queries').textContent = formatNumber(allowedQueries);
|
if (!element) return;
|
||||||
document.getElementById('error-queries').textContent = formatNumber(errorQueries);
|
|
||||||
document.getElementById('active-ips').textContent = formatNumber(activeIPs);
|
|
||||||
|
|
||||||
// 更新最常查询类型
|
const oldValue = parseInt(element.textContent.replace(/,/g, '')) || 0;
|
||||||
document.getElementById('top-query-type').textContent = topQueryType;
|
const formattedNewValue = formatNumber(newValue);
|
||||||
document.getElementById('query-type-percentage').textContent = `${Math.round(queryTypePercentage)}%`;
|
|
||||||
|
|
||||||
// 更新活跃来源IP百分比
|
// 如果值没有变化,不执行动画
|
||||||
document.getElementById('active-ips-percent').textContent = `${Math.round(activeIPsPercentage)}%`;
|
if (oldValue === newValue && element.textContent === formattedNewValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 计算并更新百分比
|
// 添加淡入淡出动画和光晕效果
|
||||||
if (totalQueries > 0) {
|
// 先移除可能存在的光晕效果类
|
||||||
document.getElementById('blocked-percent').textContent = `${Math.round((blockedQueries / totalQueries) * 100)}%`;
|
element.classList.remove('number-glow');
|
||||||
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%`;
|
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 {
|
} else {
|
||||||
document.getElementById('queries-percent').textContent = '---';
|
// 默认光晕效果
|
||||||
document.getElementById('blocked-percent').textContent = '---';
|
element.classList.add('number-glow');
|
||||||
document.getElementById('allowed-percent').textContent = '---';
|
}
|
||||||
document.getElementById('error-percent').textContent = '---';
|
|
||||||
|
// 2秒后移除光晕效果
|
||||||
|
setTimeout(() => {
|
||||||
|
element.classList.remove('number-glow', 'number-glow-blue', 'number-glow-red', 'number-glow-green', 'number-glow-yellow');
|
||||||
|
}, 2000);
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新百分比元素的函数
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 平滑更新数量显示
|
||||||
|
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) {
|
||||||
|
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 {
|
||||||
|
updatePercentage('queries-percent', '---');
|
||||||
|
updatePercentage('blocked-percent', '---');
|
||||||
|
updatePercentage('allowed-percent', '---');
|
||||||
|
updatePercentage('error-percent', '---');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user