// 服务器管理相关代码 const servers = JSON.parse(localStorage.getItem("servers")) || []; let currentServer = null; let currentSocket = null; // DOM 元素 const serverList = document.getElementById("server-list"); const noServerMessage = document.getElementById("no-server-message"); const serverStatus = document.getElementById("server-status"); const currentServerName = document.getElementById("current-server-name"); // 初始化UI function initUI() { updateServerList(); if (servers.length > 0) { noServerMessage.style.display = "none"; serverStatus.style.display = "block"; connectToServer(servers[0]); } else { noServerMessage.style.display = "block"; serverStatus.style.display = "none"; } } // 更新服务器下拉列表 function updateServerList() { serverList.innerHTML = ""; if (servers.length === 0) { const emptyItem = document.createElement("div"); emptyItem.className = "dropdown-item"; emptyItem.textContent = "无服务器"; emptyItem.style.color = "#888"; emptyItem.style.cursor = "default"; serverList.appendChild(emptyItem); return; } servers.forEach((server, index) => { const serverItem = document.createElement("div"); serverItem.className = "dropdown-item"; serverItem.innerHTML = `
${server.name}
${server.address}
`; serverItem.addEventListener("click", (e) => { if (!e.target.classList.contains("delete-server")) { connectToServer(server); document.querySelector(".dropdown").classList.remove("open"); } }); // 添加删除按钮事件 const deleteBtn = serverItem.querySelector(".delete-server"); deleteBtn.addEventListener("click", (e) => { e.stopPropagation(); deleteServer(index); }); serverList.appendChild(serverItem); }); } // 连接到指定服务器 function connectToServer(server) { // 断开现有连接 if (currentSocket) { currentSocket.disconnect(); } currentServer = server; currentServerName.textContent = server.name; // 显示连接状态 document.getElementById("cpu-details").textContent = "连接中..."; // 建立新连接 currentSocket = io(server.address, { transports: ["websocket"], reconnectionAttempts: 3, timeout: 5000, }); // 设置事件监听器 setupSocketListeners(currentSocket); } // 设置Socket.IO监听器 function setupSocketListeners(socket) { socket.on("connect", () => { console.log("已连接到服务器:", currentServer.name); }); socket.on("connect_error", (error) => { console.error("连接错误:", error); document.getElementById("cpu-details").textContent = "连接失败"; }); socket.on("disconnect", (reason) => { console.log("断开连接:", reason); }); socket.on("status", (data) => { updateMemory({ totalmem: data.totalmem, freemem: data.freemem, }); updateCpuLoad(data.perCpuUsage); updateLoadAvg(data.loadavg); if (data.uptime) { updateUptime(data.uptime); } const cpuCoreUsages = data.perCpuUsage || []; updateCpuCores(cpuCoreUsages); }); } // 添加新服务器 function addServer(name, address) { // 验证地址格式 if (!address.startsWith("http://") && !address.startsWith("https://")) { address = "http://" + address; } const newServer = { name, address: address.replace(/\/$/, ""), // 移除末尾的斜杠 }; servers.push(newServer); localStorage.setItem("servers", JSON.stringify(servers)); if (servers.length === 1) { // 如果是第一个服务器,自动连接 noServerMessage.style.display = "none"; serverStatus.style.display = "block"; connectToServer(newServer); } updateServerList(); } // 删除服务器 function deleteServer(index) { if (currentServer && servers[index].name === currentServer.name) { if (currentSocket) { currentSocket.disconnect(); currentSocket = null; } if (servers.length === 1) { noServerMessage.style.display = "block"; serverStatus.style.display = "none"; } } servers.splice(index, 1); localStorage.setItem("servers", JSON.stringify(servers)); updateServerList(); // 如果还有服务器,连接到第一个 if (servers.length > 0 && !currentServer) { connectToServer(servers[0]); } } // 初始化模态框 const openModal = document.getElementById("openModal"); const closeModal = document.getElementById("closeModal"); const modal = document.getElementById("addServerModal"); const addServerBtn = document.getElementById("add-server-btn"); openModal.addEventListener("click", () => { modal.style.display = "flex"; document.getElementById("server-name").focus(); }); closeModal.addEventListener("click", () => { modal.style.display = "none"; }); // 点击背景区域关闭弹窗 window.addEventListener("click", (e) => { if (e.target === modal) { modal.style.display = "none"; } }); // 添加服务器按钮事件 addServerBtn.addEventListener("click", () => { const name = document.getElementById("server-name").value.trim(); const address = document.getElementById("server-address").value.trim(); if (name && address) { addServer(name, address); modal.style.display = "none"; document.getElementById("server-name").value = ""; document.getElementById("server-address").value = ""; } else { alert("请填写服务器名称和地址"); } }); // 回车键提交表单 document.getElementById("server-address").addEventListener("keypress", (e) => { if (e.key === "Enter") { addServerBtn.click(); } }); // 下拉菜单切换 const toggleBtn = document.querySelector(".dropdown-toggle"); const dropdown = document.querySelector(".dropdown"); toggleBtn.addEventListener("click", () => { dropdown.classList.toggle("open"); }); // 点击外部关闭菜单 document.addEventListener("click", (e) => { if (!dropdown.contains(e.target)) { dropdown.classList.remove("open"); } }); // 工具函数 function bytesToGB(bytes) { return (bytes / 1024 / 1024 / 1024).toFixed(2); } function updateMemory(mem) { const totalGB = bytesToGB(mem.totalmem); const freeGB = bytesToGB(mem.freemem); const usedGB = (totalGB - freeGB).toFixed(2); const usedPercent = ((usedGB / totalGB) * 100).toFixed(1); document.getElementById("mem-used").textContent = `${usedPercent}%`; document.getElementById("mem-progress").style.width = usedPercent + "%"; document.getElementById( "mem-details" ).textContent = `${usedGB} GB / ${totalGB} GB`; } function updateCpuLoad(perCpuUsage) { if (!perCpuUsage || perCpuUsage.length === 0) { document.getElementById("cpu-load").textContent = `N/A`; document.getElementById("cpu-progress").style.width = "0%"; document.getElementById("cpu-details").textContent = `无 CPU 使用数据`; return; } const sum = perCpuUsage.reduce((a, b) => a + b, 0); const avg = (sum / perCpuUsage.length).toFixed(1); document.getElementById("cpu-load").textContent = `${avg}%`; document.getElementById("cpu-progress").style.width = avg + "%"; document.getElementById("cpu-details").textContent = `每核CPU平均使用率`; } function updateLoadAvg(loadavg) { if (!loadavg || loadavg.length < 3) return; document.getElementById( "loadavg-values" ).textContent = `1min: ${loadavg[0].toFixed(2)}, 5min: ${loadavg[1].toFixed( 2 )}, 15min: ${loadavg[2].toFixed(2)}`; } function updateUptime(uptime) { if (!uptime) return; const days = Math.floor(uptime / 86400); const hours = Math.floor((uptime % 86400) / 3600); const minutes = Math.floor((uptime % 3600) / 60); const seconds = Math.floor(uptime % 60); let uptimeStr = ""; if (days > 0) uptimeStr += `${days}天 `; if (hours > 0 || days > 0) uptimeStr += `${hours}小时 `; if (minutes > 0 || hours > 0 || days > 0) uptimeStr += `${minutes}分 `; uptimeStr += `${seconds}秒`; document.getElementById("uptime-value").textContent = uptimeStr; } function updateCpuCores(usages) { const container = document.getElementById("cpu-cores"); container.innerHTML = ""; usages.forEach((percent, idx) => { const coreDiv = document.createElement("div"); coreDiv.className = "cpu-core"; // 创建进度条 const progressBar = document.createElement("div"); progressBar.className = "progress-bar"; progressBar.style.height = "6px"; progressBar.style.marginTop = "6px"; progressBar.style.backgroundColor = "#2a2a2a"; const progress = document.createElement("div"); progress.className = "progress"; progress.style.height = "100%"; progress.style.width = `${percent}%`; progress.style.backgroundColor = percent > 80 ? "#e91e63" : percent > 60 ? "#ff9800" : "#0bc"; progressBar.appendChild(progress); coreDiv.textContent = `核心 ${idx + 1}: ${percent}%`; coreDiv.appendChild(progressBar); container.appendChild(coreDiv); }); } // 初始化应用 initUI();