// 屏蔽管理页面功能实现 // 初始化屏蔽管理页面 function initShieldPage() { // 加载屏蔽规则统计信息 loadShieldStats(); // 加载本地规则 loadLocalRules(); // 加载远程黑名单 loadRemoteBlacklists(); // 加载hosts条目 loadHostsEntries(); // 设置事件监听器 setupShieldEventListeners(); } // 加载屏蔽规则统计信息 async function loadShieldStats() { showLoading('加载屏蔽规则统计信息...'); try { const response = await fetch('/api/shield'); if (!response.ok) { throw new Error('Failed to load shield stats'); } const stats = await response.json(); // 更新统计信息 document.getElementById('domain-rules-count').textContent = stats.domainRulesCount || 0; document.getElementById('domain-exceptions-count').textContent = stats.domainExceptionsCount || 0; document.getElementById('regex-rules-count').textContent = stats.regexRulesCount || 0; document.getElementById('regex-exceptions-count').textContent = stats.regexExceptionsCount || 0; document.getElementById('hosts-rules-count').textContent = stats.hostsRulesCount || 0; document.getElementById('blacklist-count').textContent = stats.blacklistCount || 0; hideLoading(); } catch (error) { console.error('Error loading shield stats:', error); showErrorMessage('加载屏蔽规则统计信息失败'); hideLoading(); } } // 加载本地规则 async function loadLocalRules() { showLoading('加载本地规则...'); try { const response = await fetch('/api/shield'); if (!response.ok) { throw new Error('Failed to load local rules'); } // 注意:当前API不返回完整规则列表,这里只是示例 // 实际实现需要后端提供获取本地规则的API const rules = []; updateRulesTable(rules); hideLoading(); } catch (error) { console.error('Error loading local rules:', error); showErrorMessage('加载本地规则失败'); hideLoading(); } } // 更新规则表格 function updateRulesTable(rules) { const tbody = document.getElementById('rules-table-body'); if (rules.length === 0) { tbody.innerHTML = '暂无规则'; return; } tbody.innerHTML = rules.map(rule => ` ${rule} `).join(''); // 重新绑定删除事件 document.querySelectorAll('.delete-rule-btn').forEach(btn => { btn.addEventListener('click', handleDeleteRule); }); } // 处理删除规则 async function handleDeleteRule(e) { const rule = e.target.closest('.delete-rule-btn').dataset.rule; showLoading('删除规则中...'); try { const response = await fetch('/api/shield', { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ rule }) }); if (!response.ok) { throw new Error('Failed to delete rule'); } showSuccessMessage('规则删除成功'); // 重新加载规则 loadLocalRules(); // 重新加载统计信息 loadShieldStats(); hideLoading(); } catch (error) { console.error('Error deleting rule:', error); showErrorMessage('删除规则失败'); hideLoading(); } } // 添加新规则 async function handleAddRule() { const rule = document.getElementById('new-rule').value.trim(); if (!rule) { showErrorMessage('规则不能为空'); return; } showLoading('添加规则中...'); try { const response = await fetch('/api/shield', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ rule }) }); if (!response.ok) { throw new Error('Failed to add rule'); } showSuccessMessage('规则添加成功'); // 清空输入框 document.getElementById('new-rule').value = ''; // 隐藏表单 document.getElementById('add-rule-form').classList.add('hidden'); // 重新加载规则 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'); if (!response.ok) { throw new Error('Failed to load remote blacklists'); } const blacklists = await response.json(); updateBlacklistsTable(blacklists); hideLoading(); } catch (error) { console.error('Error loading remote blacklists:', error); showErrorMessage('加载远程黑名单失败'); hideLoading(); } } // 更新黑名单表格 function updateBlacklistsTable(blacklists) { const tbody = document.getElementById('blacklists-table-body'); if (blacklists.length === 0) { tbody.innerHTML = '暂无黑名单'; return; } tbody.innerHTML = blacklists.map(blacklist => ` ${blacklist.Name} ${blacklist.URL} `).join(''); // 重新绑定事件 document.querySelectorAll('.update-blacklist-btn').forEach(btn => { btn.addEventListener('click', handleUpdateBlacklist); }); document.querySelectorAll('.delete-blacklist-btn').forEach(btn => { btn.addEventListener('click', handleDeleteBlacklist); }); } // 处理更新单个黑名单 async function handleUpdateBlacklist(e) { const url = e.target.closest('.update-blacklist-btn').dataset.url; showLoading('更新黑名单中...'); try { const response = await fetch(`/api/shield/blacklists/${encodeURIComponent(url)}/update`, { method: 'POST' }); if (!response.ok) { throw new Error('Failed to update blacklist'); } showSuccessMessage('黑名单更新成功'); // 重新加载黑名单 loadRemoteBlacklists(); // 重新加载统计信息 loadShieldStats(); hideLoading(); } catch (error) { console.error('Error updating blacklist:', error); showErrorMessage('更新黑名单失败'); hideLoading(); } } // 处理删除黑名单 async function handleDeleteBlacklist(e) { const url = e.target.closest('.delete-blacklist-btn').dataset.url; showLoading('删除黑名单中...'); try { const response = await fetch(`/api/shield/blacklists/${encodeURIComponent(url)}`, { method: 'DELETE' }); if (!response.ok) { throw new Error('Failed to delete blacklist'); } showSuccessMessage('黑名单删除成功'); // 重新加载黑名单 loadRemoteBlacklists(); // 重新加载统计信息 loadShieldStats(); hideLoading(); } catch (error) { console.error('Error deleting blacklist:', error); showErrorMessage('删除黑名单失败'); hideLoading(); } } // 处理添加黑名单 async function handleAddBlacklist() { const name = document.getElementById('blacklist-name').value.trim(); const url = document.getElementById('blacklist-url').value.trim(); if (!name || !url) { showErrorMessage('名称和URL不能为空'); return; } showLoading('添加黑名单中...'); try { const response = await fetch('/api/shield/blacklists', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, url }) }); if (!response.ok) { throw new Error('Failed to add blacklist'); } showSuccessMessage('黑名单添加成功'); // 清空输入框 document.getElementById('blacklist-name').value = ''; document.getElementById('blacklist-url').value = ''; // 隐藏表单 document.getElementById('add-blacklist-form').classList.add('hidden'); // 重新加载黑名单 loadRemoteBlacklists(); // 重新加载统计信息 loadShieldStats(); hideLoading(); } catch (error) { console.error('Error adding blacklist:', error); showErrorMessage('添加黑名单失败'); hideLoading(); } } // 加载hosts条目 async function loadHostsEntries() { showLoading('加载Hosts条目...'); try { const response = await fetch('/api/shield/hosts'); if (!response.ok) { throw new Error('Failed to load hosts entries'); } const data = await response.json(); updateHostsTable(data.hosts || []); hideLoading(); } catch (error) { console.error('Error loading hosts entries:', error); showErrorMessage('加载Hosts条目失败'); hideLoading(); } } // 更新hosts表格 function updateHostsTable(hosts) { const tbody = document.getElementById('hosts-table-body'); if (hosts.length === 0) { tbody.innerHTML = '暂无Hosts条目'; return; } tbody.innerHTML = hosts.map(entry => ` ${entry.ip} ${entry.domain} `).join(''); // 重新绑定删除事件 document.querySelectorAll('.delete-hosts-btn').forEach(btn => { btn.addEventListener('click', handleDeleteHostsEntry); }); } // 处理删除hosts条目 async function handleDeleteHostsEntry(e) { const domain = e.target.closest('.delete-hosts-btn').dataset.domain; showLoading('删除Hosts条目...'); try { const response = await fetch('/api/shield/hosts', { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ domain }) }); if (!response.ok) { throw new Error('Failed to delete hosts entry'); } showSuccessMessage('Hosts条目删除成功'); // 重新加载hosts条目 loadHostsEntries(); // 重新加载统计信息 loadShieldStats(); hideLoading(); } catch (error) { console.error('Error deleting hosts entry:', error); showErrorMessage('删除Hosts条目失败'); hideLoading(); } } // 处理添加hosts条目 async function handleAddHostsEntry() { const ip = document.getElementById('hosts-ip').value.trim(); const domain = document.getElementById('hosts-domain').value.trim(); if (!ip || !domain) { showErrorMessage('IP地址和域名不能为空'); return; } showLoading('添加Hosts条目...'); try { const response = await fetch('/api/shield/hosts', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ip, domain }) }); if (!response.ok) { throw new Error('Failed to add hosts entry'); } showSuccessMessage('Hosts条目添加成功'); // 清空输入框 document.getElementById('hosts-ip').value = ''; document.getElementById('hosts-domain').value = ''; // 隐藏表单 document.getElementById('add-hosts-form').classList.add('hidden'); // 重新加载hosts条目 loadHostsEntries(); // 重新加载统计信息 loadShieldStats(); hideLoading(); } catch (error) { console.error('Error adding hosts entry:', error); showErrorMessage('添加Hosts条目失败'); hideLoading(); } } // 设置事件监听器 function setupShieldEventListeners() { // 本地规则管理事件 document.getElementById('add-rule-btn').addEventListener('click', () => { document.getElementById('add-rule-form').classList.toggle('hidden'); }); document.getElementById('save-rule-btn').addEventListener('click', handleAddRule); document.getElementById('cancel-rule-btn').addEventListener('click', () => { document.getElementById('add-rule-form').classList.add('hidden'); document.getElementById('new-rule').value = ''; }); // 远程黑名单管理事件 document.getElementById('add-blacklist-btn').addEventListener('click', () => { document.getElementById('add-blacklist-form').classList.toggle('hidden'); }); document.getElementById('save-blacklist-btn').addEventListener('click', handleAddBlacklist); document.getElementById('cancel-blacklist-btn').addEventListener('click', () => { document.getElementById('add-blacklist-form').classList.add('hidden'); document.getElementById('blacklist-name').value = ''; document.getElementById('blacklist-url').value = ''; }); // Hosts条目管理事件 document.getElementById('add-hosts-btn').addEventListener('click', () => { document.getElementById('add-hosts-form').classList.toggle('hidden'); }); document.getElementById('save-hosts-btn').addEventListener('click', handleAddHostsEntry); document.getElementById('cancel-hosts-btn').addEventListener('click', () => { document.getElementById('add-hosts-form').classList.add('hidden'); document.getElementById('hosts-ip').value = ''; document.getElementById('hosts-domain').value = ''; }); } // 显示成功消息 function showSuccessMessage(message) { showNotification(message, 'success'); } // 显示错误消息 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 = `
${message}
`; document.body.appendChild(loading); } // 隐藏加载状态 function hideLoading() { const loading = document.querySelector('.loading-overlay'); if (loading) { loading.remove(); } } // 显示通知 function showNotification(message, type = 'info') { // 移除现有通知 const existingNotification = document.querySelector('.notification'); if (existingNotification) { existingNotification.remove(); } // 创建新通知 const notification = document.createElement('div'); notification.className = `notification fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg z-50 transform transition-all duration-300 ease-in-out translate-y-0 opacity-0`; // 设置通知样式 if (type === 'success') { notification.classList.add('bg-green-500', 'text-white'); } else if (type === 'error') { notification.classList.add('bg-red-500', 'text-white'); } else { notification.classList.add('bg-blue-500', 'text-white'); } notification.innerHTML = `
${message}
`; document.body.appendChild(notification); // 显示通知 setTimeout(() => { notification.classList.remove('opacity-0'); notification.classList.add('opacity-100'); }, 10); // 3秒后隐藏通知 setTimeout(() => { notification.classList.remove('opacity-100'); notification.classList.add('opacity-0'); setTimeout(() => { notification.remove(); }, 300); }, 3000); } // 页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initShieldPage); } else { initShieldPage(); } // 当切换到屏蔽管理页面时重新加载数据 document.addEventListener('DOMContentLoaded', () => { // 监听hash变化,当切换到屏蔽管理页面时重新加载数据 window.addEventListener('hashchange', () => { if (window.location.hash === '#shield') { initShieldPage(); } }); });