web异常待修复

This commit is contained in:
Alex Yang
2025-11-24 10:50:03 +08:00
parent 534878fa4d
commit 4467a0bf4c
14 changed files with 30715 additions and 243 deletions

View File

@@ -40,13 +40,24 @@ async function loadRules() {
const rulesPanel = document.getElementById('rules-panel');
showLoading(rulesPanel);
// 更新API路径使用完整路径
const data = await apiRequest('/shield', 'GET');
rules = data.rules || [];
// 处理不同格式的响应数据
rules = Array.isArray(data) ? data : (data.rules || []);
filteredRules = [...rules];
currentPage = 1; // 重置为第一页
renderRulesList();
// 更新规则数量统计卡片
if (window.updateRulesCount && typeof window.updateRulesCount === 'function') {
window.updateRulesCount(rules.length);
}
} catch (error) {
showError('加载规则失败' + error.message);
console.error('加载规则失败:', error);
if (typeof window.showNotification === 'function') {
window.showNotification('加载规则失败', 'danger');
}
} finally {
const rulesPanel = document.getElementById('rules-panel');
hideLoading(rulesPanel);
@@ -62,7 +73,14 @@ function renderRulesList() {
rulesList.innerHTML = '';
if (filteredRules.length === 0) {
rulesList.innerHTML = '<tr><td colspan="4" class="text-center">暂无规则</td></tr>';
// 使用更友好的空状态显示
rulesList.innerHTML = '<tr><td colspan="4" class="text-center py-4">' +
'<div class="empty-state">' +
'<div class="empty-icon"><i class="fas fa-shield-alt text-muted"></i></div>' +
'<div class="empty-title text-muted">暂无规则</div>' +
'<div class="empty-description text-muted">点击添加按钮或刷新规则来获取规则列表</div>' +
'</div>' +
'</td></tr>';
paginationInfo.textContent = '共0条规则';
updatePaginationButtons();
return;
@@ -79,9 +97,12 @@ function renderRulesList() {
const row = document.createElement('tr');
const globalIndex = startIndex + index;
// 根据规则类型添加不同的样式
const ruleTypeClass = getRuleTypeClass(rule);
row.innerHTML = `
<td class="rule-id">${globalIndex + 1}</td>
<td class="rule-content"><pre>${escapeHtml(rule)}</pre></td>
<td class="rule-content ${ruleTypeClass}"><pre>${escapeHtml(rule)}</pre></td>
<td class="rule-actions">
<button class="btn btn-danger btn-sm delete-rule" data-index="${globalIndex}">
<i class="fas fa-trash"></i> 删除
@@ -89,7 +110,17 @@ function renderRulesList() {
</td>
`;
// 添加行动画效果
row.style.opacity = '0';
row.style.transform = 'translateY(10px)';
rulesList.appendChild(row);
// 使用requestAnimationFrame确保动画平滑
requestAnimationFrame(() => {
row.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
row.style.opacity = '1';
row.style.transform = 'translateY(0)';
});
});
// 绑定删除按钮事件
@@ -156,15 +187,22 @@ async function addNewRule() {
const rule = ruleInput.value.trim();
if (!rule) {
showNotification('请输入规则内容', 'warning');
if (typeof window.showNotification === 'function') {
window.showNotification('请输入规则内容', 'warning');
}
return;
}
try {
const response = await apiRequest('/shield/rule', 'POST', { rule });
// 预处理规则支持AdGuardHome格式
const processedRule = preprocessRule(rule);
if (response.success) {
rules.push(rule);
// 更新API路径
const response = await apiRequest('/shield', 'POST', { rule: processedRule });
// 处理不同的响应格式
if (response.success || response.status === 'success') {
rules.push(processedRule);
filteredRules = [...rules];
ruleInput.value = '';
@@ -172,12 +210,24 @@ async function addNewRule() {
currentPage = Math.ceil(filteredRules.length / itemsPerPage);
renderRulesList();
showNotification('规则添加成功', 'success');
// 更新规则数量统计
if (window.updateRulesCount && typeof window.updateRulesCount === 'function') {
window.updateRulesCount(rules.length);
}
if (typeof window.showNotification === 'function') {
window.showNotification('规则添加成功', 'success');
}
} else {
showNotification('规则添加失败:' + (response.message || '未知错误'), 'error');
if (typeof window.showNotification === 'function') {
window.showNotification('规则添加失败:' + (response.message || '未知错误'), 'danger');
}
}
} catch (error) {
showError('添加规则失败' + error.message);
console.error('添加规则失败:', error);
if (typeof window.showNotification === 'function') {
window.showNotification('添加规则失败', 'danger');
}
}
}
@@ -189,9 +239,20 @@ async function deleteRule(index) {
try {
const rule = filteredRules[index];
const response = await apiRequest('/shield/rule', 'DELETE', { rule });
const rowElement = document.querySelectorAll('#rules-list tr')[index];
if (response.success) {
// 添加删除动画
if (rowElement) {
rowElement.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
rowElement.style.opacity = '0';
rowElement.style.transform = 'translateX(-20px)';
}
// 更新API路径
const response = await apiRequest('/shield', 'DELETE', { rule });
// 处理不同的响应格式
if (response.success || response.status === 'success') {
// 在原规则列表中找到并删除
const originalIndex = rules.indexOf(rule);
if (originalIndex !== -1) {
@@ -207,13 +268,35 @@ async function deleteRule(index) {
currentPage = totalPages;
}
renderRulesList();
showNotification('规则删除成功', 'success');
// 等待动画完成后重新渲染列表
setTimeout(() => {
renderRulesList();
// 更新规则数量统计
if (window.updateRulesCount && typeof window.updateRulesCount === 'function') {
window.updateRulesCount(rules.length);
}
if (typeof window.showNotification === 'function') {
window.showNotification('规则删除成功', 'success');
}
}, 300);
} else {
showNotification('规则删除失败:' + (response.message || '未知错误'), 'error');
// 恢复行样式
if (rowElement) {
rowElement.style.opacity = '1';
rowElement.style.transform = 'translateX(0)';
}
if (typeof window.showNotification === 'function') {
window.showNotification('规则删除失败:' + (response.message || '未知错误'), 'danger');
}
}
} catch (error) {
showError('删除规则失败' + error.message);
console.error('删除规则失败:', error);
if (typeof window.showNotification === 'function') {
window.showNotification('删除规则失败', 'danger');
}
}
}
@@ -227,13 +310,25 @@ async function reloadRules() {
const rulesPanel = document.getElementById('rules-panel');
showLoading(rulesPanel);
await apiRequest('/shield/reload', 'POST');
// 确保使用正确的API路径
await apiRequest('/shield/refresh', 'POST');
// 重新加载规则列表
await loadRules();
showNotification('规则重新加载成功', 'success');
// 触发数据刷新事件,通知其他模块数据已更新
if (typeof window.triggerDataRefresh === 'function') {
window.triggerDataRefresh('rules');
}
if (typeof window.showNotification === 'function') {
window.showNotification('规则重新加载成功', 'success');
}
} catch (error) {
showError('重新加载规则失败' + error.message);
console.error('重新加载规则失败:', error);
if (typeof window.showNotification === 'function') {
window.showNotification('重新加载规则失败', 'danger');
}
} finally {
const rulesPanel = document.getElementById('rules-panel');
hideLoading(rulesPanel);
@@ -263,8 +358,56 @@ function escapeHtml(text) {
'"': '&quot;',
"'": '&#039;'
};
return text.replace(/[&<>"']/g, m => map[m]);
return text.replace(/[&<>'"]/g, m => map[m]);
}
// 根据规则类型返回对应的CSS类名
function getRuleTypeClass(rule) {
// 简单的规则类型判断
if (rule.startsWith('||') || rule.startsWith('|http')) {
return 'rule-type-url';
} else if (rule.startsWith('@@')) {
return 'rule-type-exception';
} else if (rule.startsWith('#')) {
return 'rule-type-comment';
} else if (rule.includes('$')) {
return 'rule-type-filter';
}
return 'rule-type-standard';
}
// 预处理规则,支持多种规则格式
function preprocessRule(rule) {
// 移除首尾空白字符
let processed = rule.trim();
// 处理AdGuardHome格式的规则
if (processed.startsWith('0.0.0.0 ') || processed.startsWith('127.0.0.1 ')) {
const parts = processed.split(' ');
if (parts.length >= 2) {
// 转换为AdBlock Plus格式
processed = '||' + parts[1] + '^';
}
}
return processed;
}
// 导出函数,供其他模块调用
window.updateRulesCount = function(count) {
const rulesCountElement = document.getElementById('rules-count');
if (rulesCountElement) {
rulesCountElement.textContent = count;
}
}
// 导出初始化函数
window.initRulesPanel = initRulesPanel;
window.initRulesPanel = initRulesPanel;
// 注册到面板导航系统
if (window.registerPanelModule) {
window.registerPanelModule('rules-panel', {
init: initRulesPanel,
refresh: loadRules
});
}