This commit is contained in:
Alex Yang
2026-04-01 12:22:55 +08:00
parent 61789061ce
commit efebce3c39
46 changed files with 4797716 additions and 462145 deletions
+129 -19
View File
@@ -9,37 +9,37 @@ const pageDataCache = {
dashboard: {
timestamp: 0,
data: null,
expiry: 5 * 60 * 1000 // 5分钟过期
expiry: 5 * 60 * 1000 // 5 分钟过期
},
logs: {
timestamp: 0,
data: null,
expiry: 5 * 60 * 1000 // 5分钟过期
expiry: 5 * 60 * 1000 // 5 分钟过期
},
shield: {
timestamp: 0,
data: null,
expiry: 10 * 60 * 1000 // 10分钟过期
expiry: 10 * 60 * 1000 // 10 分钟过期
},
hosts: {
timestamp: 0,
data: null,
expiry: 10 * 60 * 1000 // 10分钟过期
expiry: 10 * 60 * 1000 // 10 分钟过期
},
gfwlist: {
timestamp: 0,
data: null,
expiry: 10 * 60 * 1000 // 10分钟过期
expiry: 10 * 60 * 1000 // 10 分钟过期
},
about: {
timestamp: 0,
data: null,
expiry: 10 * 60 * 1000 // 10分钟过期
expiry: 10 * 60 * 1000 // 10 分钟过期
},
threats: {
timestamp: 0,
data: null,
expiry: 5 * 60 * 1000 // 5分钟过期
expiry: 5 * 60 * 1000 // 5 分钟过期
}
},
@@ -89,6 +89,11 @@ const pageDataCache = {
// 页面可见性状态
let isPageVisible = true;
// 全局 WebSocket 管理器 - 用于服务器状态更新
let serverStatusWebSocket = null;
let serverStatusReconnectTimer = null;
let isWebSocketProcessingPaused = false;
// 页面初始化函数 - 根据当前hash值初始化对应页面
function initPageByHash() {
const hash = window.location.hash.substring(1);
@@ -101,6 +106,7 @@ function initPageByHash() {
document.getElementById('gfwlist-content'),
document.getElementById('query-content'),
document.getElementById('domain-content'),
document.getElementById('whois-content'),
document.getElementById('logs-content'),
document.getElementById('config-content'),
document.getElementById('about-content'),
@@ -125,10 +131,11 @@ function initPageByHash() {
const titles = {
'dashboard': '仪表盘',
'shield': '屏蔽管理',
'hosts': 'Hosts管理',
'gfwlist': 'GFWList管理',
'query': 'DNS屏蔽查询',
'hosts': 'Hosts 管理',
'gfwlist': 'GFWList 管理',
'query': 'DNS 屏蔽查询',
'domain': '域名查询',
'whois': '域名信息',
'logs': '查询日志',
'config': '系统设置',
'about': '关于',
@@ -208,6 +215,12 @@ function initPageByHash() {
}
}
}, 0);
} else if (hash === 'whois') {
setTimeout(() => {
if (typeof initWhoisPage === 'function') {
initWhoisPage();
}
}, 0);
}
}
@@ -542,20 +555,103 @@ function updateThemeIcon(toggleElement, isDark) {
}
}
// 处理页面可见性变化
// 建立 WebSocket 连接监听服务器状态
function connectServerStatusWebSocket() {
try {
const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsUrl = `${wsProtocol}//${window.location.host}/ws/stats`;
serverStatusWebSocket = new WebSocket(wsUrl);
serverStatusWebSocket.onopen = function() {
console.log('服务器状态 WebSocket 连接已建立');
if (serverStatusReconnectTimer) {
clearTimeout(serverStatusReconnectTimer);
serverStatusReconnectTimer = null;
}
};
serverStatusWebSocket.onmessage = function(event) {
if (isWebSocketProcessingPaused) {
return;
}
try {
const data = JSON.parse(event.data);
if (data.type === 'stats_update' || data.type === 'initial_data') {
updateSystemStatusFromWebSocket(data.data);
}
} catch (error) {
console.error('处理服务器状态 WebSocket 消息失败:', error);
}
};
serverStatusWebSocket.onclose = function() {
console.warn('服务器状态 WebSocket 连接已关闭');
serverStatusWebSocket = null;
setupServerStatusReconnect();
};
serverStatusWebSocket.onerror = function(error) {
console.error('服务器状态 WebSocket 连接错误:', error);
};
} catch (error) {
console.error('创建服务器状态 WebSocket 连接失败:', error);
}
}
function setupServerStatusReconnect() {
if (serverStatusReconnectTimer) {
return;
}
serverStatusReconnectTimer = setTimeout(() => {
connectServerStatusWebSocket();
}, 5000);
}
function updateSystemStatusFromWebSocket(stats) {
if (!isPageVisible) {
return;
}
const uptimeElement = document.getElementById('uptime');
if (uptimeElement && stats.uptime) {
uptimeElement.textContent = `正常运行中 | ${formatUptime(stats.uptime)}`;
uptimeElement.classList.remove('text-danger');
}
}
function pauseWebSocketProcessing() {
isWebSocketProcessingPaused = true;
console.log('已暂停 WebSocket 数据处理');
}
function resumeWebSocketProcessing() {
isWebSocketProcessingPaused = false;
console.log('已恢复 WebSocket 数据处理');
}
function clearAllTimers() {
if (serverStatusReconnectTimer) {
clearTimeout(serverStatusReconnectTimer);
serverStatusReconnectTimer = null;
}
}
function handleVisibilityChange() {
if (document.visibilityState === 'visible') {
isPageVisible = true;
console.log('页面变为可见');
// 当页面重新可见时,检查当前页面是否需要刷新数据
resumeWebSocketProcessing();
const hash = window.location.hash.substring(1);
// 只有当缓存过期时才重新加载数据
if (hash && !pageDataCache.isCacheValid(hash)) {
console.log(`缓存已过期,重新加载${hash}页面数据`);
// 根据当前页面类型重新加载数据
if (hash === 'dashboard' && typeof loadDashboardData === 'function') {
loadDashboardData();
} else if (hash === 'logs' && typeof loadLogs === 'function') {
@@ -571,11 +667,15 @@ function handleVisibilityChange() {
}
}
// 更新系统状态
updateSystemStatus();
if (!serverStatusWebSocket) {
connectServerStatusWebSocket();
}
} else {
isPageVisible = false;
console.log('页面变为隐藏');
pauseWebSocketProcessing();
clearAllTimers();
}
}
@@ -593,14 +693,24 @@ function init() {
// 初始化页面
initPageByHash();
// 添加hashchange事件监听,处理浏览器前进/后退按钮
// 添加 hashchange 事件监听,处理浏览器前进/后退按钮
window.addEventListener('hashchange', initPageByHash);
// 添加页面可见性变化监听
document.addEventListener('visibilitychange', handleVisibilityChange);
// 定期更新系统状态
setInterval(updateSystemStatus, 5000);
// 建立 WebSocket 连接监听服务器状态(替代原来的 setInterval 轮询)
connectServerStatusWebSocket();
// 页面卸载时清理资源
window.addEventListener('beforeunload', () => {
if (serverStatusWebSocket) {
serverStatusWebSocket.close();
}
if (serverStatusReconnectTimer) {
clearTimeout(serverStatusReconnectTimer);
}
});
}
// 页面加载完成后执行初始化