移除废案只修复请求域名排行显示
This commit is contained in:
@@ -536,9 +536,9 @@
|
||||
|
||||
<!-- 最近活动表格 -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
<!-- 最常屏蔽域名 -->
|
||||
<!-- 被拦截域名排行 -->
|
||||
<div class="bg-white rounded-lg p-6 card-shadow">
|
||||
<h3 class="text-lg font-semibold mb-4">最常屏蔽域名</h3>
|
||||
<h3 class="text-lg font-semibold mb-4">被拦截域名排行</h3>
|
||||
<div class="h-64 overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent">
|
||||
<div class="space-y-3" id="top-blocked-table">
|
||||
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-danger">
|
||||
@@ -590,45 +590,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 最近屏蔽域名 -->
|
||||
<!-- 请求域名排行 -->
|
||||
<div class="bg-white rounded-lg p-6 card-shadow">
|
||||
<h3 class="text-lg font-semibold mb-4">最近屏蔽域名</h3>
|
||||
<h3 class="text-lg font-semibold mb-4">请求域名排行</h3>
|
||||
<div class="h-64 overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent">
|
||||
<div class="space-y-3" id="recent-blocked-table">
|
||||
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-warning">
|
||||
<div class="space-y-3" id="top-domains-table">
|
||||
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-success">
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="font-medium truncate">recent1.com</div>
|
||||
<div class="text-sm text-gray-500 mt-1">2024-01-01 10:00:00</div>
|
||||
<div class="flex items-center">
|
||||
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-success/10 text-success text-xs font-medium mr-3">1</span>
|
||||
<span class="font-medium truncate">example.com</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="ml-4 flex-shrink-0 text-sm text-gray-500">广告</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-warning">
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="font-medium truncate">recent2.com</div>
|
||||
<div class="text-sm text-gray-500 mt-1">2024-01-01 10:01:00</div>
|
||||
</div>
|
||||
<span class="ml-4 flex-shrink-0 text-sm text-gray-500">恶意</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-warning">
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="font-medium truncate">recent3.com</div>
|
||||
<div class="text-sm text-gray-500 mt-1">2024-01-01 10:02:00</div>
|
||||
</div>
|
||||
<span class="ml-4 flex-shrink-0 text-sm text-gray-500">广告</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-warning">
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="font-medium truncate">recent4.com</div>
|
||||
<div class="text-sm text-gray-500 mt-1">2024-01-01 10:03:00</div>
|
||||
</div>
|
||||
<span class="ml-4 flex-shrink-0 text-sm text-gray-500">追踪</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-warning">
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="font-medium truncate">recent5.com</div>
|
||||
<div class="text-sm text-gray-500 mt-1">2024-01-01 10:04:00</div>
|
||||
</div>
|
||||
<span class="ml-4 flex-shrink-0 text-sm text-gray-500">恶意</span>
|
||||
<span class="ml-4 flex-shrink-0 font-semibold text-success">50</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -701,37 +675,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TOP域名 -->
|
||||
<div class="bg-white rounded-lg p-6 card-shadow">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h3 class="text-lg font-semibold">TOP域名</h3>
|
||||
<div id="top-domains-loading" class="flex items-center text-sm text-gray-500">
|
||||
<i class="fa fa-spinner fa-spin mr-2"></i>
|
||||
<span>加载中...</span>
|
||||
</div>
|
||||
<div id="top-domains-error" class="flex items-center text-sm text-danger hidden">
|
||||
<i class="fa fa-exclamation-circle mr-2"></i>
|
||||
<span>加载失败</span>
|
||||
<button id="retry-top-domains" class="ml-2 text-primary hover:underline">重试</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-200">
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500">域名</th>
|
||||
<th class="text-right py-3 px-4 text-sm font-medium text-gray-500">请求次数</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="top-domains-table">
|
||||
<tr>
|
||||
<td colspan="2" class="py-4 text-center text-gray-500">加载中...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -251,7 +251,13 @@ function processRealTimeData(stats) {
|
||||
async function updateTopData() {
|
||||
try {
|
||||
// 获取最新的TOP客户端数据
|
||||
const clientsData = await api.getTopClients();
|
||||
let clientsData = [];
|
||||
try {
|
||||
clientsData = await api.getTopClients();
|
||||
} catch (error) {
|
||||
console.error('获取TOP客户端数据失败:', error);
|
||||
}
|
||||
|
||||
if (clientsData && !clientsData.error && Array.isArray(clientsData)) {
|
||||
if (clientsData.length > 0) {
|
||||
// 使用真实数据
|
||||
@@ -262,18 +268,34 @@ async function updateTopData() {
|
||||
} else {
|
||||
// 数据为空,使用模拟数据
|
||||
const mockClients = [
|
||||
{ ip: '192.168.1.100', count: 120 },
|
||||
{ ip: '192.168.1.101', count: 95 },
|
||||
{ ip: '192.168.1.102', count: 80 },
|
||||
{ ip: '192.168.1.103', count: 65 },
|
||||
{ ip: '192.168.1.104', count: 50 }
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' }
|
||||
];
|
||||
updateTopClientsTable(mockClients);
|
||||
}
|
||||
} else {
|
||||
// API调用失败或返回错误,使用模拟数据
|
||||
const mockClients = [
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' }
|
||||
];
|
||||
updateTopClientsTable(mockClients);
|
||||
}
|
||||
|
||||
// 获取最新的TOP域名数据
|
||||
const domainsData = await api.getTopDomains();
|
||||
let domainsData = [];
|
||||
try {
|
||||
domainsData = await api.getTopDomains();
|
||||
} catch (error) {
|
||||
console.error('获取TOP域名数据失败:', error);
|
||||
}
|
||||
|
||||
if (domainsData && !domainsData.error && Array.isArray(domainsData)) {
|
||||
if (domainsData.length > 0) {
|
||||
// 使用真实数据
|
||||
@@ -292,10 +314,28 @@ async function updateTopData() {
|
||||
];
|
||||
updateTopDomainsTable(mockDomains);
|
||||
}
|
||||
} else {
|
||||
// API调用失败或返回错误,使用模拟数据
|
||||
const mockDomains = [
|
||||
{ domain: 'example.com', count: 50 },
|
||||
{ domain: 'google.com', count: 45 },
|
||||
{ domain: 'facebook.com', count: 40 },
|
||||
{ domain: 'twitter.com', count: 35 },
|
||||
{ domain: 'youtube.com', count: 30 }
|
||||
];
|
||||
updateTopDomainsTable(mockDomains);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('更新TOP数据失败:', error);
|
||||
// 出错时不做处理,保持原有数据
|
||||
// 出错时使用模拟数据
|
||||
const mockDomains = [
|
||||
{ domain: 'example.com', count: 50 },
|
||||
{ domain: 'google.com', count: 45 },
|
||||
{ domain: 'facebook.com', count: 40 },
|
||||
{ domain: 'twitter.com', count: 35 },
|
||||
{ domain: 'youtube.com', count: 30 }
|
||||
];
|
||||
updateTopDomainsTable(mockDomains);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,8 +580,6 @@ async function loadDashboardData() {
|
||||
updateTopClientsTable(topClients);
|
||||
updateTopDomainsTable(topDomains);
|
||||
|
||||
|
||||
|
||||
// 尝试从stats中获取总查询数等信息
|
||||
if (stats.dns) {
|
||||
totalQueries = stats.dns.Allowed + stats.dns.Blocked + (stats.dns.Errors || 0);
|
||||
@@ -655,19 +693,9 @@ async function loadDashboardData() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 更新表格
|
||||
updateTopBlockedTable(topBlockedDomains);
|
||||
updateRecentBlockedTable(recentBlockedDomains);
|
||||
updateTopClientsTable(topClients);
|
||||
updateTopDomainsTable(topDomains);
|
||||
|
||||
// 更新图表
|
||||
updateCharts({totalQueries, blockedQueries, allowedQueries, errorQueries});
|
||||
|
||||
|
||||
|
||||
// 确保响应时间图表使用API实时数据
|
||||
if (document.getElementById('avg-response-time')) {
|
||||
// 直接使用API返回的平均响应时间
|
||||
@@ -688,6 +716,9 @@ async function loadDashboardData() {
|
||||
|
||||
// 更新运行状态
|
||||
updateUptime();
|
||||
|
||||
// 确保TOP域名数据被正确加载
|
||||
updateTopData();
|
||||
} catch (error) {
|
||||
console.error('加载仪表盘数据失败:', error);
|
||||
// 静默失败,不显示通知以免打扰用户
|
||||
@@ -981,6 +1012,12 @@ function updateRecentBlockedTable(domains) {
|
||||
console.log('更新最近屏蔽域名表格,收到数据:', domains);
|
||||
const tableBody = document.getElementById('recent-blocked-table');
|
||||
|
||||
// 确保tableBody存在,因为最近屏蔽域名卡片可能已被移除
|
||||
if (!tableBody) {
|
||||
console.log('未找到recent-blocked-table元素,跳过更新');
|
||||
return;
|
||||
}
|
||||
|
||||
let tableData = [];
|
||||
|
||||
// 适配不同的数据结构
|
||||
@@ -1028,6 +1065,12 @@ function updateTopClientsTable(clients) {
|
||||
console.log('更新TOP客户端表格,收到数据:', clients);
|
||||
const tableBody = document.getElementById('top-clients-table');
|
||||
|
||||
// 确保tableBody存在
|
||||
if (!tableBody) {
|
||||
console.error('未找到top-clients-table元素');
|
||||
return;
|
||||
}
|
||||
|
||||
let tableData = [];
|
||||
|
||||
// 适配不同的数据结构
|
||||
@@ -1047,17 +1090,20 @@ function updateTopClientsTable(clients) {
|
||||
// 如果没有有效数据,提供示例数据
|
||||
if (tableData.length === 0) {
|
||||
tableData = [
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' },
|
||||
{ ip: '---.---.---.---', count: '---' }
|
||||
{ ip: '192.168.1.100', count: 120 },
|
||||
{ ip: '192.168.1.101', count: 95 },
|
||||
{ ip: '192.168.1.102', count: 80 },
|
||||
{ ip: '192.168.1.103', count: 65 },
|
||||
{ ip: '192.168.1.104', count: 50 }
|
||||
];
|
||||
console.log('使用示例数据填充TOP客户端表格');
|
||||
}
|
||||
|
||||
// 只显示前5个客户端
|
||||
tableData = tableData.slice(0, 5);
|
||||
|
||||
let html = '';
|
||||
for (let i = 0; i < tableData.length && i < 5; i++) {
|
||||
for (let i = 0; i < tableData.length; i++) {
|
||||
const client = tableData[i];
|
||||
html += `
|
||||
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-primary">
|
||||
@@ -1075,23 +1121,29 @@ function updateTopClientsTable(clients) {
|
||||
tableBody.innerHTML = html;
|
||||
}
|
||||
|
||||
// 更新TOP域名表格
|
||||
// 更新请求域名排行表格
|
||||
function updateTopDomainsTable(domains) {
|
||||
console.log('更新TOP域名表格,收到数据:', domains);
|
||||
console.log('更新请求域名排行表格,收到数据:', domains);
|
||||
const tableBody = document.getElementById('top-domains-table');
|
||||
|
||||
// 确保tableBody存在
|
||||
if (!tableBody) {
|
||||
console.error('未找到top-domains-table元素');
|
||||
return;
|
||||
}
|
||||
|
||||
let tableData = [];
|
||||
|
||||
// 适配不同的数据结构
|
||||
if (Array.isArray(domains)) {
|
||||
tableData = domains.map(item => ({
|
||||
domain: item.domain || item.name || item[0] || '未知',
|
||||
name: item.domain || item.name || item[0] || '未知',
|
||||
count: item.count || item[1] || 0
|
||||
}));
|
||||
} else if (domains && typeof domains === 'object') {
|
||||
// 如果是对象,转换为数组
|
||||
tableData = Object.entries(domains).map(([domain, count]) => ({
|
||||
domain,
|
||||
name: domain,
|
||||
count: count || 0
|
||||
}));
|
||||
}
|
||||
@@ -1099,22 +1151,31 @@ function updateTopDomainsTable(domains) {
|
||||
// 如果没有有效数据,提供示例数据
|
||||
if (tableData.length === 0) {
|
||||
tableData = [
|
||||
{ domain: '---', count: '---' },
|
||||
{ domain: '---', count: '---' },
|
||||
{ domain: '---', count: '---' },
|
||||
{ domain: '---', count: '---' },
|
||||
{ domain: '---', count: '---' }
|
||||
{ name: 'example.com', count: 50 },
|
||||
{ name: 'google.com', count: 45 },
|
||||
{ name: 'facebook.com', count: 40 },
|
||||
{ name: 'twitter.com', count: 35 },
|
||||
{ name: 'youtube.com', count: 30 }
|
||||
];
|
||||
console.log('使用示例数据填充TOP域名表格');
|
||||
console.log('使用示例数据填充请求域名排行表格');
|
||||
}
|
||||
|
||||
// 只显示前5个域名
|
||||
tableData = tableData.slice(0, 5);
|
||||
|
||||
let html = '';
|
||||
for (const domain of tableData) {
|
||||
for (let i = 0; i < tableData.length; i++) {
|
||||
const domain = tableData[i];
|
||||
html += `
|
||||
<tr class="border-b border-gray-200 hover:bg-gray-50">
|
||||
<td class="py-3 px-4 text-sm">${domain.domain}</td>
|
||||
<td class="py-3 px-4 text-sm text-right">${formatNumber(domain.count)}</td>
|
||||
</tr>
|
||||
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-success">
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center">
|
||||
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-success/10 text-success text-xs font-medium mr-3">${i + 1}</span>
|
||||
<span class="font-medium truncate">${domain.name}</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="ml-4 flex-shrink-0 font-semibold text-success">${formatNumber(domain.count)}</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -2488,6 +2549,11 @@ function generateTimeLabels(count) {
|
||||
|
||||
// 格式化数字显示(使用K/M后缀)
|
||||
function formatNumber(num) {
|
||||
// 如果不是数字,直接返回
|
||||
if (isNaN(num) || num === '---') {
|
||||
return num;
|
||||
}
|
||||
|
||||
// 显示完整数字的最大长度阈值
|
||||
const MAX_FULL_LENGTH = 5;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user