屏蔽规则页面丰富显示
This commit is contained in:
@@ -12,16 +12,115 @@ async function initShieldPage() {
|
||||
setupShieldEventListeners();
|
||||
}
|
||||
|
||||
// 更新状态显示函数
|
||||
function updateStatus(url, status, message) {
|
||||
const statusElement = document.getElementById(`update-status-${encodeURIComponent(url)}`);
|
||||
if (!statusElement) return;
|
||||
|
||||
let statusHTML = '';
|
||||
|
||||
switch (status) {
|
||||
case 'loading':
|
||||
statusHTML = '<span class="text-blue-500"><i class="fa fa-spinner fa-spin"></i> 处理中...</span>';
|
||||
break;
|
||||
case 'success':
|
||||
statusHTML = `<span class="text-green-500"><i class="fa fa-check"></i> ${message || '成功'}</span>`;
|
||||
break;
|
||||
case 'error':
|
||||
statusHTML = `<span class="text-red-500"><i class="fa fa-times"></i> ${message || '失败'}</span>`;
|
||||
break;
|
||||
default:
|
||||
statusHTML = '<span class="text-gray-400">-</span>';
|
||||
}
|
||||
|
||||
statusElement.innerHTML = statusHTML;
|
||||
|
||||
// 如果是成功或失败状态,3秒后恢复默认状态
|
||||
if (status === 'success' || status === 'error') {
|
||||
setTimeout(() => {
|
||||
updateStatus(url, 'default');
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
// 数字更新动画函数
|
||||
function animateCounter(element, target, duration = 1000) {
|
||||
// 确保element存在
|
||||
if (!element) return;
|
||||
|
||||
// 清除元素上可能存在的现有定时器
|
||||
if (element.animationTimer) {
|
||||
clearInterval(element.animationTimer);
|
||||
}
|
||||
|
||||
// 确保target是数字
|
||||
const targetNum = typeof target === 'number' ? target : parseInt(target) || 0;
|
||||
|
||||
// 获取起始值,使用更安全的方法
|
||||
const startText = element.textContent.replace(/[^0-9]/g, '');
|
||||
const start = parseInt(startText) || 0;
|
||||
|
||||
// 如果起始值和目标值相同,直接返回
|
||||
if (start === targetNum) {
|
||||
element.textContent = targetNum;
|
||||
return;
|
||||
}
|
||||
|
||||
let current = start;
|
||||
const increment = (targetNum - start) / (duration / 16); // 16ms per frame
|
||||
|
||||
// 使用requestAnimationFrame实现更平滑的动画
|
||||
let startTime = null;
|
||||
|
||||
function updateCounter(timestamp) {
|
||||
if (!startTime) startTime = timestamp;
|
||||
const elapsed = timestamp - startTime;
|
||||
const progress = Math.min(elapsed / duration, 1);
|
||||
|
||||
// 使用缓动函数使动画更自然
|
||||
const easeOutQuad = progress * (2 - progress);
|
||||
current = start + (targetNum - start) * easeOutQuad;
|
||||
|
||||
// 根据方向使用floor或ceil确保平滑过渡
|
||||
const displayValue = targetNum > start ? Math.floor(current) : Math.ceil(current);
|
||||
element.textContent = displayValue;
|
||||
|
||||
if (progress < 1) {
|
||||
// 继续动画
|
||||
element.animationTimer = requestAnimationFrame(updateCounter);
|
||||
} else {
|
||||
// 动画结束,确保显示准确值
|
||||
element.textContent = targetNum;
|
||||
// 清除定时器引用
|
||||
element.animationTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 开始动画
|
||||
element.animationTimer = requestAnimationFrame(updateCounter);
|
||||
}
|
||||
|
||||
// 加载屏蔽规则统计信息
|
||||
async function loadShieldStats() {
|
||||
try {
|
||||
const response = await fetch('/api/shield');
|
||||
// 获取屏蔽规则统计信息
|
||||
const shieldResponse = await fetch('/api/shield');
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`加载失败: ${response.status}`);
|
||||
if (!shieldResponse.ok) {
|
||||
throw new Error(`加载屏蔽统计失败: ${shieldResponse.status}`);
|
||||
}
|
||||
|
||||
const stats = await response.json();
|
||||
const stats = await shieldResponse.json();
|
||||
|
||||
// 获取黑名单列表,计算禁用数量
|
||||
const blacklistsResponse = await fetch('/api/shield/blacklists');
|
||||
|
||||
if (!blacklistsResponse.ok) {
|
||||
throw new Error(`加载黑名单列表失败: ${blacklistsResponse.status}`);
|
||||
}
|
||||
|
||||
const blacklists = await blacklistsResponse.json();
|
||||
const disabledBlacklistCount = blacklists.filter(blacklist => !blacklist.enabled).length;
|
||||
|
||||
// 更新统计信息
|
||||
const elements = [
|
||||
@@ -36,12 +135,18 @@ async function loadShieldStats() {
|
||||
elements.forEach(item => {
|
||||
const element = document.getElementById(item.id);
|
||||
if (element) {
|
||||
element.textContent = item.value || 0;
|
||||
animateCounter(element, item.value || 0);
|
||||
}
|
||||
});
|
||||
|
||||
// 更新禁用黑名单数量
|
||||
const disabledBlacklistElement = document.getElementById('blacklist-disabled-count');
|
||||
if (disabledBlacklistElement) {
|
||||
animateCounter(disabledBlacklistElement, disabledBlacklistCount);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载屏蔽规则统计信息失败:', error);
|
||||
showErrorMessage('加载屏蔽规则统计信息失败');
|
||||
showNotification('加载屏蔽规则统计信息失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +191,7 @@ async function loadLocalRules() {
|
||||
updateRulesTable(rules);
|
||||
} catch (error) {
|
||||
console.error('加载本地规则失败:', error);
|
||||
showErrorMessage('加载本地规则失败');
|
||||
showNotification('加载本地规则失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +235,7 @@ async function loadRemoteRules() {
|
||||
updateRulesTable(rules);
|
||||
} catch (error) {
|
||||
console.error('加载远程规则失败:', error);
|
||||
showErrorMessage('加载远程规则失败');
|
||||
showNotification('加载远程规则失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +356,7 @@ async function handleDeleteRule(e) {
|
||||
const responseData = await response.json();
|
||||
console.log('Response data:', responseData);
|
||||
|
||||
showSuccessMessage('规则删除成功');
|
||||
showNotification('规则删除成功', 'success');
|
||||
console.log('Current rules type:', currentRulesType);
|
||||
// 根据当前显示的规则类型重新加载对应的规则列表
|
||||
if (currentRulesType === 'local') {
|
||||
@@ -265,7 +370,7 @@ async function handleDeleteRule(e) {
|
||||
loadShieldStats();
|
||||
} catch (error) {
|
||||
console.error('Error deleting rule:', error);
|
||||
showErrorMessage('删除规则失败: ' + error.message);
|
||||
showNotification('删除规则失败: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +378,7 @@ async function handleDeleteRule(e) {
|
||||
async function handleAddRule() {
|
||||
const rule = document.getElementById('new-rule').value.trim();
|
||||
if (!rule) {
|
||||
showErrorMessage('规则不能为空');
|
||||
showNotification('规则不能为空', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -290,7 +395,7 @@ async function handleAddRule() {
|
||||
throw new Error('Failed to add rule');
|
||||
}
|
||||
|
||||
showSuccessMessage('规则添加成功');
|
||||
showNotification('规则添加成功', 'success');
|
||||
// 清空输入框
|
||||
document.getElementById('new-rule').value = '';
|
||||
// 重新加载规则
|
||||
@@ -299,7 +404,7 @@ async function handleAddRule() {
|
||||
loadShieldStats();
|
||||
} catch (error) {
|
||||
console.error('Error adding rule:', error);
|
||||
showErrorMessage('添加规则失败');
|
||||
showNotification('添加规则失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,7 +424,7 @@ async function loadRemoteBlacklists() {
|
||||
updateBlacklistsTable(blacklistArray);
|
||||
} catch (error) {
|
||||
console.error('加载远程黑名单失败:', error);
|
||||
showErrorMessage('加载远程黑名单失败');
|
||||
showNotification('加载远程黑名单失败', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,30 +470,24 @@ function updateBlacklistsTable(blacklists) {
|
||||
// 名称单元格
|
||||
const tdName = document.createElement('td');
|
||||
tdName.className = 'py-3 px-4';
|
||||
tdName.textContent = blacklist.Name || '未命名';
|
||||
tdName.textContent = blacklist.name || '未命名';
|
||||
|
||||
// URL单元格
|
||||
const tdUrl = document.createElement('td');
|
||||
tdUrl.className = 'py-3 px-4 truncate max-w-xs';
|
||||
tdUrl.textContent = blacklist.URL;
|
||||
tdUrl.textContent = blacklist.url;
|
||||
|
||||
// 状态单元格
|
||||
const tdStatus = document.createElement('td');
|
||||
tdStatus.className = 'py-3 px-4 text-center';
|
||||
|
||||
// 判断状态颜色:绿色(正常)、黄色(过期)、灰色(禁用)
|
||||
// 判断状态颜色:绿色(启用)、灰色(禁用)
|
||||
let statusColor = 'bg-gray-300'; // 默认禁用
|
||||
let statusText = '禁用';
|
||||
|
||||
if (blacklist.Enabled) {
|
||||
const expired = isBlacklistExpired(blacklist.lastUpdateTime || blacklist.LastUpdateTime);
|
||||
if (expired) {
|
||||
statusColor = 'bg-warning'; // 黄色表示过期
|
||||
statusText = '过期';
|
||||
} else {
|
||||
statusColor = 'bg-success'; // 绿色表示正常
|
||||
statusText = '正常';
|
||||
}
|
||||
if (blacklist.enabled) {
|
||||
statusColor = 'bg-success'; // 绿色表示启用
|
||||
statusText = '启用';
|
||||
}
|
||||
|
||||
const statusContainer = document.createElement('div');
|
||||
@@ -406,14 +505,29 @@ function updateBlacklistsTable(blacklists) {
|
||||
statusContainer.appendChild(statusTextSpan);
|
||||
tdStatus.appendChild(statusContainer);
|
||||
|
||||
// 更新状态单元格
|
||||
const tdUpdateStatus = document.createElement('td');
|
||||
tdUpdateStatus.className = 'py-3 px-4 text-center';
|
||||
tdUpdateStatus.id = `update-status-${encodeURIComponent(blacklist.url)}`;
|
||||
tdUpdateStatus.innerHTML = '<span class="text-gray-400">-</span>';
|
||||
|
||||
// 操作单元格
|
||||
const tdActions = document.createElement('td');
|
||||
tdActions.className = 'py-3 px-4 text-right space-x-2';
|
||||
|
||||
// 启用/禁用按钮
|
||||
const toggleBtn = document.createElement('button');
|
||||
toggleBtn.className = `toggle-blacklist-btn px-3 py-1 rounded-md transition-colors text-sm ${blacklist.enabled ? 'bg-warning text-white hover:bg-warning/90' : 'bg-success text-white hover:bg-success/90'}`;
|
||||
toggleBtn.dataset.url = blacklist.url;
|
||||
toggleBtn.dataset.enabled = blacklist.enabled;
|
||||
toggleBtn.innerHTML = `<i class="fa fa-${blacklist.enabled ? 'toggle-on' : 'toggle-off'}"></i>`;
|
||||
toggleBtn.title = blacklist.enabled ? '禁用黑名单' : '启用黑名单';
|
||||
toggleBtn.addEventListener('click', handleToggleBlacklist);
|
||||
|
||||
// 刷新按钮
|
||||
const refreshBtn = document.createElement('button');
|
||||
refreshBtn.className = 'update-blacklist-btn px-3 py-1 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors text-sm';
|
||||
refreshBtn.dataset.url = blacklist.URL;
|
||||
refreshBtn.dataset.url = blacklist.url;
|
||||
refreshBtn.innerHTML = '<i class="fa fa-refresh"></i>';
|
||||
refreshBtn.title = '刷新黑名单';
|
||||
refreshBtn.addEventListener('click', handleUpdateBlacklist);
|
||||
@@ -421,17 +535,19 @@ function updateBlacklistsTable(blacklists) {
|
||||
// 删除按钮
|
||||
const deleteBtn = document.createElement('button');
|
||||
deleteBtn.className = 'delete-blacklist-btn px-3 py-1 bg-danger text-white rounded-md hover:bg-danger/90 transition-colors text-sm';
|
||||
deleteBtn.dataset.url = blacklist.URL;
|
||||
deleteBtn.dataset.url = blacklist.url;
|
||||
deleteBtn.innerHTML = '<i class="fa fa-trash"></i>';
|
||||
deleteBtn.title = '删除黑名单';
|
||||
deleteBtn.addEventListener('click', handleDeleteBlacklist);
|
||||
|
||||
tdActions.appendChild(toggleBtn);
|
||||
tdActions.appendChild(refreshBtn);
|
||||
tdActions.appendChild(deleteBtn);
|
||||
|
||||
tr.appendChild(tdName);
|
||||
tr.appendChild(tdUrl);
|
||||
tr.appendChild(tdStatus);
|
||||
tr.appendChild(tdUpdateStatus);
|
||||
tr.appendChild(tdActions);
|
||||
fragment.appendChild(tr);
|
||||
});
|
||||
@@ -449,43 +565,93 @@ function updateBlacklistsTable(blacklists) {
|
||||
|
||||
// 处理更新单个黑名单
|
||||
async function handleUpdateBlacklist(e) {
|
||||
const url = e.target.closest('.update-blacklist-btn').dataset.url;
|
||||
// 确保获取到正确的按钮元素
|
||||
const btn = e.target.closest('.update-blacklist-btn');
|
||||
if (!btn) {
|
||||
console.error('未找到更新按钮元素');
|
||||
return;
|
||||
}
|
||||
|
||||
const url = btn.dataset.url;
|
||||
|
||||
if (!url) {
|
||||
showToast('无效的黑名单URL', 'error');
|
||||
showNotification('无效的黑名单URL', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/shield/blacklists/${encodeURIComponent(url)}/update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
// 显示加载状态
|
||||
updateStatus(url, 'loading');
|
||||
|
||||
// 获取当前所有黑名单
|
||||
const response = await fetch('/api/shield/blacklists');
|
||||
if (!response.ok) {
|
||||
throw new Error(`获取黑名单失败: ${response.status}`);
|
||||
}
|
||||
|
||||
const blacklists = await response.json();
|
||||
|
||||
// 找到目标黑名单并更新其状态
|
||||
const updatedBlacklists = blacklists.map(blacklist => {
|
||||
if (blacklist.url === url) {
|
||||
return {
|
||||
Name: blacklist.name,
|
||||
URL: blacklist.url,
|
||||
Enabled: blacklist.enabled,
|
||||
LastUpdateTime: new Date().toISOString()
|
||||
};
|
||||
}
|
||||
return {
|
||||
Name: blacklist.name,
|
||||
URL: blacklist.url,
|
||||
Enabled: blacklist.enabled,
|
||||
LastUpdateTime: blacklist.lastUpdateTime || blacklist.LastUpdateTime
|
||||
};
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.error || 'Failed to update blacklist');
|
||||
// 发送更新请求
|
||||
const updateResponse = await fetch('/api/shield/blacklists', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(updatedBlacklists)
|
||||
});
|
||||
|
||||
if (!updateResponse.ok) {
|
||||
const errorText = await updateResponse.text();
|
||||
throw new Error(`更新失败: ${updateResponse.status} ${errorText}`);
|
||||
}
|
||||
|
||||
// 显示成功状态
|
||||
updateStatus(url, 'success');
|
||||
|
||||
// 重新加载黑名单
|
||||
loadRemoteBlacklists();
|
||||
// 重新加载统计信息
|
||||
loadShieldStats();
|
||||
showToast('黑名单更新成功');
|
||||
showNotification('黑名单更新成功', 'success');
|
||||
} catch (error) {
|
||||
console.error('更新黑名单失败:', error);
|
||||
showToast('更新黑名单失败: ' + error.message, 'error');
|
||||
// 显示错误状态
|
||||
updateStatus(url, 'error', error.message);
|
||||
showNotification('更新黑名单失败: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 处理删除黑名单
|
||||
async function handleDeleteBlacklist(e) {
|
||||
const url = e.target.closest('.delete-blacklist-btn').dataset.url;
|
||||
// 确保获取到正确的按钮元素
|
||||
const btn = e.target.closest('.delete-blacklist-btn');
|
||||
if (!btn) {
|
||||
console.error('未找到删除按钮元素');
|
||||
return;
|
||||
}
|
||||
|
||||
const url = btn.dataset.url;
|
||||
|
||||
if (!url) {
|
||||
showToast('无效的黑名单URL', 'error');
|
||||
showNotification('无效的黑名单URL', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -495,26 +661,124 @@ async function handleDeleteBlacklist(e) {
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/shield/blacklists/${encodeURIComponent(url)}`, {
|
||||
method: 'DELETE',
|
||||
// 显示加载状态
|
||||
updateStatus(url, 'loading');
|
||||
|
||||
// 获取当前所有黑名单
|
||||
const response = await fetch('/api/shield/blacklists');
|
||||
if (!response.ok) {
|
||||
throw new Error(`获取黑名单失败: ${response.status}`);
|
||||
}
|
||||
|
||||
const blacklists = await response.json();
|
||||
|
||||
// 过滤掉要删除的黑名单
|
||||
const updatedBlacklists = blacklists.filter(blacklist => blacklist.url !== url);
|
||||
|
||||
// 发送更新请求
|
||||
const updateResponse = await fetch('/api/shield/blacklists', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
},
|
||||
body: JSON.stringify(updatedBlacklists)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.error || 'Failed to delete blacklist');
|
||||
if (!updateResponse.ok) {
|
||||
const errorText = await updateResponse.text();
|
||||
throw new Error(`删除失败: ${updateResponse.status} ${errorText}`);
|
||||
}
|
||||
|
||||
// 显示成功状态
|
||||
updateStatus(url, 'success', '已删除');
|
||||
|
||||
// 重新加载黑名单
|
||||
loadRemoteBlacklists();
|
||||
// 重新加载统计信息
|
||||
loadShieldStats();
|
||||
showToast('黑名单删除成功');
|
||||
showNotification('黑名单删除成功', 'success');
|
||||
} catch (error) {
|
||||
console.error('删除黑名单失败:', error);
|
||||
showToast('删除黑名单失败: ' + error.message, 'error');
|
||||
// 显示错误状态
|
||||
updateStatus(url, 'error', error.message);
|
||||
showNotification('删除黑名单失败: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 处理启用/禁用黑名单
|
||||
async function handleToggleBlacklist(e) {
|
||||
// 确保获取到正确的按钮元素
|
||||
const btn = e.target.closest('.toggle-blacklist-btn');
|
||||
if (!btn) {
|
||||
console.error('未找到启用/禁用按钮元素');
|
||||
return;
|
||||
}
|
||||
|
||||
const url = btn.dataset.url;
|
||||
const currentEnabled = btn.dataset.enabled === 'true';
|
||||
|
||||
if (!url) {
|
||||
showNotification('无效的黑名单URL', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 显示加载状态
|
||||
updateStatus(url, 'loading');
|
||||
|
||||
// 获取当前所有黑名单
|
||||
const response = await fetch('/api/shield/blacklists');
|
||||
if (!response.ok) {
|
||||
throw new Error(`获取黑名单失败: ${response.status}`);
|
||||
}
|
||||
|
||||
const blacklists = await response.json();
|
||||
|
||||
// 找到目标黑名单并更新其状态
|
||||
const updatedBlacklists = blacklists.map(blacklist => {
|
||||
if (blacklist.url === url) {
|
||||
return {
|
||||
Name: blacklist.name,
|
||||
URL: blacklist.url,
|
||||
Enabled: !currentEnabled,
|
||||
LastUpdateTime: blacklist.lastUpdateTime || blacklist.LastUpdateTime
|
||||
};
|
||||
}
|
||||
return {
|
||||
Name: blacklist.name,
|
||||
URL: blacklist.url,
|
||||
Enabled: blacklist.enabled,
|
||||
LastUpdateTime: blacklist.lastUpdateTime || blacklist.LastUpdateTime
|
||||
};
|
||||
});
|
||||
|
||||
// 发送更新请求
|
||||
const updateResponse = await fetch('/api/shield/blacklists', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(updatedBlacklists)
|
||||
});
|
||||
|
||||
if (!updateResponse.ok) {
|
||||
const errorText = await updateResponse.text();
|
||||
throw new Error(`更新状态失败: ${updateResponse.status} ${errorText}`);
|
||||
}
|
||||
|
||||
// 显示成功状态
|
||||
updateStatus(url, 'success', currentEnabled ? '已禁用' : '已启用');
|
||||
|
||||
// 重新加载黑名单
|
||||
loadRemoteBlacklists();
|
||||
// 重新加载统计信息
|
||||
loadShieldStats();
|
||||
showNotification(`黑名单已${currentEnabled ? '禁用' : '启用'}`, 'success');
|
||||
} catch (error) {
|
||||
console.error('启用/禁用黑名单失败:', error);
|
||||
// 显示错误状态
|
||||
updateStatus(url, 'error', error.message);
|
||||
showNotification('启用/禁用黑名单失败: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,13 +791,14 @@ async function handleAddBlacklist(event) {
|
||||
|
||||
const nameInput = document.getElementById('blacklist-name');
|
||||
const urlInput = document.getElementById('blacklist-url');
|
||||
const statusElement = document.getElementById('save-blacklist-status');
|
||||
|
||||
const name = nameInput ? nameInput.value.trim() : '';
|
||||
const url = urlInput ? urlInput.value.trim() : '';
|
||||
|
||||
// 简单验证
|
||||
if (!name || !url) {
|
||||
showErrorMessage('名称和URL不能为空');
|
||||
showNotification('名称和URL不能为空', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -541,11 +806,15 @@ async function handleAddBlacklist(event) {
|
||||
try {
|
||||
new URL(url);
|
||||
} catch (e) {
|
||||
showErrorMessage('URL格式不正确');
|
||||
showNotification('URL格式不正确', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 显示加载状态
|
||||
statusElement.innerHTML = '<i class="fa fa-spinner fa-spin text-blue-500"></i> 正在添加...';
|
||||
|
||||
// 发送添加请求
|
||||
const response = await fetch('/api/shield/blacklists', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -568,7 +837,10 @@ async function handleAddBlacklist(event) {
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
showSuccessMessage('黑名单添加成功');
|
||||
// 显示成功状态
|
||||
statusElement.innerHTML = '<span class="text-green-500"><i class="fa fa-check"></i> 成功</span>';
|
||||
|
||||
showNotification('黑名单添加成功', 'success');
|
||||
// 清空输入框
|
||||
if (nameInput) nameInput.value = '';
|
||||
if (urlInput) urlInput.value = '';
|
||||
@@ -578,7 +850,14 @@ async function handleAddBlacklist(event) {
|
||||
loadShieldStats();
|
||||
} catch (error) {
|
||||
console.error('Error adding blacklist:', error);
|
||||
showErrorMessage(error.message || '添加黑名单失败');
|
||||
// 显示错误状态
|
||||
statusElement.innerHTML = `<span class="text-red-500"><i class="fa fa-times"></i> 失败</span>`;
|
||||
showNotification(error.message || '添加黑名单失败', 'error');
|
||||
} finally {
|
||||
// 3秒后清除状态显示
|
||||
setTimeout(() => {
|
||||
statusElement.innerHTML = '';
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user