web修复
This commit is contained in:
@@ -23,13 +23,59 @@ function loadDashboardData() {
|
||||
function loadHourlyStats() {
|
||||
apiRequest('/api/hourly-stats')
|
||||
.then(data => {
|
||||
if (data && data.labels && data.data) {
|
||||
// 只使用一组数据(假设是屏蔽请求数)
|
||||
renderHourlyChart(data.labels, data.data, []);
|
||||
// 处理不同可能的数据格式
|
||||
if (data) {
|
||||
// 优先处理用户提供的实际数据格式 {data: [], labels: []}
|
||||
if (data.labels && data.data && Array.isArray(data.labels) && Array.isArray(data.data)) {
|
||||
// 确保labels和data数组长度一致
|
||||
if (data.labels.length === data.data.length) {
|
||||
// 假设data数组包含的是屏蔽请求数据,允许请求设为0
|
||||
renderHourlyChart(data.labels, data.data, Array(data.data.length).fill(0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理其他可能的数据格式
|
||||
if (data.labels && data.blocked && data.allowed) {
|
||||
// 完整数据格式:分别有屏蔽和允许的数据
|
||||
renderHourlyChart(data.labels, data.blocked, data.allowed);
|
||||
} else if (data.labels && data.data) {
|
||||
// 简化数据格式:只有一组数据
|
||||
renderHourlyChart(data.labels, data.data, Array(data.data.length).fill(0));
|
||||
} else {
|
||||
// 尝试直接使用数据对象的属性
|
||||
const hours = [];
|
||||
const blocked = [];
|
||||
const allowed = [];
|
||||
|
||||
// 假设数据是按小时组织的对象
|
||||
for (const key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
hours.push(key);
|
||||
// 尝试不同的数据结构访问方式
|
||||
if (typeof data[key] === 'object' && data[key] !== null) {
|
||||
blocked.push(data[key].Blocked || data[key].blocked || 0);
|
||||
allowed.push(data[key].Allowed || data[key].allowed || 0);
|
||||
} else {
|
||||
blocked.push(data[key]);
|
||||
allowed.push(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 只在有数据时渲染
|
||||
if (hours.length > 0) {
|
||||
renderHourlyChart(hours, blocked, allowed);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取24小时统计失败:', error);
|
||||
// 显示默认空数据,避免图表区域空白
|
||||
const emptyHours = Array.from({length: 24}, (_, i) => `${i}:00`);
|
||||
const emptyData = Array(24).fill(0);
|
||||
renderHourlyChart(emptyHours, emptyData, emptyData);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -104,19 +150,45 @@ function renderHourlyChart(hours, blocked, allowed) {
|
||||
function loadRequestsDistribution() {
|
||||
apiRequest('/api/stats')
|
||||
.then(data => {
|
||||
if (data && data.dns) {
|
||||
// 构造饼图所需的数据
|
||||
const labels = ['允许请求', '屏蔽请求', '错误请求'];
|
||||
const requestData = [
|
||||
data.dns.Allowed || 0,
|
||||
data.dns.Blocked || 0,
|
||||
data.dns.Errors || 0
|
||||
];
|
||||
renderRequestsPieChart(labels, requestData);
|
||||
// 构造饼图所需的数据,支持多种数据格式
|
||||
const labels = ['允许请求', '屏蔽请求', '错误请求'];
|
||||
let requestData = [0, 0, 0]; // 默认值
|
||||
|
||||
if (data) {
|
||||
// 尝试多种可能的数据结构
|
||||
if (data.dns) {
|
||||
// 主要数据结构
|
||||
requestData = [
|
||||
data.dns.Allowed || data.dns.allowed || 0,
|
||||
data.dns.Blocked || data.dns.blocked || 0,
|
||||
data.dns.Errors || data.dns.errors || 0
|
||||
];
|
||||
} else if (data.Allowed !== undefined || data.Blocked !== undefined) {
|
||||
// 直接在顶级对象中
|
||||
requestData = [
|
||||
data.Allowed || data.allowed || 0,
|
||||
data.Blocked || data.blocked || 0,
|
||||
data.Errors || data.errors || 0
|
||||
];
|
||||
} else if (data.requests) {
|
||||
// 可能在requests属性中
|
||||
requestData = [
|
||||
data.requests.Allowed || data.requests.allowed || 0,
|
||||
data.requests.Blocked || data.requests.blocked || 0,
|
||||
data.requests.Errors || data.requests.errors || 0
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染图表,即使数据全为0也渲染,避免空白
|
||||
renderRequestsPieChart(labels, requestData);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取请求类型分布失败:', error);
|
||||
// 显示默认空数据的图表
|
||||
const labels = ['允许请求', '屏蔽请求', '错误请求'];
|
||||
const defaultData = [0, 0, 0];
|
||||
renderRequestsPieChart(labels, defaultData);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -173,21 +245,53 @@ function renderRequestsPieChart(labels, data) {
|
||||
|
||||
// 加载最常屏蔽的域名
|
||||
function loadTopBlockedDomains() {
|
||||
// 首先获取表格元素并显示加载状态
|
||||
const tbody = document.getElementById('top-blocked-table')?.querySelector('tbody');
|
||||
if (tbody) {
|
||||
// 显示加载中状态
|
||||
tbody.innerHTML = `<td colspan="100%" style="color: #7f8c8d; font-style: italic;">加载中...</td>`;
|
||||
}
|
||||
|
||||
apiRequest('/api/top-blocked')
|
||||
.then(data => {
|
||||
renderTopBlockedDomains(data);
|
||||
// 处理多种可能的数据格式,特别优化对用户提供格式的支持
|
||||
let processedData = [];
|
||||
|
||||
console.log('最常屏蔽域名API返回数据:', data);
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
// 数组格式:直接使用,并过滤出有效的域名数据
|
||||
processedData = data.filter(item => item && (item.domain || item.name || item.Domain || item.Name) && (item.count !== undefined || item.Count !== undefined || item.hits !== undefined || item.Hits !== undefined));
|
||||
console.log('处理后的域名数据:', processedData);
|
||||
} else if (data && data.domains && Array.isArray(data.domains)) {
|
||||
// 嵌套在domains属性中
|
||||
processedData = data.domains;
|
||||
} else if (data && typeof data === 'object') {
|
||||
// 对象格式:转换为数组
|
||||
processedData = Object.keys(data).map(key => ({
|
||||
domain: key,
|
||||
count: data[key]
|
||||
}));
|
||||
}
|
||||
|
||||
renderTopBlockedDomains(processedData);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取最常屏蔽域名失败:', error);
|
||||
showError(document.getElementById('top-blocked-table').querySelector('tbody'), '获取数据失败');
|
||||
// 显示默认空数据而不是错误消息,保持界面一致性
|
||||
if (tbody) {
|
||||
showEmpty(tbody, '获取数据失败');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 渲染最常屏蔽的域名表格
|
||||
function renderTopBlockedDomains(domains) {
|
||||
const tbody = document.getElementById('top-blocked-table').querySelector('tbody');
|
||||
const tbody = document.getElementById('top-blocked-table')?.querySelector('tbody');
|
||||
if (!tbody) return;
|
||||
|
||||
console.log('准备渲染的域名数据:', domains);
|
||||
|
||||
if (!domains || domains.length === 0) {
|
||||
showEmpty(tbody, '暂无屏蔽记录');
|
||||
return;
|
||||
@@ -196,27 +300,61 @@ function renderTopBlockedDomains(domains) {
|
||||
tbody.innerHTML = '';
|
||||
|
||||
domains.forEach((domain, index) => {
|
||||
if (!domain) return;
|
||||
|
||||
// 支持不同的字段名和格式,特别针对用户提供的数据格式优化
|
||||
const domainName = domain.domain || domain.name || domain.Domain || domain.Name || '未知域名';
|
||||
const count = domain.count !== undefined ? domain.count :
|
||||
(domain.Count !== undefined ? domain.Count :
|
||||
(domain.hits !== undefined ? domain.hits :
|
||||
(domain.Hits !== undefined ? domain.Hits : 0)));
|
||||
|
||||
console.log(`渲染域名 ${index + 1}:`, {domainName, count});
|
||||
|
||||
const row = document.createElement('tr');
|
||||
row.innerHTML = `
|
||||
<td>${domain.domain}</td>
|
||||
<td>${formatNumber(domain.count)}</td>
|
||||
<td>${domainName}</td>
|
||||
<td>${formatNumber(count)}</td>
|
||||
`;
|
||||
tbody.appendChild(row);
|
||||
});
|
||||
|
||||
// 初始化表格排序
|
||||
initTableSort('top-blocked-table');
|
||||
if (typeof initTableSort === 'function') {
|
||||
initTableSort('top-blocked-table');
|
||||
}
|
||||
}
|
||||
|
||||
// 加载最常解析的域名
|
||||
function loadTopResolvedDomains() {
|
||||
apiRequest('/api/top-resolved')
|
||||
.then(data => {
|
||||
renderTopResolvedDomains(data);
|
||||
// 处理多种可能的数据格式
|
||||
let processedData = [];
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
// 数组格式:直接使用
|
||||
processedData = data;
|
||||
} else if (data && data.domains && Array.isArray(data.domains)) {
|
||||
// 嵌套在domains属性中
|
||||
processedData = data.domains;
|
||||
} else if (data && typeof data === 'object') {
|
||||
// 对象格式:转换为数组
|
||||
processedData = Object.keys(data).map(key => ({
|
||||
domain: key,
|
||||
count: data[key]
|
||||
}));
|
||||
}
|
||||
|
||||
renderTopResolvedDomains(processedData);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取最常解析域名失败:', error);
|
||||
showError(document.getElementById('top-resolved-table').querySelector('tbody'), '获取数据失败');
|
||||
// 显示默认空数据而不是错误消息,保持界面一致性
|
||||
const tbody = document.getElementById('top-resolved-table').querySelector('tbody');
|
||||
if (tbody) {
|
||||
showEmpty(tbody, '暂无解析记录');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -233,10 +371,14 @@ function renderTopResolvedDomains(domains) {
|
||||
tbody.innerHTML = '';
|
||||
|
||||
domains.forEach((domain, index) => {
|
||||
const row = document.createElement('tr');
|
||||
row.innerHTML = `
|
||||
<td>${domain.domain}</td>
|
||||
<td>${formatNumber(domain.count)}</td>
|
||||
// 支持不同的字段名和格式
|
||||
const domainName = domain.domain || domain.name || domain.Domain || domain.Name || '未知域名';
|
||||
const count = domain.count || domain.Count || domain.hits || domain.Hits || 0;
|
||||
|
||||
const row = document.createElement('tr');
|
||||
row.innerHTML = `
|
||||
<td>${domainName}</td>
|
||||
<td>${formatNumber(count)}</td>
|
||||
`;
|
||||
tbody.appendChild(row);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user