This commit is contained in:
Alex Yang
2026-04-12 21:40:22 +08:00
parent 7abc2b5339
commit f9e2e5a6bc
52 changed files with 3388 additions and 368846 deletions
+103
View File
@@ -0,0 +1,103 @@
[dns]
port = 53
upstreamDNS = 10.35.10.200
dnssecUpstreamDNS = 208.67.220.220, 208.67.222.222
saveInterval = 10
cacheTTL = 10
enableDNSSEC = false
queryMode = parallel
queryTimeout = 5000
enableFastReturn = true
noDNSSECDomains = amazehome.cn, addr.arpa, amazehome.xyz, .cn
enableIPv6 = false
cacheMode = file
cacheSize = 100
maxCacheTTL = 30
minCacheTTL = 5
domain_akamai = 10.35.10.200:53
domain_amazehome.cn = 10.35.10.200:53
domain_amazehome.xyz = 10.35.10.200:53
domain_microsoft.com = 10.35.10.200:53
domain_addr.arpa = 10.35.10.200:53
domain_akadns = 10.35.10.200:53
[http]
port = 8081
host = 0.0.0.0
enableAPI = true
username = admin
password = admin
[shield]
updateInterval = 3600
blockMethod = NXDOMAIN
customBlockIP = 0.0.0.2
statsSaveInterval = 60
blacklist_AdGuard_DNS_filter = https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt,true
blacklist_Adaway_Default_Blocklist = https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt,true
blacklist_CHN_anti_AD = https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt,true
blacklist_My_GitHub_Rules = https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt,true
blacklist_CNList = https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/list/china.list,false
blacklist_大圣净化 = http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/dsjh.txt,true
blacklist_Hate_and_Junk = http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/hate-and-junk-extended.txt,true
blacklist_My_Gitlab_Hosts = http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/hosts/costomize.txt,true
blacklist_Anti_Remote_Requests = http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/hosts/anti-remoterequests.txt,true
blacklist_URL_Based = http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/url-based-adguard.txt,true
blacklist_My_Gitlab_A_T_Rules = http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/ads-and-trackers.txt,true
blacklist_My_Gitlab_Malware_List = http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/malware.txt,true
blacklist_hosts = http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/costomize.txt,true
blacklist_AWAvenue_Ads_Rule = http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/rules/AWAvenue-Ads-Rule.txt,true
blacklist_诈骗域名 = https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/cheat.txt,true
[domainInfo]
updateInterval = 3600
enableAutoUpdate = true
domainInfo_域名信息列表 = https://gitea.amazehome.xyz/AMAZEHOME/domain-info/raw/branch/main/domains/domain-info.json,domain-info,true
domainInfo_威胁数据库 = https://gitea.amazehome.xyz/AMAZEHOME/domain-info/src/branch/main/threats/threats-database.csv,threat-database,true
domainInfo_跟踪器列表 = https://gitea.amazehome.xyz/AMAZEHOME/domain-info/raw/branch/main/tracker/trackers.json,tracker,true
[gfwList]
ip = 127.0.0.1
content =
enabled = false
[log]
level = debug
maxSize = 100
maxBackups = 10
maxAge = 30
[queryLog]
# 基本配置
enabled = true
ringBufferSize = 10000
# SQLite 主库配置
databasePath = data/query_logs.db
maxDatabaseSizeMB = 1024
enableWAL = true
# 归档配置
archiveEnabled = true
archiveDir = data/archive
archivePrefix = querylog
compressionLevel = 6
# 清理配置
retentionDays = 0
retentionMonths = 0
# 查询配置
queryTimeout = 5
enableCache = true
cacheTTL = 300
[threat]
enabled = true
queryRateThreshold = 0
nxDomainThreshold = 0
maxDomainLength = 0
suspiciousPatterns = malware,phishing,trojan,virus,ransomware
unusualQueryTypes = TXT,SRV,MX
alertRetentionDays = 0
threatDatabasePath = ./static/domain-info/threats/threats-database.csv
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+175 -6
View File
@@ -47,11 +47,18 @@
<span>屏蔽管理</span>
</a>
</li>
<li>
<a href="#domain-info"
class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-database mr-3 text-lg"></i>
<span>域名信息管理</span>
</a>
</li>
<li>
<a href="#hosts"
class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-file-text mr-3 text-lg"></i>
<span>Hosts管理</span>
<span>Hosts 管理</span>
</a>
</li>
<li>
@@ -146,11 +153,18 @@
<span>屏蔽管理</span>
</a>
</li>
<li>
<a href="#domain-info"
class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-database mr-3 text-lg"></i>
<span>域名信息管理</span>
</a>
</li>
<li>
<a href="#hosts"
class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-file-text mr-3 text-lg"></i>
<span>Hosts管理</span>
<span>Hosts 管理</span>
</a>
</li>
<li>
@@ -730,6 +744,164 @@
<!-- 添加域名信息列表模态框 -->
<div id="add-domain-info-modal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-lg w-full max-w-md p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold">添加域名信息列表</h3>
<button onclick="window.domainInfo.hideAddListModal()"
class="p-2 rounded-full hover:bg-gray-100 transition-colors">
<i class="fa fa-times"></i>
</button>
</div>
<form id="add-domain-info-form">
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">名称</label>
<input type="text" id="list-name" required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">URL</label>
<input type="url" id="list-url" required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">类型</label>
<select id="list-type" required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
<option value="domain-info">域名信息</option>
<option value="threat-database">威胁数据库</option>
<option value="tracker">跟踪器</option>
</select>
</div>
<div>
<label class="flex items-center space-x-2">
<input type="checkbox" id="list-enabled" checked
class="rounded border-gray-300 text-primary focus:ring-primary">
<span class="text-sm text-gray-700">启用</span>
</label>
</div>
</div>
<div class="mt-6 flex space-x-3">
<button type="button" onclick="window.domainInfo.hideAddListModal()"
class="px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50 transition-colors text-sm flex-1">
取消
</button>
<button type="submit"
class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors text-sm flex-1">
添加
</button>
</div>
</form>
</div>
</div>
<!-- 域名信息管理页面内容(初始隐藏) -->
<div id="domain-info-content" class="hidden space-y-6">
<!-- 域名信息统计卡片 -->
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 sm:gap-6">
<!-- 域名信息数量卡片 -->
<div class="bg-blue-50 rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-primary opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">域名信息数量</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-primary/10 text-primary">
<i class="fa fa-database text-xs sm:text-sm"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="domain-info-count">0</p>
</div>
</div>
</div>
</div>
<!-- 威胁域名数量卡片 -->
<div class="bg-red-50 rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-danger opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">威胁域名数量</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-danger/10 text-danger">
<i class="fa fa-exclamation-triangle text-xs sm:text-sm"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="threat-count">0</p>
</div>
</div>
</div>
</div>
<!-- 跟踪器数量卡片 -->
<div class="bg-purple-50 rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-purple-500 opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">跟踪器数量</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-purple-500/10 text-purple-500">
<i class="fa fa-bullseye text-xs sm:text-sm"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="tracker-count">0</p>
</div>
</div>
</div>
</div>
</div>
<!-- 域名信息列表管理 -->
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-4 sm:mb-6">
<h3 class="text-base sm:text-lg font-semibold mb-3 sm:mb-0">远程域名信息列表</h3>
<div class="flex space-x-2 sm:space-x-3">
<button onclick="window.domainInfo.updateAllDomainInfo()"
class="px-3 sm:px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors text-sm flex items-center">
<i class="fa fa-refresh mr-2"></i>
更新所有列表
</button>
<button onclick="window.domainInfo.showAddListModal()"
class="px-3 sm:px-4 py-2 bg-green-500 text-white rounded-md hover:bg-green-600 transition-colors text-sm flex items-center">
<i class="fa fa-plus mr-2"></i>
添加列表
</button>
</div>
</div>
<!-- 最后更新时间 -->
<div class="mb-4 text-sm text-gray-500">
<i class="fa fa-clock-o mr-2"></i>
最后更新时间:<span id="last-update-time">从未更新</span>
</div>
<!-- 域名信息列表表格 -->
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-3 sm:px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">名称</th>
<th class="px-3 sm:px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">状态</th>
<th class="px-3 sm:px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">类型</th>
<th class="px-3 sm:px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">规则数量</th>
<th class="px-3 sm:px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">最后更新</th>
<th class="px-3 sm:px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">操作</th>
</tr>
</thead>
<tbody id="domain-info-lists-table-body" class="bg-white divide-y divide-gray-200">
<!-- 动态生成 -->
</tbody>
</table>
</div>
</div>
</div>
<!-- 威胁告警页面内容(初始隐藏) -->
<div id="threats-content" class="hidden space-y-6">
<!-- 威胁统计卡片 -->
@@ -2219,16 +2391,13 @@
<script src="js/api.js"></script>
<script src="js/dashboard.js"></script>
<script src="js/shield.js"></script>
<script src="js/modules/domain-info.js"></script>
<script src="js/hosts.js"></script>
<script src="js/query.js"></script>
<script src="js/logs.js"></script>
<script src="js/config.js"></script>
<script src="js/about.js"></script>
<!-- 直接渲染滚动列表的静态HTML内容 -->
<script src="js/whois.js"></script>
<!-- 威胁告警页面脚本 -->
<script src="js/threats.js"></script>
</body>
+374
View File
@@ -0,0 +1,374 @@
// 域名信息管理模块
// 用于管理远程域名信息列表的加载、更新和显示
(function() {
'use strict';
// 域名信息列表缓存
let domainInfoCache = null;
let cacheTimestamp = 0;
const CACHE_DURATION = 5 * 60 * 1000; // 5 分钟缓存
/**
* 加载域名信息列表
*/
function loadDomainInfoLists() {
const tbody = document.getElementById('domain-info-lists-table-body');
if (!tbody) {
console.warn('未找到域名信息列表表格元素');
return;
}
showLoading(tbody);
// 检查缓存
if (domainInfoCache && (Date.now() - cacheTimestamp) < CACHE_DURATION) {
console.log('使用缓存的域名信息列表');
renderDomainInfoLists(domainInfoCache);
return;
}
apiRequest('/api/domain-info')
.then(data => {
domainInfoCache = data;
cacheTimestamp = Date.now();
renderDomainInfoLists(data);
})
.catch(error => {
console.error('获取域名信息列表失败:', error);
showError(tbody, '获取域名信息列表失败');
window.showNotification('获取域名信息列表失败', 'error');
});
}
/**
* 渲染域名信息列表
*/
function renderDomainInfoLists(data) {
const tbody = document.getElementById('domain-info-lists-table-body');
if (!tbody) return;
tbody.innerHTML = '';
if (!data || !data.lists || data.lists.length === 0) {
const emptyRow = document.createElement('tr');
emptyRow.innerHTML = '<td colspan="6" class="py-4 text-center text-gray-500">暂无域名信息列表</td>';
tbody.appendChild(emptyRow);
return;
}
const fragment = document.createDocumentFragment();
data.lists.forEach((list, index) => {
const tr = document.createElement('tr');
tr.className = 'border-b border-gray-200 hover:bg-gray-50';
const typeLabel = getTypeLabel(list.type);
const statusClass = list.enabled ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800';
const statusText = list.enabled ? '启用' : '禁用';
tr.innerHTML = `
<td class="py-3 px-4 font-medium">${escapeHtml(list.name)}</td>
<td class="py-3 px-4">
<span class="px-2 py-1 rounded-full text-xs font-medium ${statusClass}">${statusText}</span>
</td>
<td class="py-3 px-4">
<span class="px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800">${typeLabel}</span>
</td>
<td class="py-3 px-4 text-center">${list.ruleCount || 0}</td>
<td class="py-3 px-4 text-sm text-gray-600">${formatLastUpdateTime(list.lastUpdateTime)}</td>
<td class="py-3 px-4 text-center">
<div class="flex space-x-2 justify-center">
<button onclick="window.domainInfo.updateDomainInfo('${list.type}')"
class="px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600 text-sm"
title="更新此列表">
更新
</button>
<button onclick="window.domainInfo.removeDomainInfo('${list.type}')"
class="px-3 py-1 bg-red-500 text-white rounded hover:bg-red-600 text-sm"
title="删除此列表">
删除
</button>
</div>
</td>
`;
fragment.appendChild(tr);
});
tbody.appendChild(fragment);
// 更新统计信息
updateDomainInfoStats(data);
}
/**
* 更新域名信息统计
*/
function updateDomainInfoStats(data) {
if (document.getElementById('domain-info-count')) {
document.getElementById('domain-info-count').textContent = data.domainInfoCount || 0;
}
if (document.getElementById('threat-count')) {
document.getElementById('threat-count').textContent = data.threatCount || 0;
}
if (document.getElementById('tracker-count')) {
document.getElementById('tracker-count').textContent = data.trackerCount || 0;
}
if (document.getElementById('last-update-time')) {
document.getElementById('last-update-time').textContent = formatLastUpdateTime(data.lastUpdateTime);
}
}
/**
* 更新域名信息
*/
function updateDomainInfo(type) {
const url = `/api/domain-info/update/${encodeURIComponent(type)}`;
apiRequest(url, 'POST')
.then(data => {
if (data.status === 'success') {
window.showNotification(`域名信息更新任务已启动:${getTypeLabel(type)}`, 'success');
// 延迟刷新列表
setTimeout(() => {
loadDomainInfoLists();
}, 2000);
} else {
window.showNotification(`更新失败:${data.message || '未知错误'}`, 'error');
}
})
.catch(error => {
console.error('更新域名信息失败:', error);
window.showNotification('更新域名信息失败', 'error');
});
}
/**
* 更新所有域名信息
*/
function updateAllDomainInfo() {
if (!confirm('确定要更新所有域名信息吗?这可能需要一些时间。')) {
return;
}
apiRequest('/api/domain-info/update', 'POST')
.then(data => {
if (data.status === 'success') {
window.showNotification('所有域名信息更新任务已启动', 'success');
setTimeout(() => {
loadDomainInfoLists();
}, 2000);
} else {
window.showNotification(`更新失败:${data.message || '未知错误'}`, 'error');
}
})
.catch(error => {
console.error('更新所有域名信息失败:', error);
window.showNotification('更新所有域名信息失败', 'error');
});
}
/**
* 获取类型标签
*/
function getTypeLabel(type) {
const labels = {
'domain-info': '域名信息',
'threat-database': '威胁数据库',
'tracker': '跟踪器'
};
return labels[type] || type;
}
/**
* 格式化最后更新时间
*/
function formatLastUpdateTime(timeStr) {
if (!timeStr) return '从未更新';
const date = new Date(timeStr);
const now = new Date();
const diff = now - date;
const minutes = Math.floor(diff / 60000);
const hours = Math.floor(diff / 3600000);
const days = Math.floor(diff / 86400000);
if (minutes < 1) return '刚刚';
if (minutes < 60) return `${minutes}分钟前`;
if (hours < 24) return `${hours}小时前`;
if (days < 30) return `${days}天前`;
return date.toLocaleDateString('zh-CN');
}
/**
* 显示加载状态
*/
function showLoading(container) {
container.innerHTML = `
<tr>
<td colspan="6" class="py-8 text-center">
<div class="flex items-center justify-center">
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
<span class="ml-3 text-gray-600">加载中...</span>
</div>
</td>
</tr>
`;
}
/**
* 显示错误状态
*/
function showError(container, message) {
container.innerHTML = `
<tr>
<td colspan="6" class="py-8 text-center text-red-500">
<svg class="w-12 h-12 mx-auto mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
${escapeHtml(message)}
</td>
</tr>
`;
}
/**
* HTML 转义
*/
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
/**
* API 请求封装
*/
function apiRequest(url, method = 'GET', data = null) {
const options = {
method: method,
headers: {
'Content-Type': 'application/json'
},
credentials: 'same-origin' // 添加认证信息
};
if (data && method !== 'GET') {
options.body = JSON.stringify(data);
}
return fetch(url, options)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
});
}
/**
* 显示添加列表模态框
*/
function showAddListModal() {
const modal = document.getElementById('add-domain-info-modal');
if (modal) {
modal.classList.remove('hidden');
}
}
/**
* 隐藏添加列表模态框
*/
function hideAddListModal() {
const modal = document.getElementById('add-domain-info-modal');
if (modal) {
modal.classList.add('hidden');
// 重置表单
document.getElementById('add-domain-info-form').reset();
}
}
/**
* 添加域名信息列表
*/
function addDomainInfo(e) {
e.preventDefault();
const name = document.getElementById('list-name').value.trim();
const url = document.getElementById('list-url').value.trim();
const type = document.getElementById('list-type').value;
const enabled = document.getElementById('list-enabled').checked;
if (!name || !url) {
window.showNotification('请填写名称和URL', 'error');
return;
}
const data = {
name: name,
url: url,
type: type,
enabled: enabled
};
apiRequest('/api/domain-info/add', 'POST', data)
.then(response => {
if (response.status === 'success') {
window.showNotification('域名信息列表添加成功', 'success');
hideAddListModal();
loadDomainInfoLists();
} else {
window.showNotification(`添加失败:${response.message || '未知错误'}`, 'error');
}
})
.catch(error => {
console.error('添加域名信息列表失败:', error);
window.showNotification('添加域名信息列表失败', 'error');
});
}
/**
* 删除域名信息列表
*/
function removeDomainInfo(type) {
if (!confirm('确定要删除此域名信息列表吗?此操作不可恢复。')) {
return;
}
apiRequest(`/api/domain-info/remove/${encodeURIComponent(type)}`, 'POST')
.then(response => {
if (response.status === 'success') {
window.showNotification('域名信息列表删除成功', 'success');
loadDomainInfoLists();
} else {
window.showNotification(`删除失败:${response.message || '未知错误'}`, 'error');
}
})
.catch(error => {
console.error('删除域名信息列表失败:', error);
window.showNotification('删除域名信息列表失败', 'error');
});
}
// 绑定添加列表表单提交事件
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('add-domain-info-form');
if (form) {
form.addEventListener('submit', addDomainInfo);
}
});
// 暴露到全局命名空间
window.domainInfo = {
loadDomainInfoLists,
updateDomainInfo,
updateAllDomainInfo,
renderDomainInfoLists,
showAddListModal,
hideAddListModal,
removeDomainInfo
};
})();
+150 -1
View File
@@ -1480,4 +1480,153 @@ document.addEventListener('DOMContentLoaded', () => {
initShieldPage();
}
});
});
});
// ========== 域名信息管理相关功能 ==========
// 加载远程域名信息列表
async function loadRemoteDomainInfoLists() {
// 检查是否有有效的缓存数据
const cachedDomainInfo = window.pageDataCache && window.pageDataCache.getCache('domain_info_lists');
if (cachedDomainInfo) {
console.log('使用缓存的域名信息列表');
updateDomainInfoListsTable(cachedDomainInfo);
return;
}
try {
const response = await fetch('/api/domain-info');
if (!response.ok) {
throw new Error(`加载失败:${response.status}`);
}
const domainInfo = await response.json();
// 更新域名信息列表 UI
updateDomainInfoListsTable(domainInfo);
// 存储数据到缓存
if (window.pageDataCache) {
window.pageDataCache.setCache('domain_info_lists', domainInfo);
}
} catch (error) {
console.error('加载域名信息列表失败:', error);
showNotification('加载域名信息列表失败', 'error');
}
}
// 更新域名信息列表表格
function updateDomainInfoListsTable(data) {
if (!data) return;
// 更新统计信息
if (document.getElementById('domain-info-count')) {
document.getElementById('domain-info-count').textContent = data.domainInfoCount || 0;
}
if (document.getElementById('threat-count')) {
document.getElementById('threat-count').textContent = data.threatCount || 0;
}
if (document.getElementById('tracker-count')) {
document.getElementById('tracker-count').textContent = data.trackerCount || 0;
}
// 渲染列表(如果页面有表格元素)
if (window.domainInfo && typeof window.domainInfo.renderDomainInfoLists === 'function') {
window.domainInfo.renderDomainInfoLists(data);
}
}
// 更新所有域名信息
async function updateAllDomainInfo() {
if (!confirm('确定要更新所有域名信息吗?这可能需要一些时间。')) {
return;
}
try {
const response = await fetch('/api/domain-info/update', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`更新失败:${response.status}`);
}
const result = await response.json();
if (result.status === 'success') {
showNotification('所有域名信息更新任务已启动', 'success');
// 清除缓存
if (window.pageDataCache) {
window.pageDataCache.clearCache('domain_info_lists');
}
// 延迟刷新
setTimeout(() => {
loadRemoteDomainInfoLists();
}, 2000);
} else {
showNotification(`更新失败:${result.message || '未知错误'}`, 'error');
}
} catch (error) {
console.error('更新所有域名信息失败:', error);
showNotification('更新所有域名信息失败', 'error');
}
}
// 更新指定类型的域名信息
async function updateDomainInfoByType(type) {
const typeLabels = {
'domain-info': '域名信息',
'threat-database': '威胁数据库',
'tracker': '跟踪器'
};
const typeName = typeLabels[type] || type;
try {
const response = await fetch(`/api/domain-info/update/${encodeURIComponent(type)}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`更新失败:${response.status}`);
}
const result = await response.json();
if (result.status === 'success') {
showNotification(`${typeName}更新任务已启动`, 'success');
// 清除缓存
if (window.pageDataCache) {
window.pageDataCache.clearCache('domain_info_lists');
}
// 延迟刷新
setTimeout(() => {
loadRemoteDomainInfoLists();
}, 2000);
} else {
showNotification(`更新失败:${result.message || '未知错误'}`, 'error');
}
} catch (error) {
console.error(`更新${typeName}失败:`, error);
showNotification(`更新${typeName}失败`, 'error');
}
}
// 在 initShieldPage 中添加域名信息列表加载(如果页面存在相关元素)
const originalInitShieldPage = window.initShieldPage;
window.initShieldPage = async function() {
if (originalInitShieldPage) {
await originalInitShieldPage();
}
// 如果页面有域名信息管理相关元素,则加载
if (document.getElementById('domain-info-lists-table-body')) {
await loadRemoteDomainInfoLists();
}
};