优化修复

This commit is contained in:
Alex Yang
2026-01-02 02:43:10 +08:00
parent 2524336bab
commit 8889c875a9
14 changed files with 2335 additions and 51009 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -165,12 +165,16 @@ function processRealTimeData(stats) {
let trendIcon = '---';
if (stats.avgResponseTime !== undefined && stats.avgResponseTime !== null) {
// 存储当前值用于下次计算趋势
const prevResponseTime = window.dashboardHistoryData.prevResponseTime || stats.avgResponseTime;
window.dashboardHistoryData.prevResponseTime = stats.avgResponseTime;
const prevResponseTime = window.dashboardHistoryData.prevResponseTime;
// 计算变化百分比
if (prevResponseTime > 0) {
// 首次加载时初始化历史数据,不计算趋势
if (prevResponseTime === null) {
window.dashboardHistoryData.prevResponseTime = stats.avgResponseTime;
responsePercent = '0.0%';
trendIcon = '•';
trendClass = 'text-gray-500';
} else {
// 计算变化百分比
const changePercent = ((stats.avgResponseTime - prevResponseTime) / prevResponseTime) * 100;
responsePercent = Math.abs(changePercent).toFixed(1) + '%';
@@ -185,6 +189,9 @@ function processRealTimeData(stats) {
trendIcon = '•';
trendClass = 'text-gray-500';
}
// 更新历史数据
window.dashboardHistoryData.prevResponseTime = stats.avgResponseTime;
}
}
@@ -208,26 +215,35 @@ function processRealTimeData(stats) {
let trendIcon = '---';
if (stats.topQueryTypeCount !== undefined && stats.topQueryTypeCount !== null) {
// 存储当前值用于下次计算趋势
const prevTopQueryTypeCount = window.dashboardHistoryData.prevTopQueryTypeCount || stats.topQueryTypeCount;
window.dashboardHistoryData.prevTopQueryTypeCount = stats.topQueryTypeCount;
const prevTopQueryTypeCount = window.dashboardHistoryData.prevTopQueryTypeCount;
// 计算变化百分比
if (prevTopQueryTypeCount > 0) {
const changePercent = ((stats.topQueryTypeCount - prevTopQueryTypeCount) / prevTopQueryTypeCount) * 100;
queryPercent = Math.abs(changePercent).toFixed(1) + '%';
// 设置趋势图标和颜色
if (changePercent > 0) {
trendIcon = '↑';
trendClass = 'text-primary';
} else if (changePercent < 0) {
trendIcon = '';
trendClass = 'text-secondary';
} else {
trendIcon = '•';
trendClass = 'text-gray-500';
// 首次加载时初始化历史数据,不计算趋势
if (prevTopQueryTypeCount === null) {
window.dashboardHistoryData.prevTopQueryTypeCount = stats.topQueryTypeCount;
queryPercent = '0.0%';
trendIcon = '•';
trendClass = 'text-gray-500';
} else {
// 计算变化百分比
if (prevTopQueryTypeCount > 0) {
const changePercent = ((stats.topQueryTypeCount - prevTopQueryTypeCount) / prevTopQueryTypeCount) * 100;
queryPercent = Math.abs(changePercent).toFixed(1) + '%';
// 设置趋势图标和颜色
if (changePercent > 0) {
trendIcon = '';
trendClass = 'text-primary';
} else if (changePercent < 0) {
trendIcon = '↓';
trendClass = 'text-secondary';
} else {
trendIcon = '•';
trendClass = 'text-gray-500';
}
}
// 更新历史数据
window.dashboardHistoryData.prevTopQueryTypeCount = stats.topQueryTypeCount;
}
}
@@ -245,23 +261,33 @@ function processRealTimeData(stats) {
let trendIcon = '---';
if (stats.activeIPs !== undefined) {
const prevActiveIPs = window.dashboardHistoryData.prevActiveIPs || stats.activeIPs;
window.dashboardHistoryData.prevActiveIPs = stats.activeIPs;
const prevActiveIPs = window.dashboardHistoryData.prevActiveIPs;
if (prevActiveIPs > 0) {
const changePercent = ((stats.activeIPs - prevActiveIPs) / prevActiveIPs) * 100;
ipsPercent = Math.abs(changePercent).toFixed(1) + '%';
if (changePercent > 0) {
trendIcon = '';
trendClass = 'text-primary';
} else if (changePercent < 0) {
trendIcon = '↓';
trendClass = 'text-secondary';
} else {
trendIcon = '•';
trendClass = 'text-gray-500';
// 首次加载时初始化历史数据,不计算趋势
if (prevActiveIPs === null) {
window.dashboardHistoryData.prevActiveIPs = stats.activeIPs;
ipsPercent = '0.0%';
trendIcon = '•';
trendClass = 'text-gray-500';
} else {
if (prevActiveIPs > 0) {
const changePercent = ((stats.activeIPs - prevActiveIPs) / prevActiveIPs) * 100;
ipsPercent = Math.abs(changePercent).toFixed(1) + '%';
if (changePercent > 0) {
trendIcon = '';
trendClass = 'text-primary';
} else if (changePercent < 0) {
trendIcon = '↓';
trendClass = 'text-secondary';
} else {
trendIcon = '•';
trendClass = 'text-gray-500';
}
}
// 更新历史数据
window.dashboardHistoryData.prevActiveIPs = stats.activeIPs;
}
}

View File

@@ -275,17 +275,22 @@ async function getDomainInfo(domain) {
function isDomainMatch(urlValue, targetDomain, categoryId) {
console.log(' 开始匹配URL:', urlValue, '目标域名:', targetDomain, '类别ID:', categoryId);
// 规范化目标域名,去除末尾的点
const normalizedTargetDomain = targetDomain.replace(/\.$/, '').toLowerCase();
try {
// 尝试将URL值解析为完整URL
console.log(' 尝试解析URL为完整URL');
const url = new URL(urlValue);
const hostname = url.hostname.toLowerCase();
console.log(' 解析成功,主机名:', hostname);
let hostname = url.hostname.toLowerCase();
// 规范化主机名,去除末尾的点
hostname = hostname.replace(/\.$/, '');
console.log(' 解析成功,主机名:', hostname, '规范化目标域名:', normalizedTargetDomain);
// 根据类别ID选择匹配方式
if (categoryId === 2) {
// CDN类别使用域名后缀匹配
if (targetDomain.endsWith('.' + hostname) || targetDomain === hostname) {
if (normalizedTargetDomain.endsWith('.' + hostname) || normalizedTargetDomain === hostname) {
console.log(' CDN域名后缀匹配成功');
return true;
} else {
@@ -294,7 +299,7 @@ function isDomainMatch(urlValue, targetDomain, categoryId) {
}
} else {
// 其他类别,使用完整域名匹配
if (hostname === targetDomain) {
if (hostname === normalizedTargetDomain) {
console.log(' 完整域名匹配成功');
return true;
} else {
@@ -305,13 +310,15 @@ function isDomainMatch(urlValue, targetDomain, categoryId) {
} catch (e) {
console.log(' 解析URL失败将其视为纯域名处理错误信息:', e.message);
// 如果是纯域名而不是完整URL
const urlDomain = urlValue.toLowerCase();
console.log(' 处理为纯域名:', urlDomain);
let urlDomain = urlValue.toLowerCase();
// 规范化纯域名,去除末尾的点
urlDomain = urlDomain.replace(/\.$/, '');
console.log(' 处理为纯域名:', urlDomain, '规范化目标域名:', normalizedTargetDomain);
// 根据类别ID选择匹配方式
if (categoryId === 2) {
// CDN类别使用域名后缀匹配
if (targetDomain.endsWith('.' + urlDomain) || targetDomain === urlDomain) {
if (normalizedTargetDomain.endsWith('.' + urlDomain) || normalizedTargetDomain === urlDomain) {
console.log(' CDN域名后缀匹配成功');
return true;
} else {
@@ -320,7 +327,7 @@ function isDomainMatch(urlValue, targetDomain, categoryId) {
}
} else {
// 其他类别,使用完整域名匹配
if (urlDomain === targetDomain) {
if (urlDomain === normalizedTargetDomain) {
console.log(' 完整域名匹配成功');
return true;
} else {
@@ -1485,20 +1492,20 @@ async function showLogDetailModal(log) {
domainInfoDiv.className = 'col-span-1 md:col-span-2 space-y-1';
domainInfoDiv.innerHTML = `
<div class="text-xs text-gray-500">域名信息</div>
<div class="text-sm font-medium text-gray-900 p-3 bg-gray-50 rounded-md border border-gray-200">
<div class="text-sm font-medium text-gray-900 p-3 bg-gray-50 rounded-md border border-gray-200 w-full">
${domainInfo ? `
<div class="flex items-center mb-2">
${domainInfo.icon ? `<img src="${domainInfo.icon}" alt="${domainInfo.name}" class="w-6 h-6 mr-2 rounded-sm" onerror="this.style.display='none'" />` : ''}
<span class="text-base font-semibold">${domainInfo.name || '未知'}</span>
<span class="text-base font-semibold flex-grow">${domainInfo.name || '未知'}</span>
</div>
<div class="ml-8 mt-1">
<div class="flex items-center mb-1">
<span class="text-gray-500 w-16">类别:</span>
<span>${domainInfo.categoryName || '未知'}</span>
<div class="mt-1">
<div class="flex items-center mb-1 flex-wrap">
<span class="text-gray-500 mr-2">类别</span>
<span class="flex-grow">${domainInfo.categoryName || '未知'}</span>
</div>
<div class="flex items-center">
<span class="text-gray-500 w-16">所属公司:</span>
<span>${domainInfo.company || '未知'}</span>
<div class="flex items-center flex-wrap">
<span class="text-gray-500 mr-2">所属单位:</span>
<span class="flex-grow">${domainInfo.company || '未知'}</span>
</div>
</div>
` : '无'}
@@ -1615,16 +1622,59 @@ async function showLogDetailModal(log) {
clientDetails.appendChild(clientDetailsTitle);
clientDetails.appendChild(clientIPDiv);
// 操作按钮区域
const actionButtons = document.createElement('div');
actionButtons.className = 'pt-4 border-t border-gray-200 flex justify-end space-x-2';
// 根据域名状态显示不同的操作按钮
if (result === 'blocked') {
// 被拦截时显示放行按钮
actionButtons.innerHTML = `
<button class="px-4 py-2 bg-green-500 text-white rounded-md hover:bg-green-600 transition-colors text-sm" id="unblock-domain-btn">
<i class="fa fa-unlock-alt mr-1"></i>放行
</button>
`;
} else {
// 未被拦截时显示拦截按钮
actionButtons.innerHTML = `
<button class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 transition-colors text-sm" id="block-domain-btn">
<i class="fa fa-lock mr-1"></i>拦截
</button>
`;
}
// 组装内容
content.appendChild(basicInfo);
content.appendChild(responseDetails);
content.appendChild(clientDetails);
content.appendChild(actionButtons);
// 组装模态框
modalContent.appendChild(header);
modalContent.appendChild(content);
modalContainer.appendChild(modalContent);
// 绑定操作按钮事件
if (result === 'blocked') {
const unblockBtn = modalContent.querySelector('#unblock-domain-btn');
if (unblockBtn) {
unblockBtn.addEventListener('click', async () => {
await unblockDomain(domain);
closeModal();
loadLogs(); // 刷新日志列表
});
}
} else {
const blockBtn = modalContent.querySelector('#block-domain-btn');
if (blockBtn) {
blockBtn.addEventListener('click', async () => {
await blockDomain(domain);
closeModal();
loadLogs(); // 刷新日志列表
});
}
}
// 添加到页面
document.body.appendChild(modalContainer);