修复配置更新未写入配置文件的问题
This commit is contained in:
@@ -36,6 +36,11 @@
|
|||||||
"name": "My GitHub Rules",
|
"name": "My GitHub Rules",
|
||||||
"url": "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt",
|
"url": "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt",
|
||||||
"enabled": true
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "China List",
|
||||||
|
"url": "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/china.txt",
|
||||||
|
"enabled": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"updateInterval": 3600,
|
"updateInterval": 3600,
|
||||||
|
|||||||
BIN
dns-server
BIN
dns-server
Binary file not shown.
@@ -731,6 +731,14 @@ func (s *Server) handleShieldBlacklists(w http.ResponseWriter, r *http.Request)
|
|||||||
blacklists[targetIndex].LastUpdateTime = time.Now().Format(time.RFC3339)
|
blacklists[targetIndex].LastUpdateTime = time.Now().Format(time.RFC3339)
|
||||||
// 保存更新后的黑名单列表
|
// 保存更新后的黑名单列表
|
||||||
s.shieldManager.UpdateBlacklist(blacklists)
|
s.shieldManager.UpdateBlacklist(blacklists)
|
||||||
|
// 更新全局配置中的黑名单
|
||||||
|
s.globalConfig.Shield.Blacklists = blacklists
|
||||||
|
// 保存配置到文件
|
||||||
|
if err := saveConfigToFile(s.globalConfig, "config.json"); err != nil {
|
||||||
|
logger.Error("保存配置文件失败", "error", err)
|
||||||
|
http.Error(w, "保存配置失败", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
// 重新加载规则以获取最新的远程规则
|
// 重新加载规则以获取最新的远程规则
|
||||||
s.shieldManager.LoadRules()
|
s.shieldManager.LoadRules()
|
||||||
|
|
||||||
@@ -753,6 +761,14 @@ func (s *Server) handleShieldBlacklists(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.shieldManager.UpdateBlacklist(newBlacklists)
|
s.shieldManager.UpdateBlacklist(newBlacklists)
|
||||||
|
// 更新全局配置中的黑名单
|
||||||
|
s.globalConfig.Shield.Blacklists = newBlacklists
|
||||||
|
// 保存配置到文件
|
||||||
|
if err := saveConfigToFile(s.globalConfig, "config.json"); err != nil {
|
||||||
|
logger.Error("保存配置文件失败", "error", err)
|
||||||
|
http.Error(w, "保存配置失败", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
|
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -800,6 +816,14 @@ func (s *Server) handleShieldBlacklists(w http.ResponseWriter, r *http.Request)
|
|||||||
|
|
||||||
blacklists = append(blacklists, newEntry)
|
blacklists = append(blacklists, newEntry)
|
||||||
s.shieldManager.UpdateBlacklist(blacklists)
|
s.shieldManager.UpdateBlacklist(blacklists)
|
||||||
|
// 更新全局配置中的黑名单
|
||||||
|
s.globalConfig.Shield.Blacklists = blacklists
|
||||||
|
// 保存配置到文件
|
||||||
|
if err := saveConfigToFile(s.globalConfig, "config.json"); err != nil {
|
||||||
|
logger.Error("保存配置文件失败", "error", err)
|
||||||
|
http.Error(w, "保存配置失败", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 重新加载规则以获取新添加的远程规则
|
// 重新加载规则以获取新添加的远程规则
|
||||||
s.shieldManager.LoadRules()
|
s.shieldManager.LoadRules()
|
||||||
@@ -815,6 +839,14 @@ func (s *Server) handleShieldBlacklists(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.shieldManager.UpdateBlacklist(blacklists)
|
s.shieldManager.UpdateBlacklist(blacklists)
|
||||||
|
// 更新全局配置中的黑名单
|
||||||
|
s.globalConfig.Shield.Blacklists = blacklists
|
||||||
|
// 保存配置到文件
|
||||||
|
if err := saveConfigToFile(s.globalConfig, "config.json"); err != nil {
|
||||||
|
logger.Error("保存配置文件失败", "error", err)
|
||||||
|
http.Error(w, "保存配置失败", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
// 重新加载所有规则
|
// 重新加载所有规则
|
||||||
s.shieldManager.LoadRules()
|
s.shieldManager.LoadRules()
|
||||||
|
|
||||||
|
|||||||
@@ -293,6 +293,19 @@ async function loadRemoteBlacklists() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断黑名单是否过期(超过24小时未更新视为过期)
|
||||||
|
function isBlacklistExpired(lastUpdateTime) {
|
||||||
|
if (!lastUpdateTime) {
|
||||||
|
return true; // 从未更新过,视为过期
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastUpdate = new Date(lastUpdateTime);
|
||||||
|
const now = new Date();
|
||||||
|
const hoursDiff = (now - lastUpdate) / (1000 * 60 * 60);
|
||||||
|
|
||||||
|
return hoursDiff > 24; // 超过24小时视为过期
|
||||||
|
}
|
||||||
|
|
||||||
// 更新黑名单表格
|
// 更新黑名单表格
|
||||||
function updateBlacklistsTable(blacklists) {
|
function updateBlacklistsTable(blacklists) {
|
||||||
const tbody = document.getElementById('blacklists-table-body');
|
const tbody = document.getElementById('blacklists-table-body');
|
||||||
@@ -300,7 +313,8 @@ function updateBlacklistsTable(blacklists) {
|
|||||||
// 清空表格
|
// 清空表格
|
||||||
tbody.innerHTML = '';
|
tbody.innerHTML = '';
|
||||||
|
|
||||||
if (blacklists.length === 0) {
|
// 检查黑名单数据是否为空
|
||||||
|
if (!blacklists || blacklists.length === 0) {
|
||||||
const emptyRow = document.createElement('tr');
|
const emptyRow = document.createElement('tr');
|
||||||
emptyRow.innerHTML = '<tr><td colspan="4" class="py-4 text-center text-gray-500">暂无黑名单</td></tr>';
|
emptyRow.innerHTML = '<tr><td colspan="4" class="py-4 text-center text-gray-500">暂无黑名单</td></tr>';
|
||||||
tbody.appendChild(emptyRow);
|
tbody.appendChild(emptyRow);
|
||||||
@@ -316,12 +330,12 @@ function updateBlacklistsTable(blacklists) {
|
|||||||
|
|
||||||
blacklistsToShow.forEach(blacklist => {
|
blacklistsToShow.forEach(blacklist => {
|
||||||
const tr = document.createElement('tr');
|
const tr = document.createElement('tr');
|
||||||
tr.className = 'border-b border-gray-200';
|
tr.className = 'border-b border-gray-200 hover:bg-gray-50';
|
||||||
|
|
||||||
// 名称单元格
|
// 名称单元格
|
||||||
const tdName = document.createElement('td');
|
const tdName = document.createElement('td');
|
||||||
tdName.className = 'py-3 px-4';
|
tdName.className = 'py-3 px-4';
|
||||||
tdName.textContent = blacklist.Name;
|
tdName.textContent = blacklist.Name || '未命名';
|
||||||
|
|
||||||
// URL单元格
|
// URL单元格
|
||||||
const tdUrl = document.createElement('td');
|
const tdUrl = document.createElement('td');
|
||||||
@@ -331,29 +345,58 @@ function updateBlacklistsTable(blacklists) {
|
|||||||
// 状态单元格
|
// 状态单元格
|
||||||
const tdStatus = document.createElement('td');
|
const tdStatus = document.createElement('td');
|
||||||
tdStatus.className = 'py-3 px-4 text-center';
|
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 = '正常';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusContainer = document.createElement('div');
|
||||||
|
statusContainer.className = 'flex items-center justify-center';
|
||||||
|
|
||||||
const statusDot = document.createElement('span');
|
const statusDot = document.createElement('span');
|
||||||
statusDot.className = `inline-block w-3 h-3 rounded-full ${blacklist.Enabled ? 'bg-success' : 'bg-gray-300'}`;
|
statusDot.className = `inline-block w-3 h-3 rounded-full ${statusColor}`;
|
||||||
tdStatus.appendChild(statusDot);
|
statusDot.title = statusText;
|
||||||
|
|
||||||
|
const statusTextSpan = document.createElement('span');
|
||||||
|
statusTextSpan.className = 'text-sm ml-2';
|
||||||
|
statusTextSpan.textContent = statusText;
|
||||||
|
|
||||||
|
statusContainer.appendChild(statusDot);
|
||||||
|
statusContainer.appendChild(statusTextSpan);
|
||||||
|
tdStatus.appendChild(statusContainer);
|
||||||
|
|
||||||
// 操作单元格
|
// 操作单元格
|
||||||
const tdActions = document.createElement('td');
|
const tdActions = document.createElement('td');
|
||||||
tdActions.className = 'py-3 px-4 text-right space-x-2';
|
tdActions.className = 'py-3 px-4 text-right space-x-2';
|
||||||
|
|
||||||
// 更新按钮
|
// 刷新按钮
|
||||||
const updateBtn = document.createElement('button');
|
const refreshBtn = document.createElement('button');
|
||||||
updateBtn.className = 'update-blacklist-btn px-3 py-1 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors text-sm';
|
refreshBtn.className = 'update-blacklist-btn px-3 py-1 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors text-sm';
|
||||||
updateBtn.dataset.url = blacklist.URL;
|
refreshBtn.dataset.url = blacklist.URL;
|
||||||
updateBtn.innerHTML = '<i class="fa fa-refresh"></i>';
|
refreshBtn.innerHTML = '<i class="fa fa-refresh"></i>';
|
||||||
updateBtn.addEventListener('click', handleUpdateBlacklist);
|
refreshBtn.title = '刷新黑名单';
|
||||||
|
refreshBtn.addEventListener('click', handleUpdateBlacklist);
|
||||||
|
|
||||||
// 删除按钮
|
// 删除按钮
|
||||||
const deleteBtn = document.createElement('button');
|
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.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.innerHTML = '<i class="fa fa-trash"></i>';
|
||||||
|
deleteBtn.title = '删除黑名单';
|
||||||
deleteBtn.addEventListener('click', handleDeleteBlacklist);
|
deleteBtn.addEventListener('click', handleDeleteBlacklist);
|
||||||
|
|
||||||
tdActions.appendChild(updateBtn);
|
tdActions.appendChild(refreshBtn);
|
||||||
tdActions.appendChild(deleteBtn);
|
tdActions.appendChild(deleteBtn);
|
||||||
|
|
||||||
tr.appendChild(tdName);
|
tr.appendChild(tdName);
|
||||||
@@ -377,25 +420,35 @@ function updateBlacklistsTable(blacklists) {
|
|||||||
// 处理更新单个黑名单
|
// 处理更新单个黑名单
|
||||||
async function handleUpdateBlacklist(e) {
|
async function handleUpdateBlacklist(e) {
|
||||||
const url = e.target.closest('.update-blacklist-btn').dataset.url;
|
const url = e.target.closest('.update-blacklist-btn').dataset.url;
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
showToast('无效的黑名单URL', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
showLoading('更新黑名单中...');
|
showLoading('更新黑名单中...');
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/shield/blacklists/${encodeURIComponent(url)}/update`, {
|
const response = await fetch(`/api/shield/blacklists/${encodeURIComponent(url)}/update`, {
|
||||||
method: 'POST'
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Failed to update blacklist');
|
const errorData = await response.json().catch(() => ({}));
|
||||||
|
throw new Error(errorData.error || 'Failed to update blacklist');
|
||||||
}
|
}
|
||||||
|
|
||||||
showSuccessMessage('黑名单更新成功');
|
|
||||||
// 重新加载黑名单
|
// 重新加载黑名单
|
||||||
loadRemoteBlacklists();
|
loadRemoteBlacklists();
|
||||||
// 重新加载统计信息
|
// 重新加载统计信息
|
||||||
loadShieldStats();
|
loadShieldStats();
|
||||||
hideLoading();
|
showToast('黑名单更新成功');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error updating blacklist:', error);
|
console.error('更新黑名单失败:', error);
|
||||||
showErrorMessage('更新黑名单失败');
|
showToast('更新黑名单失败: ' + error.message, 'error');
|
||||||
|
} finally {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -403,39 +456,71 @@ async function handleUpdateBlacklist(e) {
|
|||||||
// 处理删除黑名单
|
// 处理删除黑名单
|
||||||
async function handleDeleteBlacklist(e) {
|
async function handleDeleteBlacklist(e) {
|
||||||
const url = e.target.closest('.delete-blacklist-btn').dataset.url;
|
const url = e.target.closest('.delete-blacklist-btn').dataset.url;
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
showToast('无效的黑名单URL', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认删除
|
||||||
|
if (!confirm('确定要删除这个黑名单吗?删除后将无法恢复。')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
showLoading('删除黑名单中...');
|
showLoading('删除黑名单中...');
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/shield/blacklists/${encodeURIComponent(url)}`, {
|
const response = await fetch(`/api/shield/blacklists/${encodeURIComponent(url)}`, {
|
||||||
method: 'DELETE'
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Failed to delete blacklist');
|
const errorData = await response.json().catch(() => ({}));
|
||||||
|
throw new Error(errorData.error || 'Failed to delete blacklist');
|
||||||
}
|
}
|
||||||
|
|
||||||
showSuccessMessage('黑名单删除成功');
|
|
||||||
// 重新加载黑名单
|
// 重新加载黑名单
|
||||||
loadRemoteBlacklists();
|
loadRemoteBlacklists();
|
||||||
// 重新加载统计信息
|
// 重新加载统计信息
|
||||||
loadShieldStats();
|
loadShieldStats();
|
||||||
hideLoading();
|
showToast('黑名单删除成功');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error deleting blacklist:', error);
|
console.error('删除黑名单失败:', error);
|
||||||
showErrorMessage('删除黑名单失败');
|
showToast('删除黑名单失败: ' + error.message, 'error');
|
||||||
|
} finally {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理添加黑名单
|
// 处理添加黑名单
|
||||||
async function handleAddBlacklist() {
|
async function handleAddBlacklist(event) {
|
||||||
const name = document.getElementById('blacklist-name').value.trim();
|
// 如果存在event参数,则调用preventDefault()防止表单默认提交
|
||||||
const url = document.getElementById('blacklist-url').value.trim();
|
if (event && typeof event.preventDefault === 'function') {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
const nameInput = document.getElementById('blacklist-name');
|
||||||
|
const urlInput = document.getElementById('blacklist-url');
|
||||||
|
|
||||||
|
const name = nameInput ? nameInput.value.trim() : '';
|
||||||
|
const url = urlInput ? urlInput.value.trim() : '';
|
||||||
|
|
||||||
|
// 简单验证
|
||||||
if (!name || !url) {
|
if (!name || !url) {
|
||||||
showErrorMessage('名称和URL不能为空');
|
showErrorMessage('名称和URL不能为空');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 验证URL格式
|
||||||
|
try {
|
||||||
|
new URL(url);
|
||||||
|
} catch (e) {
|
||||||
|
showErrorMessage('URL格式不正确');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
showLoading('添加黑名单中...');
|
showLoading('添加黑名单中...');
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/shield/blacklists', {
|
const response = await fetch('/api/shield/blacklists', {
|
||||||
@@ -447,13 +532,23 @@ async function handleAddBlacklist() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Failed to add blacklist');
|
// 尝试从响应中获取更详细的错误信息
|
||||||
|
let errorMessage = '添加黑名单失败';
|
||||||
|
try {
|
||||||
|
const errorData = await response.json();
|
||||||
|
if (errorData.error) {
|
||||||
|
errorMessage = errorData.error;
|
||||||
|
}
|
||||||
|
} catch (jsonError) {
|
||||||
|
// 忽略JSON解析错误
|
||||||
|
}
|
||||||
|
throw new Error(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
showSuccessMessage('黑名单添加成功');
|
showSuccessMessage('黑名单添加成功');
|
||||||
// 清空输入框
|
// 清空输入框
|
||||||
document.getElementById('blacklist-name').value = '';
|
if (nameInput) nameInput.value = '';
|
||||||
document.getElementById('blacklist-url').value = '';
|
if (urlInput) urlInput.value = '';
|
||||||
// 重新加载黑名单
|
// 重新加载黑名单
|
||||||
loadRemoteBlacklists();
|
loadRemoteBlacklists();
|
||||||
// 重新加载统计信息
|
// 重新加载统计信息
|
||||||
@@ -461,7 +556,7 @@ async function handleAddBlacklist() {
|
|||||||
hideLoading();
|
hideLoading();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error adding blacklist:', error);
|
console.error('Error adding blacklist:', error);
|
||||||
showErrorMessage('添加黑名单失败');
|
showErrorMessage(error.message || '添加黑名单失败');
|
||||||
hideLoading();
|
hideLoading();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user