远程列表web

This commit is contained in:
Alex Yang
2025-11-24 00:00:47 +08:00
parent fcd4fc9e68
commit f499a4a84a
7 changed files with 328 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
{ {
"blockedDomainsCount": {}, "blockedDomainsCount": {},
"resolvedDomainsCount": {}, "resolvedDomainsCount": {},
"lastSaved": "2025-11-23T23:49:00.869596178+08:00" "lastSaved": "2025-11-23T23:59:38.260427873+08:00"
} }

View File

@@ -340,5 +340,5 @@
"2025-11-23-22": 2, "2025-11-23-22": 2,
"2025-11-23-23": 2 "2025-11-23-23": 2
}, },
"lastSaved": "2025-11-23T23:35:51.696690359+08:00" "lastSaved": "2025-11-23T23:53:55.655573463+08:00"
} }

BIN
dns-server Executable file

Binary file not shown.

View File

@@ -18920,3 +18920,93 @@ time="2025-11-23T23:49:01+08:00" level=error msg="获取远程规则失败" erro
time="2025-11-23T23:49:01+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt" time="2025-11-23T23:49:01+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt"
time="2025-11-23T23:49:01+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 901, hosts规则: 3" time="2025-11-23T23:49:01+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 901, hosts规则: 3"
time="2025-11-23T23:49:01+08:00" level=info msg="自动更新规则成功" time="2025-11-23T23:49:01+08:00" level=info msg="自动更新规则成功"
time="2025-11-23T23:50:00+08:00" level=info msg="开始自动更新规则"
time="2025-11-23T23:50:00+08:00" level=info msg="Shield计数数据保存成功"
time="2025-11-23T23:50:00+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt"
time="2025-11-23T23:50:01+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt"
time="2025-11-23T23:50:01+08:00" level=error msg="获取远程规则失败" error="Get \"hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt\": unsupported protocol scheme \"hhttps\"" url="hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
time="2025-11-23T23:50:01+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt"
time="2025-11-23T23:50:01+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 901, hosts规则: 3"
time="2025-11-23T23:50:01+08:00" level=info msg="自动更新规则成功"
time="2025-11-23T23:51:00+08:00" level=info msg="开始自动更新规则"
time="2025-11-23T23:51:00+08:00" level=info msg="Shield计数数据保存成功"
time="2025-11-23T23:51:00+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt"
time="2025-11-23T23:51:01+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt"
time="2025-11-23T23:51:01+08:00" level=error msg="获取远程规则失败" error="Get \"hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt\": unsupported protocol scheme \"hhttps\"" url="hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
time="2025-11-23T23:51:01+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt"
time="2025-11-23T23:51:01+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 901, hosts规则: 3"
time="2025-11-23T23:51:01+08:00" level=info msg="自动更新规则成功"
time="2025-11-23T23:52:00+08:00" level=info msg="开始自动更新规则"
time="2025-11-23T23:52:00+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt"
time="2025-11-23T23:52:01+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt"
time="2025-11-23T23:52:01+08:00" level=error msg="获取远程规则失败" error="Get \"hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt\": unsupported protocol scheme \"hhttps\"" url="hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
time="2025-11-23T23:52:01+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt"
time="2025-11-23T23:52:01+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 901, hosts规则: 3"
time="2025-11-23T23:52:01+08:00" level=info msg="自动更新规则成功"
time="2025-11-23T23:52:01+08:00" level=info msg="Shield计数数据保存成功"
time="2025-11-23T23:53:00+08:00" level=info msg="开始自动更新规则"
time="2025-11-23T23:53:00+08:00" level=info msg="Shield计数数据保存成功"
time="2025-11-23T23:53:00+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt"
time="2025-11-23T23:53:01+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt"
time="2025-11-23T23:53:01+08:00" level=error msg="获取远程规则失败" error="Get \"hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt\": unsupported protocol scheme \"hhttps\"" url="hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
time="2025-11-23T23:53:01+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt"
time="2025-11-23T23:53:01+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 901, hosts规则: 3"
time="2025-11-23T23:53:01+08:00" level=info msg="自动更新规则成功"
time="2025-11-23T23:53:55+08:00" level=info msg="正在关闭服务..."
time="2025-11-23T23:53:55+08:00" level=info msg="统计数据保存成功"
time="2025-11-23T23:53:55+08:00" level=info msg="DNS服务器已停止"
time="2025-11-23T23:53:55+08:00" level=error msg="HTTP控制台服务器启动失败" error="http: Server closed"
time="2025-11-23T23:53:55+08:00" level=info msg="HTTP控制台服务器已停止"
time="2025-11-23T23:53:55+08:00" level=info msg="Shield计数数据保存成功"
time="2025-11-23T23:53:55+08:00" level=info msg="规则自动更新已停止"
time="2025-11-23T23:53:55+08:00" level=info msg="所有服务已关闭"
time="2025-11-23T23:53:55+08:00" level=warning msg="日志系统已关闭"
time="2025-11-23T23:54:37+08:00" level=error msg="解析Shield计数数据失败" error="unexpected end of JSON input"
time="2025-11-23T23:54:37+08:00" level=error msg="获取远程规则失败" error="Get \"hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt\": unsupported protocol scheme \"hhttps\"" url="hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
time="2025-11-23T23:54:37+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 452, hosts规则: 3"
time="2025-11-23T23:54:37+08:00" level=info msg="统计数据加载成功"
time="2025-11-23T23:54:37+08:00" level=info msg="DNS服务器已启动监听端口: 53"
time="2025-11-23T23:54:37+08:00" level=info msg="HTTP控制台已启动监听端口: 8080"
time="2025-11-23T23:54:37+08:00" level=info msg="DNS TCP服务器启动监听端口: 53"
time="2025-11-23T23:54:37+08:00" level=info msg="规则自动更新已启动" interval=60
time="2025-11-23T23:54:37+08:00" level=info msg="DNS UDP服务器启动监听端口: 53"
time="2025-11-23T23:54:37+08:00" level=info msg="启动Shield计数数据自动保存功能" file=./data/shield_stats.json interval=60
time="2025-11-23T23:54:37+08:00" level=info msg="HTTP控制台服务器启动监听地址: 0.0.0.0:8080"
time="2025-11-23T23:54:37+08:00" level=info msg="Shield计数数据保存成功"
time="2025-11-23T23:55:37+08:00" level=info msg="开始自动更新规则"
time="2025-11-23T23:55:37+08:00" level=info msg="Shield计数数据保存成功"
time="2025-11-23T23:55:38+08:00" level=error msg="获取远程规则失败" error="Get \"hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt\": unsupported protocol scheme \"hhttps\"" url="hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
time="2025-11-23T23:55:38+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 452, hosts规则: 3"
time="2025-11-23T23:55:38+08:00" level=info msg="自动更新规则成功"
time="2025-11-23T23:56:37+08:00" level=info msg="开始自动更新规则"
time="2025-11-23T23:56:37+08:00" level=info msg="Shield计数数据保存成功"
time="2025-11-23T23:56:37+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt"
time="2025-11-23T23:56:37+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt"
time="2025-11-23T23:56:38+08:00" level=error msg="获取远程规则失败" error="Get \"hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt\": unsupported protocol scheme \"hhttps\"" url="hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
time="2025-11-23T23:56:38+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt"
time="2025-11-23T23:56:38+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 901, hosts规则: 3"
time="2025-11-23T23:56:38+08:00" level=info msg="自动更新规则成功"
time="2025-11-23T23:57:37+08:00" level=info msg="Shield计数数据保存成功"
time="2025-11-23T23:57:37+08:00" level=info msg="开始自动更新规则"
time="2025-11-23T23:57:37+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt"
time="2025-11-23T23:57:37+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt"
time="2025-11-23T23:57:38+08:00" level=error msg="获取远程规则失败" error="Get \"hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt\": unsupported protocol scheme \"hhttps\"" url="hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
time="2025-11-23T23:57:38+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt"
time="2025-11-23T23:57:38+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 901, hosts规则: 3"
time="2025-11-23T23:57:38+08:00" level=info msg="自动更新规则成功"
time="2025-11-23T23:58:37+08:00" level=info msg="开始自动更新规则"
time="2025-11-23T23:58:37+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt"
time="2025-11-23T23:58:37+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt"
time="2025-11-23T23:58:38+08:00" level=error msg="获取远程规则失败" error="Get \"hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt\": unsupported protocol scheme \"hhttps\"" url="hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
time="2025-11-23T23:58:38+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt"
time="2025-11-23T23:58:38+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 901, hosts规则: 3"
time="2025-11-23T23:58:38+08:00" level=info msg="自动更新规则成功"
time="2025-11-23T23:58:38+08:00" level=info msg="Shield计数数据保存成功"
time="2025-11-23T23:59:37+08:00" level=info msg="开始自动更新规则"
time="2025-11-23T23:59:37+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt"
time="2025-11-23T23:59:37+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt"
time="2025-11-23T23:59:38+08:00" level=error msg="获取远程规则失败" error="Get \"hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt\": unsupported protocol scheme \"hhttps\"" url="hhttps://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
time="2025-11-23T23:59:38+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt"
time="2025-11-23T23:59:38+08:00" level=info msg="规则加载完成,域名规则: 86449, 排除规则: 977, 正则规则: 901, hosts规则: 3"
time="2025-11-23T23:59:38+08:00" level=info msg="自动更新规则成功"
time="2025-11-23T23:59:38+08:00" level=info msg="Shield计数数据保存成功"

View File

@@ -304,12 +304,21 @@ func (s *Server) handleShieldHosts(w http.ResponseWriter, r *http.Request) {
case http.MethodGet: case http.MethodGet:
// 获取hosts条目列表 // 获取hosts条目列表
// 注意这需要在shieldManager中添加一个获取所有hosts条目的方法 hosts := s.shieldManager.GetAllHosts()
// 暂时返回统计信息 hostsCount := s.shieldManager.GetHostsCount()
stats := s.shieldManager.GetStats()
// 转换为数组格式,便于前端展示
hostsList := make([]map[string]string, 0, len(hosts))
for domain, ip := range hosts {
hostsList = append(hostsList, map[string]string{
"domain": domain,
"ip": ip,
})
}
json.NewEncoder(w).Encode(map[string]interface{}{ json.NewEncoder(w).Encode(map[string]interface{}{
"hostsCount": stats["hostsRules"], "hosts": hostsList,
"message": "获取hosts列表功能待实现", "hostsCount": hostsCount,
}) })
default: default:

View File

@@ -1019,6 +1019,28 @@ func (m *ShieldManager) UpdateBlacklist(blacklists []config.BlacklistEntry) {
m.config.Blacklists = blacklists m.config.Blacklists = blacklists
} }
// GetAllHosts 获取所有hosts条目
func (m *ShieldManager) GetAllHosts() map[string]string {
m.rulesMutex.RLock()
defer m.rulesMutex.RUnlock()
// 返回hostsMap的副本避免并发问题
hostsCopy := make(map[string]string, len(m.hostsMap))
for domain, ip := range m.hostsMap {
hostsCopy[domain] = ip
}
return hostsCopy
}
// GetHostsCount 获取hosts条目数量
func (m *ShieldManager) GetHostsCount() int {
m.rulesMutex.RLock()
defer m.rulesMutex.RUnlock()
return len(m.hostsMap)
}
// GetRules 获取所有规则 // GetRules 获取所有规则
func (m *ShieldManager) GetRules() map[string]interface{} { func (m *ShieldManager) GetRules() map[string]interface{} {
m.rulesMutex.RLock() m.rulesMutex.RLock()

View File

@@ -1559,7 +1559,7 @@ function loadRules() {
console.error('保存黑名单设置失败:', error); console.error('保存黑名单设置失败:', error);
showNotification('danger', '保存失败: ' + error.message); showNotification('danger', '保存失败: ' + error.message);
}); });
.then(data => { then(data => {
// 重置按钮状态 // 重置按钮状态
btn.innerHTML = originalText; btn.innerHTML = originalText;
btn.disabled = false; btn.disabled = false;
@@ -1591,22 +1591,40 @@ function loadRules() {
fetch('/api/shield/hosts') fetch('/api/shield/hosts')
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
// 注意这需要在shieldManager中添加一个获取所有hosts条目的方法
// 暂时返回统计信息
const hostsCount = data.hostsCount || 0; const hostsCount = data.hostsCount || 0;
const hostsList = data.hosts || [];
if (hostsCount > 0) { if (hostsCount > 0 && hostsList.length > 0) {
hostsContainer.innerHTML = `<div class="list-item"> // 构建hosts列表HTML
<div class="list-content"> let hostsHTML = `<div class="list-header">
<div class="list-title">Hosts概览</div> <div class="list-title">Hosts条目列表</div>
<div class="list-description">共 ${hostsCount} 个Hosts条目</div> <div class="list-description">共 ${hostsCount} 个Hosts条目</div>
</div>
<div class="list-actions">
<button class="btn-outline btn-sm" onclick="location.reload()">刷新</button>
</div>
</div>`; </div>`;
hostsList.forEach(item => {
hostsHTML += `<div class="list-item">
<div class="list-content">
<div class="list-title">${item.domain}</div>
<div class="list-description">IP: ${item.ip}</div>
</div>
<div class="list-actions">
<button class="btn-danger btn-sm" onclick="deleteHostsEntry('${item.domain}')">删除</button>
</div>
</div>`;
});
hostsHTML += `<div class="list-footer">
<button class="btn-primary btn-sm" onclick="showAddHostsModal()">添加Hosts条目</button>
<button class="btn-outline btn-sm" onclick="loadHostsList()">刷新</button>
</div>`;
hostsContainer.innerHTML = hostsHTML;
} else { } else {
hostsContainer.innerHTML = '<div class="empty-state"><i class="fas fa-info-circle"></i><p>暂无Hosts条目</p></div>'; hostsContainer.innerHTML = `<div class="empty-state">
<i class="fas fa-info-circle"></i>
<p>暂无Hosts条目</p>
<button class="btn-primary btn-sm" onclick="showAddHostsModal()">添加Hosts条目</button>
</div>`;
} }
}) })
.catch(error => { .catch(error => {
@@ -2095,10 +2113,178 @@ function loadRules() {
blacklists.push({ name, URL: url, enabled }); blacklists.push({ name, URL: url, enabled });
} }
}); });
}
// 加载hosts列表
function loadHostsList() {
const hostsContainer = document.getElementById('hosts-container');
hostsContainer.innerHTML = '<div class="loading-state"><i class="fas fa-spinner fa-spin"></i><p>加载中...</p></div>';
fetch('/api/shield/hosts')
.then(response => response.json())
.then(data => {
const hostsCount = data.hostsCount || 0;
const hostsList = data.hosts || [];
if (hostsCount > 0 && hostsList.length > 0) {
// 构建hosts列表HTML
let hostsHTML = `<div class="list-header">
<div class="list-title">Hosts条目列表</div>
<div class="list-description">共 ${hostsCount} 个Hosts条目</div>
</div>`;
hostsList.forEach(item => {
hostsHTML += `<div class="list-item">
<div class="list-content">
<div class="list-title">${item.domain}</div>
<div class="list-description">IP: ${item.ip}</div>
</div>
<div class="list-actions">
<button class="btn-danger btn-sm" onclick="deleteHostsEntry('${item.domain}')">删除</button>
</div>
</div>`;
});
hostsHTML += `<div class="list-footer">
<button class="btn-primary btn-sm" onclick="showAddHostsModal()">添加Hosts条目</button>
<button class="btn-outline btn-sm" onclick="loadHostsList()">刷新</button>
</div>`;
hostsContainer.innerHTML = hostsHTML;
} else {
hostsContainer.innerHTML = `<div class="empty-state">
<i class="fas fa-info-circle"></i>
<p>暂无Hosts条目</p>
<button class="btn-primary btn-sm" onclick="showAddHostsModal()">添加Hosts条目</button>
</div>`;
}
})
.catch(error => {
hostsContainer.innerHTML = `<div class="error-state"><i class="fas fa-exclamation-circle"></i><p>加载失败: ${error.message}</p></div>`;
console.error('加载hosts列表失败:', error);
});
}
// 显示添加hosts条目的模态框
function showAddHostsModal() {
// 创建模态框HTML
const modalHTML = `
<div class="modal-overlay" onclick="closeAddHostsModal()">
<div class="modal-content" onclick="event.stopPropagation()">
<div class="modal-header">
<h3>添加Hosts条目</h3>
<button class="modal-close" onclick="closeAddHostsModal()">&times;</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="hosts-domain">域名</label>
<input type="text" id="hosts-domain" placeholder="请输入域名,如 example.com" required>
</div>
<div class="form-group">
<label for="hosts-ip">IP地址</label>
<input type="text" id="hosts-ip" placeholder="请输入IP地址如 192.168.1.1" required>
</div>
</div>
<div class="modal-footer">
<button class="btn-outline" onclick="closeAddHostsModal()">取消</button>
<button class="btn-primary" onclick="addHostsEntry()">添加</button>
</div>
</div>
</div>`;
// 添加模态框到页面
const modalDiv = document.createElement('div');
modalDiv.id = 'add-hosts-modal';
modalDiv.innerHTML = modalHTML;
document.body.appendChild(modalDiv);
}
// 关闭添加hosts条目的模态框
function closeAddHostsModal() {
const modal = document.getElementById('add-hosts-modal');
if (modal) {
modal.remove();
}
}
// 添加hosts条目
function addHostsEntry() {
const domain = document.getElementById('hosts-domain').value.trim();
const ip = document.getElementById('hosts-ip').value.trim();
if (!domain || !ip) {
alert('请填写域名和IP地址');
return;
}
// 简单的IP地址验证
const ipRegex = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/;
if (!ipRegex.test(ip)) {
alert('请输入有效的IP地址');
return;
}
fetch('/api/shield/hosts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ domain, ip })
})
.then(response => {
if (!response.ok) {
throw new Error('添加失败');
}
return response.json();
})
.then(data => {
if (data.status === 'success') {
alert('添加成功');
closeAddHostsModal();
loadHostsList();
} else {
alert('添加失败');
}
})
.catch(error => {
console.error('添加hosts条目失败:', error);
alert('添加失败: ' + error.message);
});
}
// 删除hosts条目
function deleteHostsEntry(domain) {
if (confirm(`确定要删除域名 ${domain} 的hosts条目吗`)) {
fetch('/api/shield/hosts', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ domain })
})
.then(response => {
if (!response.ok) {
throw new Error('删除失败');
}
return response.json();
})
.then(data => {
if (data.status === 'success') {
loadHostsList();
} else {
alert('删除失败');
}
})
.catch(error => {
console.error('删除hosts条目失败:', error);
alert('删除失败: ' + error.message);
});
}
}
renderBlacklistsList(blacklists); renderBlacklistsList(blacklists);
showNotification('success', '黑名单已删除'); showNotification('success', '黑名单已删除');
}
// 保存黑名单设置 // 保存黑名单设置
function saveBlacklistsSettings() { function saveBlacklistsSettings() {