修复本地规则管理不工作的问题
This commit is contained in:
@@ -36,7 +36,6 @@ function initConfigPage() {
|
||||
// 加载系统配置
|
||||
async function loadConfig() {
|
||||
try {
|
||||
showLoading(true);
|
||||
const result = await api.getConfig();
|
||||
|
||||
// 检查API返回的错误
|
||||
@@ -49,8 +48,6 @@ async function loadConfig() {
|
||||
} catch (error) {
|
||||
// 捕获可能的异常(虽然apiRequest不应该再抛出异常)
|
||||
showErrorMessage('加载配置失败: ' + (error.message || '未知错误'));
|
||||
} finally {
|
||||
showLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +103,6 @@ async function handleSaveConfig() {
|
||||
if (!formData) return;
|
||||
|
||||
try {
|
||||
showLoading(true);
|
||||
const result = await api.saveConfig(formData);
|
||||
|
||||
// 检查API返回的错误
|
||||
@@ -119,8 +115,6 @@ async function handleSaveConfig() {
|
||||
} catch (error) {
|
||||
// 捕获可能的异常(虽然apiRequest不应该再抛出异常)
|
||||
showErrorMessage('保存配置失败: ' + (error.message || '未知错误'));
|
||||
} finally {
|
||||
showLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +123,6 @@ async function handleRestartService() {
|
||||
if (!confirm('确定要重启DNS服务吗?重启期间服务可能会短暂不可用。')) return;
|
||||
|
||||
try {
|
||||
showLoading(true);
|
||||
const result = await api.restartService();
|
||||
|
||||
// 检查API返回的错误
|
||||
@@ -142,8 +135,6 @@ async function handleRestartService() {
|
||||
} catch (error) {
|
||||
// 捕获可能的异常(虽然apiRequest不应该再抛出异常)
|
||||
showErrorMessage('重启服务失败: ' + (error.message || '未知错误'));
|
||||
} finally {
|
||||
showLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,34 +211,7 @@ function setupConfigEventListeners() {
|
||||
getElement('restart-service-btn')?.addEventListener('click', handleRestartService);
|
||||
}
|
||||
|
||||
// 显示加载状态
|
||||
function showLoading(show) {
|
||||
const loadingElement = document.getElementById('loading-overlay');
|
||||
if (show) {
|
||||
if (!loadingElement) {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.id = 'loading-overlay';
|
||||
overlay.style.cssText = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1000;
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
`;
|
||||
overlay.innerHTML = '<div>处理中...</div>';
|
||||
document.body.appendChild(overlay);
|
||||
}
|
||||
} else {
|
||||
loadingElement?.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 显示成功消息
|
||||
function showSuccessMessage(message) {
|
||||
|
||||
@@ -446,18 +446,7 @@ async function loadDashboardData() {
|
||||
];
|
||||
}
|
||||
|
||||
// 实现数据加载状态管理
|
||||
function showLoading(elementId) {
|
||||
const loadingElement = document.getElementById(elementId + '-loading');
|
||||
const errorElement = document.getElementById(elementId + '-error');
|
||||
if (loadingElement) loadingElement.classList.remove('hidden');
|
||||
if (errorElement) errorElement.classList.add('hidden');
|
||||
}
|
||||
|
||||
function hideLoading(elementId) {
|
||||
const loadingElement = document.getElementById(elementId + '-loading');
|
||||
if (loadingElement) loadingElement.classList.add('hidden');
|
||||
}
|
||||
|
||||
|
||||
function showError(elementId) {
|
||||
const loadingElement = document.getElementById(elementId + '-loading');
|
||||
@@ -468,7 +457,6 @@ async function loadDashboardData() {
|
||||
|
||||
// 尝试获取TOP客户端,优先使用真实数据,失败时使用模拟数据
|
||||
let topClients = [];
|
||||
showLoading('top-clients');
|
||||
try {
|
||||
const clientsData = await api.getTopClients();
|
||||
console.log('TOP客户端:', clientsData);
|
||||
@@ -513,13 +501,10 @@ async function loadDashboardData() {
|
||||
{ ip: '192.168.1.104', count: 50 }
|
||||
];
|
||||
showError('top-clients');
|
||||
} finally {
|
||||
hideLoading('top-clients');
|
||||
}
|
||||
|
||||
// 尝试获取TOP域名,优先使用真实数据,失败时使用模拟数据
|
||||
let topDomains = [];
|
||||
showLoading('top-domains');
|
||||
try {
|
||||
const domainsData = await api.getTopDomains();
|
||||
console.log('TOP域名:', domainsData);
|
||||
@@ -564,8 +549,6 @@ async function loadDashboardData() {
|
||||
{ domain: 'youtube.com', count: 30 }
|
||||
];
|
||||
showError('top-domains');
|
||||
} finally {
|
||||
hideLoading('top-domains');
|
||||
}
|
||||
|
||||
// 更新统计卡片
|
||||
|
||||
@@ -23,8 +23,6 @@ async function handleDNSQuery() {
|
||||
return;
|
||||
}
|
||||
|
||||
showLoading('查询中...');
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/query?domain=${encodeURIComponent(domain)}`);
|
||||
if (!response.ok) {
|
||||
@@ -35,11 +33,9 @@ async function handleDNSQuery() {
|
||||
displayQueryResult(result, domain);
|
||||
saveQueryHistory(domain, result);
|
||||
loadQueryHistory();
|
||||
hideLoading();
|
||||
} catch (error) {
|
||||
console.error('DNS查询出错:', error);
|
||||
showErrorMessage('查询失败,请稍后重试');
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,31 +225,7 @@ function setupQueryEventListeners() {
|
||||
}
|
||||
}
|
||||
|
||||
// 显示加载状态
|
||||
function showLoading(message = '加载中...') {
|
||||
// 移除现有加载状态
|
||||
hideLoading();
|
||||
|
||||
// 创建加载状态元素
|
||||
const loading = document.createElement('div');
|
||||
loading.className = 'loading-overlay fixed inset-0 bg-black/50 flex items-center justify-center z-50';
|
||||
loading.innerHTML = `
|
||||
<div class="bg-white rounded-lg p-6 shadow-lg flex items-center space-x-4">
|
||||
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
|
||||
<span class="text-gray-700 font-medium">${message}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(loading);
|
||||
}
|
||||
|
||||
// 隐藏加载状态
|
||||
function hideLoading() {
|
||||
const loading = document.querySelector('.loading-overlay');
|
||||
if (loading) {
|
||||
loading.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// 显示成功消息
|
||||
function showSuccessMessage(message) {
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
// 屏蔽管理页面功能实现
|
||||
|
||||
// 初始化屏蔽管理页面
|
||||
function initShieldPage() {
|
||||
// 加载屏蔽规则统计信息
|
||||
loadShieldStats();
|
||||
// 加载本地规则
|
||||
loadLocalRules();
|
||||
// 加载远程黑名单
|
||||
loadRemoteBlacklists();
|
||||
async function initShieldPage() {
|
||||
// 并行加载所有数据
|
||||
await Promise.all([
|
||||
loadShieldStats(),
|
||||
loadLocalRules(),
|
||||
loadRemoteBlacklists()
|
||||
]);
|
||||
// 设置事件监听器
|
||||
setupShieldEventListeners();
|
||||
}
|
||||
|
||||
// 加载屏蔽规则统计信息
|
||||
async function loadShieldStats() {
|
||||
showLoading('加载屏蔽规则统计信息...');
|
||||
try {
|
||||
const response = await fetch('/api/shield');
|
||||
|
||||
@@ -40,18 +39,14 @@ async function loadShieldStats() {
|
||||
element.textContent = item.value || 0;
|
||||
}
|
||||
});
|
||||
|
||||
hideLoading();
|
||||
} catch (error) {
|
||||
console.error('加载屏蔽规则统计信息失败:', error);
|
||||
showErrorMessage('加载屏蔽规则统计信息失败');
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
// 加载本地规则
|
||||
async function loadLocalRules() {
|
||||
showLoading('加载本地规则...');
|
||||
try {
|
||||
const response = await fetch('/api/shield/localrules');
|
||||
|
||||
@@ -89,17 +84,14 @@ async function loadLocalRules() {
|
||||
}
|
||||
|
||||
updateRulesTable(rules);
|
||||
hideLoading();
|
||||
} catch (error) {
|
||||
console.error('加载本地规则失败:', error);
|
||||
showErrorMessage('加载本地规则失败');
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
// 加载远程规则
|
||||
async function loadRemoteRules() {
|
||||
showLoading('加载远程规则...');
|
||||
try {
|
||||
// 设置当前规则类型
|
||||
currentRulesType = 'remote';
|
||||
@@ -136,11 +128,9 @@ async function loadRemoteRules() {
|
||||
}
|
||||
|
||||
updateRulesTable(rules);
|
||||
hideLoading();
|
||||
} catch (error) {
|
||||
console.error('加载远程规则失败:', error);
|
||||
showErrorMessage('加载远程规则失败');
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,8 +169,19 @@ function updateRulesTable(rules) {
|
||||
const deleteBtn = document.createElement('button');
|
||||
deleteBtn.className = 'delete-rule-btn px-3 py-1 bg-danger text-white rounded-md hover:bg-danger/90 transition-colors text-sm';
|
||||
deleteBtn.dataset.rule = rule;
|
||||
deleteBtn.innerHTML = '<i class="fa fa-trash"></i>';
|
||||
deleteBtn.addEventListener('click', handleDeleteRule);
|
||||
|
||||
// 创建删除图标
|
||||
const deleteIcon = document.createElement('i');
|
||||
deleteIcon.className = 'fa fa-trash';
|
||||
deleteIcon.style.pointerEvents = 'none'; // 防止图标拦截点击事件
|
||||
|
||||
deleteBtn.appendChild(deleteIcon);
|
||||
|
||||
// 使用普通函数,确保this指向按钮元素
|
||||
deleteBtn.onclick = function(e) {
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
handleDeleteRule(e);
|
||||
};
|
||||
|
||||
tdAction.appendChild(deleteBtn);
|
||||
tr.appendChild(tdRule);
|
||||
@@ -201,9 +202,36 @@ function updateRulesTable(rules) {
|
||||
|
||||
// 处理删除规则
|
||||
async function handleDeleteRule(e) {
|
||||
const rule = e.target.closest('.delete-rule-btn').dataset.rule;
|
||||
showLoading('删除规则中...');
|
||||
console.log('Delete button clicked');
|
||||
let deleteBtn;
|
||||
|
||||
// 尝试从事件目标获取按钮元素
|
||||
deleteBtn = e.target.closest('.delete-rule-btn');
|
||||
console.log('Delete button from event target:', deleteBtn);
|
||||
|
||||
// 尝试从this获取按钮元素(备用方案)
|
||||
if (!deleteBtn && this && typeof this.classList === 'object' && this.classList) {
|
||||
if (this.classList.contains('delete-rule-btn')) {
|
||||
deleteBtn = this;
|
||||
console.log('Delete button from this:', deleteBtn);
|
||||
}
|
||||
}
|
||||
|
||||
if (!deleteBtn) {
|
||||
console.error('Delete button not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const rule = deleteBtn.dataset.rule;
|
||||
console.log('Rule to delete:', rule);
|
||||
|
||||
if (!rule) {
|
||||
console.error('Rule not found in data-rule attribute');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('Sending DELETE request to /api/shield');
|
||||
const response = await fetch('/api/shield', {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
@@ -212,24 +240,32 @@ async function handleDeleteRule(e) {
|
||||
body: JSON.stringify({ rule })
|
||||
});
|
||||
|
||||
console.log('Response status:', response.status);
|
||||
console.log('Response ok:', response.ok);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to delete rule');
|
||||
const errorText = await response.text();
|
||||
throw new Error(`Failed to delete rule: ${response.status} ${errorText}`);
|
||||
}
|
||||
|
||||
const responseData = await response.json();
|
||||
console.log('Response data:', responseData);
|
||||
|
||||
showSuccessMessage('规则删除成功');
|
||||
console.log('Current rules type:', currentRulesType);
|
||||
// 根据当前显示的规则类型重新加载对应的规则列表
|
||||
if (currentRulesType === 'local') {
|
||||
console.log('Reloading local rules');
|
||||
loadLocalRules();
|
||||
} else {
|
||||
console.log('Reloading remote rules');
|
||||
loadRemoteRules();
|
||||
}
|
||||
// 重新加载统计信息
|
||||
loadShieldStats();
|
||||
hideLoading();
|
||||
} catch (error) {
|
||||
console.error('Error deleting rule:', error);
|
||||
showErrorMessage('删除规则失败');
|
||||
hideLoading();
|
||||
showErrorMessage('删除规则失败: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +277,6 @@ async function handleAddRule() {
|
||||
return;
|
||||
}
|
||||
|
||||
showLoading('添加规则中...');
|
||||
try {
|
||||
const response = await fetch('/api/shield', {
|
||||
method: 'POST',
|
||||
@@ -262,17 +297,14 @@ async function handleAddRule() {
|
||||
loadLocalRules();
|
||||
// 重新加载统计信息
|
||||
loadShieldStats();
|
||||
hideLoading();
|
||||
} catch (error) {
|
||||
console.error('Error adding rule:', error);
|
||||
showErrorMessage('添加规则失败');
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
// 加载远程黑名单
|
||||
async function loadRemoteBlacklists() {
|
||||
showLoading('加载远程黑名单...');
|
||||
try {
|
||||
const response = await fetch('/api/shield/blacklists');
|
||||
|
||||
@@ -285,11 +317,9 @@ async function loadRemoteBlacklists() {
|
||||
// 确保blacklists是数组
|
||||
const blacklistArray = Array.isArray(blacklists) ? blacklists : [];
|
||||
updateBlacklistsTable(blacklistArray);
|
||||
hideLoading();
|
||||
} catch (error) {
|
||||
console.error('加载远程黑名单失败:', error);
|
||||
showErrorMessage('加载远程黑名单失败');
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,7 +456,6 @@ async function handleUpdateBlacklist(e) {
|
||||
return;
|
||||
}
|
||||
|
||||
showLoading('更新黑名单中...');
|
||||
try {
|
||||
const response = await fetch(`/api/shield/blacklists/${encodeURIComponent(url)}/update`, {
|
||||
method: 'POST',
|
||||
@@ -448,8 +477,6 @@ async function handleUpdateBlacklist(e) {
|
||||
} catch (error) {
|
||||
console.error('更新黑名单失败:', error);
|
||||
showToast('更新黑名单失败: ' + error.message, 'error');
|
||||
} finally {
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +494,6 @@ async function handleDeleteBlacklist(e) {
|
||||
return;
|
||||
}
|
||||
|
||||
showLoading('删除黑名单中...');
|
||||
try {
|
||||
const response = await fetch(`/api/shield/blacklists/${encodeURIComponent(url)}`, {
|
||||
method: 'DELETE',
|
||||
@@ -489,8 +515,6 @@ async function handleDeleteBlacklist(e) {
|
||||
} catch (error) {
|
||||
console.error('删除黑名单失败:', error);
|
||||
showToast('删除黑名单失败: ' + error.message, 'error');
|
||||
} finally {
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,7 +545,6 @@ async function handleAddBlacklist(event) {
|
||||
return;
|
||||
}
|
||||
|
||||
showLoading('添加黑名单中...');
|
||||
try {
|
||||
const response = await fetch('/api/shield/blacklists', {
|
||||
method: 'POST',
|
||||
@@ -553,11 +576,9 @@ async function handleAddBlacklist(event) {
|
||||
loadRemoteBlacklists();
|
||||
// 重新加载统计信息
|
||||
loadShieldStats();
|
||||
hideLoading();
|
||||
} catch (error) {
|
||||
console.error('Error adding blacklist:', error);
|
||||
showErrorMessage(error.message || '添加黑名单失败');
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,18 +590,26 @@ let currentRulesType = 'local';
|
||||
// 设置事件监听器
|
||||
function setupShieldEventListeners() {
|
||||
// 本地规则管理事件
|
||||
document.getElementById('save-rule-btn').addEventListener('click', handleAddRule);
|
||||
|
||||
// 远程黑名单管理事件
|
||||
document.getElementById('save-blacklist-btn').addEventListener('click', handleAddBlacklist);
|
||||
|
||||
// 添加切换查看本地规则和远程规则的事件监听
|
||||
if (document.getElementById('view-local-rules-btn')) {
|
||||
document.getElementById('view-local-rules-btn').addEventListener('click', loadLocalRules);
|
||||
const saveRuleBtn = document.getElementById('save-rule-btn');
|
||||
if (saveRuleBtn) {
|
||||
saveRuleBtn.addEventListener('click', handleAddRule);
|
||||
}
|
||||
|
||||
if (document.getElementById('view-remote-rules-btn')) {
|
||||
document.getElementById('view-remote-rules-btn').addEventListener('click', loadRemoteRules);
|
||||
// 远程黑名单管理事件
|
||||
const saveBlacklistBtn = document.getElementById('save-blacklist-btn');
|
||||
if (saveBlacklistBtn) {
|
||||
saveBlacklistBtn.addEventListener('click', handleAddBlacklist);
|
||||
}
|
||||
|
||||
// 添加切换查看本地规则和远程规则的事件监听
|
||||
const viewLocalRulesBtn = document.getElementById('view-local-rules-btn');
|
||||
if (viewLocalRulesBtn) {
|
||||
viewLocalRulesBtn.addEventListener('click', loadLocalRules);
|
||||
}
|
||||
|
||||
const viewRemoteRulesBtn = document.getElementById('view-remote-rules-btn');
|
||||
if (viewRemoteRulesBtn) {
|
||||
viewRemoteRulesBtn.addEventListener('click', loadRemoteRules);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,31 +623,7 @@ function showErrorMessage(message) {
|
||||
showNotification(message, 'error');
|
||||
}
|
||||
|
||||
// 显示加载状态
|
||||
function showLoading(message = '加载中...') {
|
||||
// 移除现有加载状态
|
||||
hideLoading();
|
||||
|
||||
// 创建加载状态元素
|
||||
const loading = document.createElement('div');
|
||||
loading.className = 'loading-overlay fixed inset-0 bg-black/50 flex items-center justify-center z-50';
|
||||
loading.innerHTML = `
|
||||
<div class="bg-white rounded-lg p-6 shadow-lg flex items-center space-x-4">
|
||||
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
|
||||
<span class="text-gray-700 font-medium">${message}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(loading);
|
||||
}
|
||||
|
||||
// 隐藏加载状态
|
||||
function hideLoading() {
|
||||
const loading = document.querySelector('.loading-overlay');
|
||||
if (loading) {
|
||||
loading.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// 显示通知
|
||||
function showNotification(message, type = 'info') {
|
||||
|
||||
Reference in New Issue
Block a user