// 屏蔽规则管理模块 // 全局变量 let rules = []; let currentPage = 1; let itemsPerPage = 50; // 默认每页显示50条规则 let filteredRules = []; // 初始化屏蔽规则面板 function initRulesPanel() { // 加载规则列表 loadRules(); // 绑定添加规则按钮事件 document.getElementById('add-rule-btn').addEventListener('click', addNewRule); // 绑定刷新规则按钮事件 document.getElementById('reload-rules-btn').addEventListener('click', reloadRules); // 绑定搜索框事件 document.getElementById('rule-search').addEventListener('input', filterRules); // 绑定每页显示数量变更事件 document.getElementById('items-per-page').addEventListener('change', () => { itemsPerPage = parseInt(document.getElementById('items-per-page').value); currentPage = 1; // 重置为第一页 renderRulesList(); }); // 绑定分页按钮事件 document.getElementById('prev-page-btn').addEventListener('click', goToPreviousPage); document.getElementById('next-page-btn').addEventListener('click', goToNextPage); document.getElementById('first-page-btn').addEventListener('click', goToFirstPage); document.getElementById('last-page-btn').addEventListener('click', goToLastPage); } // 加载规则列表 async function loadRules() { try { const rulesPanel = document.getElementById('rules-panel'); showLoading(rulesPanel); const data = await apiRequest('/shield', 'GET'); rules = data.rules || []; filteredRules = [...rules]; currentPage = 1; // 重置为第一页 renderRulesList(); } catch (error) { showError('加载规则失败:' + error.message); } finally { const rulesPanel = document.getElementById('rules-panel'); hideLoading(rulesPanel); } } // 渲染规则列表 function renderRulesList() { const rulesList = document.getElementById('rules-list'); const paginationInfo = document.getElementById('pagination-info'); // 清空列表 rulesList.innerHTML = ''; if (filteredRules.length === 0) { rulesList.innerHTML = '暂无规则'; paginationInfo.textContent = '共0条规则'; updatePaginationButtons(); return; } // 计算分页数据 const totalPages = Math.ceil(filteredRules.length / itemsPerPage); const startIndex = (currentPage - 1) * itemsPerPage; const endIndex = Math.min(startIndex + itemsPerPage, filteredRules.length); const currentRules = filteredRules.slice(startIndex, endIndex); // 渲染当前页的规则 currentRules.forEach((rule, index) => { const row = document.createElement('tr'); const globalIndex = startIndex + index; row.innerHTML = ` ${globalIndex + 1}
${escapeHtml(rule)}
`; rulesList.appendChild(row); }); // 绑定删除按钮事件 document.querySelectorAll('.delete-rule').forEach(button => { button.addEventListener('click', (e) => { const index = parseInt(e.currentTarget.dataset.index); deleteRule(index); }); }); // 更新分页信息 paginationInfo.textContent = `显示 ${startIndex + 1}-${endIndex} 条,共 ${filteredRules.length} 条规则,第 ${currentPage}/${totalPages} 页`; // 更新分页按钮状态 updatePaginationButtons(); } // 更新分页按钮状态 function updatePaginationButtons() { const totalPages = Math.ceil(filteredRules.length / itemsPerPage); const prevBtn = document.getElementById('prev-page-btn'); const nextBtn = document.getElementById('next-page-btn'); const firstBtn = document.getElementById('first-page-btn'); const lastBtn = document.getElementById('last-page-btn'); prevBtn.disabled = currentPage === 1; nextBtn.disabled = currentPage === totalPages || totalPages === 0; firstBtn.disabled = currentPage === 1; lastBtn.disabled = currentPage === totalPages || totalPages === 0; } // 上一页 function goToPreviousPage() { if (currentPage > 1) { currentPage--; renderRulesList(); } } // 下一页 function goToNextPage() { const totalPages = Math.ceil(filteredRules.length / itemsPerPage); if (currentPage < totalPages) { currentPage++; renderRulesList(); } } // 第一页 function goToFirstPage() { currentPage = 1; renderRulesList(); } // 最后一页 function goToLastPage() { currentPage = Math.ceil(filteredRules.length / itemsPerPage); renderRulesList(); } // 添加新规则 async function addNewRule() { const ruleInput = document.getElementById('rule-input'); const rule = ruleInput.value.trim(); if (!rule) { showNotification('请输入规则内容', 'warning'); return; } try { const response = await apiRequest('/shield/rule', 'POST', { rule }); if (response.success) { rules.push(rule); filteredRules = [...rules]; ruleInput.value = ''; // 添加后跳转到最后一页,显示新添加的规则 currentPage = Math.ceil(filteredRules.length / itemsPerPage); renderRulesList(); showNotification('规则添加成功', 'success'); } else { showNotification('规则添加失败:' + (response.message || '未知错误'), 'error'); } } catch (error) { showError('添加规则失败:' + error.message); } } // 删除规则 async function deleteRule(index) { if (!confirm('确定要删除这条规则吗?')) { return; } try { const rule = filteredRules[index]; const response = await apiRequest('/shield/rule', 'DELETE', { rule }); if (response.success) { // 在原规则列表中找到并删除 const originalIndex = rules.indexOf(rule); if (originalIndex !== -1) { rules.splice(originalIndex, 1); } // 在过滤后的列表中删除 filteredRules.splice(index, 1); // 如果当前页没有数据了,回到上一页 const totalPages = Math.ceil(filteredRules.length / itemsPerPage); if (currentPage > totalPages && totalPages > 0) { currentPage = totalPages; } renderRulesList(); showNotification('规则删除成功', 'success'); } else { showNotification('规则删除失败:' + (response.message || '未知错误'), 'error'); } } catch (error) { showError('删除规则失败:' + error.message); } } // 重新加载规则 async function reloadRules() { if (!confirm('确定要重新加载所有规则吗?这将覆盖当前内存中的规则。')) { return; } try { const rulesPanel = document.getElementById('rules-panel'); showLoading(rulesPanel); await apiRequest('/shield/reload', 'POST'); // 重新加载规则列表 await loadRules(); showNotification('规则重新加载成功', 'success'); } catch (error) { showError('重新加载规则失败:' + error.message); } finally { const rulesPanel = document.getElementById('rules-panel'); hideLoading(rulesPanel); } } // 过滤规则 function filterRules() { const searchTerm = document.getElementById('rule-search').value.toLowerCase(); if (searchTerm) { filteredRules = rules.filter(rule => rule.toLowerCase().includes(searchTerm)); } else { filteredRules = [...rules]; } currentPage = 1; // 重置为第一页 renderRulesList(); } // HTML转义,防止XSS攻击 function escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return text.replace(/[&<>"']/g, m => map[m]); } // 导出初始化函数 window.initRulesPanel = initRulesPanel;