修复本地规则管理不工作的问题

This commit is contained in:
Alex Yang
2025-11-28 18:41:55 +08:00
parent ca4a32422c
commit ee148fe6c3
21 changed files with 273 additions and 819217 deletions

View File

@@ -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) {

View File

@@ -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');
}
// 更新统计卡片

View File

@@ -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) {

View File

@@ -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') {