优化日志查询页面
This commit is contained in:
@@ -901,16 +901,29 @@
|
||||
<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-left py-3 px-4 text-sm font-medium text-gray-500">客户端IP</th>
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500">域名</th>
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500">查询类型</th>
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500">结果</th>
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500">响应时间</th>
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500">屏蔽规则</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr class="border-b border-gray-200">
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500 cursor-pointer hover:text-primary transition-colors" data-sort="time">
|
||||
<div class="flex items-center">
|
||||
时间
|
||||
<i class="fa fa-sort ml-1 text-xs"></i>
|
||||
</div>
|
||||
</th>
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500 cursor-pointer hover:text-primary transition-colors" data-sort="clientIp">
|
||||
<div class="flex items-center">
|
||||
客户端IP
|
||||
<i class="fa fa-sort ml-1 text-xs"></i>
|
||||
</div>
|
||||
</th>
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500 cursor-pointer hover:text-primary transition-colors" data-sort="domain">
|
||||
<div class="flex items-center">
|
||||
请求
|
||||
<i class="fa fa-sort ml-1 text-xs"></i>
|
||||
</div>
|
||||
</th>
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500">响应时间</th>
|
||||
<th class="text-left py-3 px-4 text-sm font-medium text-gray-500">屏蔽规则</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="logs-table-body">
|
||||
<tr>
|
||||
<td colspan="7" class="py-8 text-center text-gray-500">
|
||||
|
||||
@@ -7,6 +7,8 @@ let logsPerPage = 30; // 默认显示30条记录
|
||||
let currentFilter = '';
|
||||
let currentSearch = '';
|
||||
let logsChart = null;
|
||||
let currentSortField = '';
|
||||
let currentSortDirection = 'desc'; // 默认降序
|
||||
|
||||
// 初始化查询日志页面
|
||||
function initLogsPage() {
|
||||
@@ -129,6 +131,51 @@ function bindLogsEvents() {
|
||||
updateLogsChart(range);
|
||||
});
|
||||
});
|
||||
|
||||
// 排序按钮事件
|
||||
const sortHeaders = document.querySelectorAll('th[data-sort]');
|
||||
sortHeaders.forEach(header => {
|
||||
header.addEventListener('click', () => {
|
||||
const sortField = header.getAttribute('data-sort');
|
||||
|
||||
// 如果点击的是当前排序字段,则切换排序方向
|
||||
if (sortField === currentSortField) {
|
||||
currentSortDirection = currentSortDirection === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
// 否则,设置新的排序字段,默认降序
|
||||
currentSortField = sortField;
|
||||
currentSortDirection = 'desc';
|
||||
}
|
||||
|
||||
// 更新排序图标
|
||||
updateSortIcons();
|
||||
|
||||
// 重新加载日志
|
||||
currentPage = 1;
|
||||
loadLogs();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 更新排序图标
|
||||
function updateSortIcons() {
|
||||
const sortHeaders = document.querySelectorAll('th[data-sort]');
|
||||
sortHeaders.forEach(header => {
|
||||
const sortField = header.getAttribute('data-sort');
|
||||
const icon = header.querySelector('i');
|
||||
|
||||
// 重置所有图标
|
||||
icon.className = 'fa fa-sort ml-1 text-xs';
|
||||
|
||||
// 设置当前排序字段的图标
|
||||
if (sortField === currentSortField) {
|
||||
if (currentSortDirection === 'asc') {
|
||||
icon.className = 'fa fa-sort-asc ml-1 text-xs';
|
||||
} else {
|
||||
icon.className = 'fa fa-sort-desc ml-1 text-xs';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 加载日志统计数据
|
||||
@@ -171,6 +218,11 @@ function loadLogs() {
|
||||
url += `&search=${encodeURIComponent(currentSearch)}`;
|
||||
}
|
||||
|
||||
// 添加排序条件
|
||||
if (currentSortField) {
|
||||
url += `&sort=${currentSortField}&direction=${currentSortDirection}`;
|
||||
}
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
@@ -219,7 +271,7 @@ function updateLogsTable(logs) {
|
||||
// 显示空状态
|
||||
const emptyRow = document.createElement('tr');
|
||||
emptyRow.innerHTML = `
|
||||
<td colspan="7" class="py-8 text-center text-gray-500">
|
||||
<td colspan="5" class="py-8 text-center text-gray-500">
|
||||
<i class="fa fa-file-text-o text-4xl mb-2 text-gray-300"></i>
|
||||
<div>暂无查询日志</div>
|
||||
</td>
|
||||
@@ -233,42 +285,74 @@ function updateLogsTable(logs) {
|
||||
const row = document.createElement('tr');
|
||||
row.className = 'border-b border-gray-100 hover:bg-gray-50 transition-colors';
|
||||
|
||||
// 格式化时间
|
||||
// 格式化时间 - 两行显示,第一行显示时间,第二行显示日期
|
||||
const time = new Date(log.Timestamp);
|
||||
const formattedTime = time.toLocaleString('zh-CN', {
|
||||
const formattedDate = time.toLocaleDateString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
day: '2-digit'
|
||||
});
|
||||
const formattedTime = time.toLocaleTimeString('zh-CN', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit'
|
||||
});
|
||||
|
||||
// 结果样式
|
||||
let resultClass = '';
|
||||
let resultText = '';
|
||||
// 根据结果添加不同的背景色
|
||||
let rowClass = '';
|
||||
switch (log.Result) {
|
||||
case 'allowed':
|
||||
resultClass = 'text-success';
|
||||
resultText = '允许';
|
||||
break;
|
||||
case 'blocked':
|
||||
resultClass = 'text-danger';
|
||||
resultText = '屏蔽';
|
||||
rowClass = 'bg-red-50'; // 淡红色填充
|
||||
break;
|
||||
case 'error':
|
||||
resultClass = 'text-warning';
|
||||
resultText = '错误';
|
||||
case 'allowed':
|
||||
// 检查是否是规则允许项目
|
||||
if (log.BlockRule && log.BlockRule.includes('allow')) {
|
||||
rowClass = 'bg-green-50'; // 规则允许项目用淡绿色填充
|
||||
} else {
|
||||
rowClass = ''; // 允许的不填充
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rowClass = '';
|
||||
}
|
||||
|
||||
// 构建行内容
|
||||
// 添加行背景色
|
||||
if (rowClass) {
|
||||
row.classList.add(rowClass);
|
||||
}
|
||||
|
||||
// 添加被屏蔽或允许显示,并增加颜色
|
||||
let statusText = '';
|
||||
let statusClass = '';
|
||||
switch (log.Result) {
|
||||
case 'blocked':
|
||||
statusText = '被屏蔽';
|
||||
statusClass = 'text-danger';
|
||||
break;
|
||||
case 'allowed':
|
||||
statusText = '允许';
|
||||
statusClass = 'text-success';
|
||||
break;
|
||||
case 'error':
|
||||
statusText = '错误';
|
||||
statusClass = 'text-warning';
|
||||
break;
|
||||
default:
|
||||
statusText = '';
|
||||
statusClass = '';
|
||||
}
|
||||
|
||||
// 构建行内容 - 两行显示,时间列显示时间和日期,请求列显示域名和类型状态
|
||||
row.innerHTML = `
|
||||
<td class="py-3 px-4 text-sm">${formattedTime}</td>
|
||||
<td class="py-3 px-4">
|
||||
<div class="text-sm font-medium">${formattedTime}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">${formattedDate}</div>
|
||||
</td>
|
||||
<td class="py-3 px-4 text-sm">${log.ClientIP}</td>
|
||||
<td class="py-3 px-4 text-sm font-medium">${log.Domain}</td>
|
||||
<td class="py-3 px-4 text-sm">${log.QueryType}</td>
|
||||
<td class="py-3 px-4 text-sm"><span class="${resultClass}">${resultText}</span></td>
|
||||
<td class="py-3 px-4">
|
||||
<div class="text-sm font-medium">${log.Domain}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">类型: ${log.QueryType}, <span class="${statusClass}">${statusText}</span></div>
|
||||
</td>
|
||||
<td class="py-3 px-4 text-sm">${log.ResponseTime}ms</td>
|
||||
<td class="py-3 px-4 text-sm text-gray-500">${log.BlockRule || '-'}</td>
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user