203 lines
5.4 KiB
JavaScript
203 lines
5.4 KiB
JavaScript
// Hosts管理页面功能实现
|
|
|
|
// 初始化Hosts管理页面
|
|
function initHostsPage() {
|
|
// 加载Hosts规则
|
|
loadHostsRules();
|
|
// 设置事件监听器
|
|
setupHostsEventListeners();
|
|
}
|
|
|
|
// 加载Hosts规则
|
|
async function loadHostsRules() {
|
|
try {
|
|
const response = await fetch('/api/shield/hosts');
|
|
if (!response.ok) {
|
|
throw new Error('Failed to load hosts rules');
|
|
}
|
|
const data = await response.json();
|
|
|
|
// 处理API返回的数据格式
|
|
let hostsRules = [];
|
|
if (data && Array.isArray(data)) {
|
|
// 直接是数组格式
|
|
hostsRules = data;
|
|
} else if (data && data.hosts) {
|
|
// 包含在hosts字段中
|
|
hostsRules = data.hosts;
|
|
}
|
|
|
|
updateHostsTable(hostsRules);
|
|
} catch (error) {
|
|
console.error('Error loading hosts rules:', error);
|
|
showErrorMessage('加载Hosts规则失败');
|
|
}
|
|
}
|
|
|
|
// 更新Hosts表格
|
|
function updateHostsTable(hostsRules) {
|
|
const tbody = document.getElementById('hosts-table-body');
|
|
|
|
if (hostsRules.length === 0) {
|
|
tbody.innerHTML = '<tr><td colspan="3" class="py-4 text-center text-gray-500">暂无Hosts条目</td></tr>';
|
|
return;
|
|
}
|
|
|
|
tbody.innerHTML = hostsRules.map(rule => {
|
|
// 处理对象格式的规则
|
|
const ip = rule.ip || '';
|
|
const domain = rule.domain || '';
|
|
|
|
return `
|
|
<tr class="border-b border-gray-200">
|
|
<td class="py-3 px-4">${ip}</td>
|
|
<td class="py-3 px-4">${domain}</td>
|
|
<td class="py-3 px-4 text-right">
|
|
<button class="delete-hosts-btn px-3 py-1 bg-danger text-white rounded-md hover:bg-danger/90 transition-colors text-sm" data-ip="${ip}" data-domain="${domain}">
|
|
<i class="fa fa-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
}).join('');
|
|
|
|
// 重新绑定删除事件
|
|
document.querySelectorAll('.delete-hosts-btn').forEach(btn => {
|
|
btn.addEventListener('click', handleDeleteHostsRule);
|
|
});
|
|
}
|
|
|
|
// 设置事件监听器
|
|
function setupHostsEventListeners() {
|
|
// 保存Hosts按钮
|
|
document.getElementById('save-hosts-btn').addEventListener('click', handleAddHostsRule);
|
|
}
|
|
|
|
// 处理添加Hosts规则
|
|
async function handleAddHostsRule() {
|
|
const ip = document.getElementById('hosts-ip').value.trim();
|
|
const domain = document.getElementById('hosts-domain').value.trim();
|
|
|
|
if (!ip || !domain) {
|
|
showErrorMessage('IP地址和域名不能为空');
|
|
return;
|
|
}
|
|
|
|
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 rule');
|
|
}
|
|
|
|
showSuccessMessage('Hosts规则添加成功');
|
|
|
|
// 清空输入框
|
|
document.getElementById('hosts-ip').value = '';
|
|
document.getElementById('hosts-domain').value = '';
|
|
|
|
// 重新加载规则
|
|
loadHostsRules();
|
|
} catch (error) {
|
|
console.error('Error adding hosts rule:', error);
|
|
showErrorMessage('添加Hosts规则失败');
|
|
}
|
|
}
|
|
|
|
// 处理删除Hosts规则
|
|
async function handleDeleteHostsRule(e) {
|
|
const ip = e.target.closest('.delete-hosts-btn').dataset.ip;
|
|
const domain = e.target.closest('.delete-hosts-btn').dataset.domain;
|
|
|
|
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 rule');
|
|
}
|
|
|
|
showSuccessMessage('Hosts规则删除成功');
|
|
|
|
// 重新加载规则
|
|
loadHostsRules();
|
|
} catch (error) {
|
|
console.error('Error deleting hosts rule:', error);
|
|
showErrorMessage('删除Hosts规则失败');
|
|
}
|
|
}
|
|
|
|
// 显示成功消息
|
|
function showSuccessMessage(message) {
|
|
showNotification(message, 'success');
|
|
}
|
|
|
|
// 显示错误消息
|
|
function showErrorMessage(message) {
|
|
showNotification(message, 'error');
|
|
}
|
|
|
|
|
|
|
|
// 显示通知
|
|
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 = `
|
|
<div class="flex items-center space-x-2">
|
|
<i class="fa fa-${type === 'success' ? 'check' : type === 'error' ? 'exclamation' : 'info'}"></i>
|
|
<span>${message}</span>
|
|
</div>
|
|
`;
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
// 显示通知
|
|
setTimeout(() => {
|
|
notification.classList.remove('opacity-0');
|
|
}, 100);
|
|
|
|
// 3秒后隐藏通知
|
|
setTimeout(() => {
|
|
notification.classList.add('opacity-0');
|
|
setTimeout(() => {
|
|
notification.remove();
|
|
}, 300);
|
|
}, 3000);
|
|
}
|
|
|
|
// 页面加载完成后初始化
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', initHostsPage);
|
|
} else {
|
|
initHostsPage();
|
|
}
|