web重做

This commit is contained in:
Alex Yang
2025-11-24 01:53:26 +08:00
parent f499a4a84a
commit 85320611cb
17 changed files with 4936 additions and 2346 deletions

180
static/js/modules/hosts.js Normal file
View File

@@ -0,0 +1,180 @@
// 初始化Hosts面板
function initHostsPanel() {
// 加载Hosts列表
loadHosts();
// 初始化事件监听器
initHostsEventListeners();
}
// 初始化事件监听器
function initHostsEventListeners() {
// 添加Hosts按钮
document.getElementById('add-hosts').addEventListener('click', addHostsEntry);
// Hosts过滤
document.getElementById('hosts-filter').addEventListener('input', filterHosts);
// 按Enter键添加Hosts
document.getElementById('hosts-domain').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
addHostsEntry();
}
});
}
// 加载Hosts列表
function loadHosts() {
const tbody = document.getElementById('hosts-table').querySelector('tbody');
showLoading(tbody);
apiRequest('/shield/hosts', 'GET')
.then(data => {
renderHosts(data);
})
.catch(error => {
console.error('获取Hosts列表失败:', error);
showError(tbody, '获取Hosts列表失败');
window.showNotification('获取Hosts列表失败', 'error');
});
}
// 渲染Hosts表格
function renderHosts(hosts) {
const tbody = document.getElementById('hosts-table').querySelector('tbody');
if (!tbody) return;
if (!hosts || hosts.length === 0) {
showEmpty(tbody, '暂无Hosts条目');
return;
}
tbody.innerHTML = '';
hosts.forEach(entry => {
addHostsToTable(entry.ip, entry.domain);
});
// 初始化表格排序
initTableSort('hosts-table');
// 初始化删除按钮监听器
initDeleteHostsListeners();
}
// 添加Hosts到表格
function addHostsToTable(ip, domain) {
const tbody = document.getElementById('hosts-table').querySelector('tbody');
const row = document.createElement('tr');
row.innerHTML = `
<td>${ip}</td>
<td>${domain}</td>
<td class="actions-cell">
<button class="btn btn-danger btn-sm delete-hosts" data-ip="${ip}" data-domain="${domain}">
<i class="fas fa-trash-alt"></i> 删除
</button>
</td>
`;
tbody.appendChild(row);
}
// 添加Hosts条目
function addHostsEntry() {
const ipInput = document.getElementById('hosts-ip');
const domainInput = document.getElementById('hosts-domain');
const ip = ipInput.value.trim();
const domain = domainInput.value.trim();
if (!ip) {
window.showNotification('请输入IP地址', 'warning');
ipInput.focus();
return;
}
if (!domain) {
window.showNotification('请输入域名', 'warning');
domainInput.focus();
return;
}
// 简单的IP地址格式验证
if (!isValidIp(ip)) {
window.showNotification('请输入有效的IP地址', 'warning');
ipInput.focus();
return;
}
apiRequest('/shield/hosts', 'POST', { ip: ip, domain: domain });
apiRequest('/shield/hosts', 'POST', { ip: ip, domain: domain })
.then(data => {
if (data.success) {
window.showNotification('Hosts条目添加成功', 'success');
ipInput.value = '';
domainInput.value = '';
loadHosts();
} else {
window.showNotification(`添加失败: ${data.message || '未知错误'}`, 'error');
}
})
.catch(error => {
console.error('添加Hosts条目失败:', error);
window.showNotification('添加Hosts条目失败', 'error');
});
}
// 删除Hosts条目
function deleteHostsEntry(ip, domain) {
apiRequest('/shield/hosts', 'DELETE', { ip: ip, domain: domain })
.then(data => {
if (data.success) {
window.showNotification('Hosts条目删除成功', 'success');
loadHosts();
} else {
window.showNotification(`删除失败: ${data.message || '未知错误'}`, 'error');
}
})
.catch(error => {
console.error('删除Hosts条目失败:', error);
window.showNotification('删除Hosts条目失败', 'error');
});
}
// 过滤Hosts
function filterHosts() {
const filterText = document.getElementById('hosts-filter').value.toLowerCase();
const rows = document.querySelectorAll('#hosts-table tbody tr');
rows.forEach(row => {
const ip = row.cells[0].textContent.toLowerCase();
const domain = row.cells[1].textContent.toLowerCase();
row.style.display = (ip.includes(filterText) || domain.includes(filterText)) ? '' : 'none';
});
}
// 为删除按钮添加事件监听器
function initDeleteHostsListeners() {
document.querySelectorAll('.delete-hosts').forEach(button => {
button.addEventListener('click', function() {
const ip = this.getAttribute('data-ip');
const domain = this.getAttribute('data-domain');
confirmAction(
`确定要删除这条Hosts条目吗\n${ip} ${domain}`,
() => deleteHostsEntry(ip, domain)
);
});
});
}
// 验证IP地址格式
function isValidIp(ip) {
// 支持IPv4和IPv6简单验证
const ipv4Regex = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/;
const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}$/;
return ipv4Regex.test(ip) || ipv6Regex.test(ip);
}