增加更多匹配的域名信息

This commit is contained in:
Alex Yang
2026-01-14 23:08:46 +08:00
parent f247eaeaa8
commit 8159577be0
60 changed files with 11716 additions and 1022 deletions

View File

@@ -162,7 +162,19 @@ function processRealTimeData(stats) {
// 计算响应时间趋势
let responsePercent = '---';
let trendClass = 'text-gray-400';
let trendIcon = '---';
let trendIcon = '';
// 查找箭头元素
const responseTimePercentElem = document.getElementById('response-time-percent');
let parent = null;
let arrowIcon = null;
if (responseTimePercentElem) {
parent = responseTimePercentElem.parentElement;
if (parent) {
arrowIcon = parent.querySelector('.fa-arrow-up, .fa-arrow-down, .fa-circle');
}
}
if (stats.avgResponseTime !== undefined && stats.avgResponseTime !== null) {
// 首次加载时初始化历史数据,不计算趋势
@@ -171,6 +183,10 @@ function processRealTimeData(stats) {
responsePercent = '0.0%';
trendIcon = '•';
trendClass = 'text-gray-500';
if (arrowIcon) {
arrowIcon.className = 'fa fa-circle mr-1 text-xs';
parent.className = 'text-gray-500 text-sm flex items-center';
}
} else {
const prevResponseTime = window.dashboardHistoryData.prevResponseTime;
@@ -178,16 +194,36 @@ function processRealTimeData(stats) {
const changePercent = ((stats.avgResponseTime - prevResponseTime) / prevResponseTime) * 100;
responsePercent = Math.abs(changePercent).toFixed(1) + '%';
// 设置趋势图标和颜色
// 处理-0.0%的情况
if (responsePercent === '-0.0%') {
responsePercent = '0.0%';
}
// 根据用户要求:数量下降显示红色箭头,上升显示绿色箭头
if (changePercent > 0) {
trendIcon = '↓';
trendClass = 'text-danger';
} else if (changePercent < 0) {
// 响应时间增加,数值上升
trendIcon = '↑';
trendClass = 'text-success';
if (arrowIcon) {
arrowIcon.className = 'fa fa-arrow-up mr-1';
parent.className = 'text-success text-sm flex items-center';
}
} else if (changePercent < 0) {
// 响应时间减少,数值下降
trendIcon = '↓';
trendClass = 'text-danger';
if (arrowIcon) {
arrowIcon.className = 'fa fa-arrow-down mr-1';
parent.className = 'text-danger text-sm flex items-center';
}
} else {
// 趋势为0时显示圆点图标
trendIcon = '•';
trendClass = 'text-gray-500';
if (arrowIcon) {
arrowIcon.className = 'fa fa-circle mr-1 text-xs';
parent.className = 'text-gray-500 text-sm flex items-center';
}
}
// 更新历史数据
@@ -196,7 +232,6 @@ function processRealTimeData(stats) {
}
document.getElementById('avg-response-time').textContent = responseTime;
const responseTimePercentElem = document.getElementById('response-time-percent');
if (responseTimePercentElem) {
responseTimePercentElem.textContent = trendIcon + ' ' + responsePercent;
responseTimePercentElem.className = `text-sm flex items-center ${trendClass}`;
@@ -227,7 +262,19 @@ function processRealTimeData(stats) {
// 计算活跃IP趋势
let ipsPercent = '---';
let trendClass = 'text-gray-400';
let trendIcon = '---';
let trendIcon = '';
// 查找箭头元素
const activeIpsPercentElem = document.getElementById('active-ips-percent');
let parent = null;
let arrowIcon = null;
if (activeIpsPercentElem) {
parent = activeIpsPercentElem.parentElement;
if (parent) {
arrowIcon = parent.querySelector('.fa-arrow-up, .fa-arrow-down, .fa-circle');
}
}
if (stats.activeIPs !== undefined) {
const prevActiveIPs = window.dashboardHistoryData.prevActiveIPs;
@@ -238,20 +285,43 @@ function processRealTimeData(stats) {
ipsPercent = '0.0%';
trendIcon = '•';
trendClass = 'text-gray-500';
if (arrowIcon) {
arrowIcon.className = 'fa fa-circle mr-1 text-xs';
parent.className = 'text-gray-500 text-sm flex items-center';
}
} else {
if (prevActiveIPs > 0) {
const changePercent = ((stats.activeIPs - prevActiveIPs) / prevActiveIPs) * 100;
ipsPercent = Math.abs(changePercent).toFixed(1) + '%';
// 处理-0.0%的情况
if (ipsPercent === '-0.0%') {
ipsPercent = '0.0%';
}
// 根据用户要求:数量下降显示红色箭头,上升显示绿色箭头
if (changePercent > 0) {
trendIcon = '↑';
trendClass = 'text-primary';
trendClass = 'text-success';
if (arrowIcon) {
arrowIcon.className = 'fa fa-arrow-up mr-1';
parent.className = 'text-success text-sm flex items-center';
}
} else if (changePercent < 0) {
trendIcon = '↓';
trendClass = 'text-secondary';
trendClass = 'text-danger';
if (arrowIcon) {
arrowIcon.className = 'fa fa-arrow-down mr-1';
parent.className = 'text-danger text-sm flex items-center';
}
} else {
// 趋势为0时显示圆点图标
trendIcon = '•';
trendClass = 'text-gray-500';
if (arrowIcon) {
arrowIcon.className = 'fa fa-circle mr-1 text-xs';
parent.className = 'text-gray-500 text-sm flex items-center';
}
}
}
@@ -261,7 +331,6 @@ function processRealTimeData(stats) {
}
document.getElementById('active-ips').textContent = activeIPs;
const activeIpsPercentElem = document.getElementById('active-ips-percentage');
if (activeIpsPercentElem) {
activeIpsPercentElem.textContent = trendIcon + ' ' + ipsPercent;
activeIpsPercentElem.className = `text-sm flex items-center ${trendClass}`;
@@ -627,7 +696,19 @@ async function loadDashboardData() {
// 计算响应时间趋势
let responsePercent = '---';
let trendClass = 'text-gray-400';
let trendIcon = '---';
let trendIcon = '';
// 查找箭头元素
const responseTimePercentElem = document.getElementById('response-time-percent');
let parent = null;
let arrowIcon = null;
if (responseTimePercentElem) {
parent = responseTimePercentElem.parentElement;
if (parent) {
arrowIcon = parent.querySelector('.fa-arrow-up, .fa-arrow-down, .fa-circle');
}
}
if (stats.avgResponseTime !== undefined && stats.avgResponseTime !== null) {
// 首次加载时初始化历史数据,不计算趋势
@@ -636,6 +717,10 @@ async function loadDashboardData() {
responsePercent = '0.0%';
trendIcon = '•';
trendClass = 'text-gray-500';
if (arrowIcon) {
arrowIcon.className = 'fa fa-circle mr-1 text-xs';
parent.className = 'text-gray-500 text-sm flex items-center';
}
} else {
const prevResponseTime = window.dashboardHistoryData.prevResponseTime;
@@ -644,16 +729,38 @@ async function loadDashboardData() {
const changePercent = ((stats.avgResponseTime - prevResponseTime) / prevResponseTime) * 100;
responsePercent = Math.abs(changePercent).toFixed(1) + '%';
// 设置趋势图标和颜色(响应时间增加是负面的,减少是正面的)
// 处理-0.0%的情况
if (responsePercent === '-0.0%') {
responsePercent = '0.0%';
}
// 根据用户要求:数量下降显示红色箭头,上升显示绿色箭头
// 对于响应时间,数值增加表示性能下降,数值减少表示性能提升
// 但根据用户要求,我们只根据数值变化方向来设置颜色
if (changePercent > 0) {
trendIcon = '↓';
trendClass = 'text-danger';
} else if (changePercent < 0) {
// 响应时间增加(性能下降),数值上升
trendIcon = '↑';
trendClass = 'text-success';
if (arrowIcon) {
arrowIcon.className = 'fa fa-arrow-up mr-1';
parent.className = 'text-success text-sm flex items-center';
}
} else if (changePercent < 0) {
// 响应时间减少(性能提升),数值下降
trendIcon = '↓';
trendClass = 'text-danger';
if (arrowIcon) {
arrowIcon.className = 'fa fa-arrow-down mr-1';
parent.className = 'text-danger text-sm flex items-center';
}
} else {
// 趋势为0时显示圆点图标
trendIcon = '•';
trendClass = 'text-gray-500';
if (arrowIcon) {
arrowIcon.className = 'fa fa-circle mr-1 text-xs';
parent.className = 'text-gray-500 text-sm flex items-center';
}
}
}
@@ -663,7 +770,6 @@ async function loadDashboardData() {
}
document.getElementById('avg-response-time').textContent = responseTime;
const responseTimePercentElem = document.getElementById('response-time-percent');
if (responseTimePercentElem) {
responseTimePercentElem.textContent = trendIcon + ' ' + responsePercent;
responseTimePercentElem.className = `text-sm flex items-center ${trendClass}`;
@@ -697,7 +803,19 @@ async function loadDashboardData() {
// 计算活跃IP趋势
let ipsPercent = '---';
let trendClass = 'text-gray-400';
let trendIcon = '---';
let trendIcon = '';
// 查找箭头元素
const activeIpsPercentElem = document.getElementById('active-ips-percent');
let parent = null;
let arrowIcon = null;
if (activeIpsPercentElem) {
parent = activeIpsPercentElem.parentElement;
if (parent) {
arrowIcon = parent.querySelector('.fa-arrow-up, .fa-arrow-down');
}
}
if (stats.activeIPs !== undefined && stats.activeIPs !== null) {
// 存储当前值用于下次计算趋势
@@ -713,9 +831,21 @@ async function loadDashboardData() {
if (changePercent > 0) {
trendIcon = '↑';
trendClass = 'text-success';
// 更新箭头图标和颜色
if (arrowIcon) {
arrowIcon.className = 'fa fa-arrow-up mr-1';
parent.className = 'text-success text-sm flex items-center';
}
} else if (changePercent < 0) {
trendIcon = '↓';
trendClass = 'text-danger';
// 更新箭头图标和颜色
if (arrowIcon) {
arrowIcon.className = 'fa fa-arrow-down mr-1';
parent.className = 'text-danger text-sm flex items-center';
}
} else {
trendIcon = '•';
trendClass = 'text-gray-500';
@@ -724,7 +854,6 @@ async function loadDashboardData() {
}
document.getElementById('active-ips').textContent = activeIPs;
const activeIpsPercentElem = document.getElementById('active-ips-percent');
if (activeIpsPercentElem) {
activeIpsPercentElem.textContent = trendIcon + ' ' + ipsPercent;
activeIpsPercentElem.className = `text-sm flex items-center ${trendClass}`;
@@ -768,29 +897,51 @@ function updateStatsCards(stats) {
console.log('更新统计卡片,收到数据:', stats);
// 适配不同的数据结构
let totalQueries = 0, blockedQueries = 0, allowedQueries = 0, errorQueries = 0;
// 保存当前显示的值,用于在数据缺失时保留
let totalQueries, blockedQueries, allowedQueries, errorQueries;
let topQueryType = 'A', queryTypePercentage = 0;
let activeIPs = 0, activeIPsPercentage = 0;
let activeIPs, activeIPsPercentage = 0;
// 优先从DOM中获取当前显示的值作为默认值
const totalQueriesElem = document.getElementById('total-queries');
const blockedQueriesElem = document.getElementById('blocked-queries');
const allowedQueriesElem = document.getElementById('allowed-queries');
const errorQueriesElem = document.getElementById('error-queries');
const activeIPsElem = document.getElementById('active-ips');
// 解析当前显示的值,作为默认值
const getCurrentValue = (elem) => {
if (!elem) return 0;
const text = elem.textContent.replace(/,/g, '').replace(/[^0-9]/g, '');
return parseInt(text) || 0;
};
// 初始化默认值为当前显示的值
totalQueries = getCurrentValue(totalQueriesElem);
blockedQueries = getCurrentValue(blockedQueriesElem);
allowedQueries = getCurrentValue(allowedQueriesElem);
errorQueries = getCurrentValue(errorQueriesElem);
activeIPs = getCurrentValue(activeIPsElem);
// 检查数据结构,兼容可能的不同格式
if (stats) {
// 优先使用顶层字段
totalQueries = stats.totalQueries || 0;
blockedQueries = stats.blockedQueries || 0;
allowedQueries = stats.allowedQueries || 0;
errorQueries = stats.errorQueries || 0;
topQueryType = stats.topQueryType || 'A';
queryTypePercentage = stats.queryTypePercentage || 0;
activeIPs = stats.activeIPs || 0;
activeIPsPercentage = stats.activeIPsPercentage || 0;
// 优先使用顶层字段,只有当值存在时才更新
if (stats.totalQueries !== undefined) totalQueries = stats.totalQueries;
if (stats.blockedQueries !== undefined) blockedQueries = stats.blockedQueries;
if (stats.allowedQueries !== undefined) allowedQueries = stats.allowedQueries;
if (stats.errorQueries !== undefined) errorQueries = stats.errorQueries;
if (stats.topQueryType !== undefined) topQueryType = stats.topQueryType;
if (stats.queryTypePercentage !== undefined) queryTypePercentage = stats.queryTypePercentage;
if (stats.activeIPs !== undefined) activeIPs = stats.activeIPs;
if (stats.activeIPsPercentage !== undefined) activeIPsPercentage = stats.activeIPsPercentage;
// 如果dns对象存在优先使用其中的数据
if (stats.dns) {
totalQueries = stats.dns.Queries || totalQueries;
blockedQueries = stats.dns.Blocked || blockedQueries;
allowedQueries = stats.dns.Allowed || allowedQueries;
errorQueries = stats.dns.Errors || errorQueries;
if (stats.dns.Queries !== undefined) totalQueries = stats.dns.Queries;
if (stats.dns.Blocked !== undefined) blockedQueries = stats.dns.Blocked;
if (stats.dns.Allowed !== undefined) allowedQueries = stats.dns.Allowed;
if (stats.dns.Errors !== undefined) errorQueries = stats.dns.Errors;
// 计算最常用查询类型的百分比
if (stats.dns.QueryTypes && stats.dns.Queries > 0) {
@@ -805,14 +956,14 @@ function updateStatsCards(stats) {
}
} else if (Array.isArray(stats) && stats.length > 0) {
// 可能的数据结构3: 数组形式
totalQueries = stats[0].total || 0;
blockedQueries = stats[0].blocked || 0;
allowedQueries = stats[0].allowed || 0;
errorQueries = stats[0].error || 0;
topQueryType = stats[0].topQueryType || 'A';
queryTypePercentage = stats[0].queryTypePercentage || 0;
activeIPs = stats[0].activeIPs || 0;
activeIPsPercentage = stats[0].activeIPsPercentage || 0;
if (stats[0].total !== undefined) totalQueries = stats[0].total;
if (stats[0].blocked !== undefined) blockedQueries = stats[0].blocked;
if (stats[0].allowed !== undefined) allowedQueries = stats[0].allowed;
if (stats[0].error !== undefined) errorQueries = stats[0].error;
if (stats[0].topQueryType !== undefined) topQueryType = stats[0].topQueryType;
if (stats[0].queryTypePercentage !== undefined) queryTypePercentage = stats[0].queryTypePercentage;
if (stats[0].activeIPs !== undefined) activeIPs = stats[0].activeIPs;
if (stats[0].activeIPsPercentage !== undefined) activeIPsPercentage = stats[0].activeIPsPercentage;
}
// 存储正在进行的动画状态,避免动画重叠
@@ -1040,23 +1191,33 @@ function updateStatsCards(stats) {
animateValue('active-ips', activeIPs);
// DNSSEC相关数据
let dnssecEnabled = false, dnssecQueries = 0, dnssecSuccess = 0, dnssecFailed = 0, dnssecUsage = 0;
// 优先从DOM中获取当前显示的值作为默认值
const dnssecSuccessElem = document.getElementById('dnssec-success');
const dnssecFailedElem = document.getElementById('dnssec-failed');
const dnssecQueriesElem = document.getElementById('dnssec-queries');
// 从当前显示值初始化,确保数据刷新前保留前一次结果
let dnssecEnabled = false;
let dnssecQueries = getCurrentValue(dnssecQueriesElem);
let dnssecSuccess = getCurrentValue(dnssecSuccessElem);
let dnssecFailed = getCurrentValue(dnssecFailedElem);
let dnssecUsage = 0;
// 检查DNSSEC数据
if (stats) {
// 优先使用顶层字段
dnssecEnabled = stats.dnssecEnabled || false;
dnssecQueries = stats.dnssecQueries || 0;
dnssecSuccess = stats.dnssecSuccess || 0;
dnssecFailed = stats.dnssecFailed || 0;
dnssecUsage = stats.dnssecUsage || 0;
// 优先使用顶层字段,只有当值存在时才更新
if (stats.dnssecEnabled !== undefined) dnssecEnabled = stats.dnssecEnabled;
if (stats.dnssecQueries !== undefined) dnssecQueries = stats.dnssecQueries;
if (stats.dnssecSuccess !== undefined) dnssecSuccess = stats.dnssecSuccess;
if (stats.dnssecFailed !== undefined) dnssecFailed = stats.dnssecFailed;
if (stats.dnssecUsage !== undefined) dnssecUsage = stats.dnssecUsage;
// 如果dns对象存在优先使用其中的数据
if (stats.dns) {
dnssecEnabled = stats.dns.DNSSECEnabled || dnssecEnabled;
dnssecQueries = stats.dns.DNSSECQueries || dnssecQueries;
dnssecSuccess = stats.dns.DNSSECSuccess || dnssecSuccess;
dnssecFailed = stats.dns.DNSSECFailed || dnssecFailed;
if (stats.dns.DNSSECEnabled !== undefined) dnssecEnabled = stats.dns.DNSSECEnabled;
if (stats.dns.DNSSECQueries !== undefined) dnssecQueries = stats.dns.DNSSECQueries;
if (stats.dns.DNSSECSuccess !== undefined) dnssecSuccess = stats.dns.DNSSECSuccess;
if (stats.dns.DNSSECFailed !== undefined) dnssecFailed = stats.dns.DNSSECFailed;
}
// 如果没有直接提供使用率,计算使用率
@@ -1102,12 +1263,66 @@ function updateStatsCards(stats) {
if (queryTypePercentageElement) queryTypePercentageElement.textContent = `${Math.round(queryTypePercentage)}%`;
if (activeIpsPercentElement) activeIpsPercentElement.textContent = `${Math.round(activeIPsPercentage)}%`;
// 计算并平滑更新百分比
// 计算并平滑更新百分比,同时更新箭头颜色和方向
function updatePercentWithArrow(elementId, percentage, prevValue, currentValue) {
const element = document.getElementById(elementId);
if (!element) return;
// 更新百分比数值
updatePercentage(elementId, percentage);
// 查找父元素,获取箭头图标
const parent = element.parentElement;
if (!parent) return;
let arrowIcon = parent.querySelector('.fa-arrow-up, .fa-arrow-down, .fa-circle');
if (!arrowIcon) return;
// 计算变化趋势
let isIncrease = currentValue > prevValue;
let isDecrease = currentValue < prevValue;
let isNoChange = currentValue === prevValue;
// 处理百分比显示,避免-0.0%的情况
let formattedPercentage = percentage;
if (percentage === '-0.0%') {
formattedPercentage = '0.0%';
updatePercentage(elementId, formattedPercentage);
}
// 更新箭头图标和颜色
if (isIncrease) {
arrowIcon.className = 'fa fa-arrow-up mr-1';
parent.className = 'text-success text-sm flex items-center';
} else if (isDecrease) {
arrowIcon.className = 'fa fa-arrow-down mr-1';
parent.className = 'text-danger text-sm flex items-center';
} else if (isNoChange) {
// 趋势为0时显示圆点图标
arrowIcon.className = 'fa fa-circle mr-1 text-xs';
parent.className = 'text-gray-500 text-sm flex items-center';
}
}
// 保存历史数据,用于计算趋势
window.dashboardHistoryData = window.dashboardHistoryData || {
totalQueries: 0,
blockedQueries: 0,
allowedQueries: 0,
errorQueries: 0
};
// 计算百分比并更新箭头
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%');
const queriesPercent = '100%';
const blockedPercent = `${Math.round((blockedQueries / totalQueries) * 100)}%`;
const allowedPercent = `${Math.round((allowedQueries / totalQueries) * 100)}%`;
const errorPercent = `${Math.round((errorQueries / totalQueries) * 100)}%`;
updatePercentWithArrow('queries-percent', queriesPercent, window.dashboardHistoryData.totalQueries, totalQueries);
updatePercentWithArrow('blocked-percent', blockedPercent, window.dashboardHistoryData.blockedQueries, blockedQueries);
updatePercentWithArrow('allowed-percent', allowedPercent, window.dashboardHistoryData.allowedQueries, allowedQueries);
updatePercentWithArrow('error-percent', errorPercent, window.dashboardHistoryData.errorQueries, errorQueries);
} else {
updatePercentage('queries-percent', '---');
updatePercentage('blocked-percent', '---');
@@ -1115,6 +1330,12 @@ function updateStatsCards(stats) {
updatePercentage('error-percent', '---');
}
// 更新历史数据
window.dashboardHistoryData.totalQueries = totalQueries;
window.dashboardHistoryData.blockedQueries = blockedQueries;
window.dashboardHistoryData.allowedQueries = allowedQueries;
window.dashboardHistoryData.errorQueries = errorQueries;
}