// 解析URL参数 function getQueryParams() { const urlParams = new URLSearchParams(window.location.search); return { serverUUID: urlParams.get('serverUUID'), nodeUUID: urlParams.get('nodeUUID') }; } // 检查是否包含必要的URL参数 function checkParams() { const { serverUUID, nodeUUID } = getQueryParams(); if (!serverUUID || !nodeUUID) { alert('URL中缺少必要的参数: serverUUID 和 nodeUUID'); return false; } return true; } // 显示加载模态框 function showLoadingModal() { document.getElementById('loadingModal').classList.remove('hidden'); } // 隐藏加载模态框 function hideLoadingModal() { document.getElementById('loadingModal').classList.add('hidden'); } // 加载实例信息 function loadInstanceInfo() { showLoadingModal(); const { serverUUID, nodeUUID } = getQueryParams(); fetch(`php/api.php?action=getInstanceInfo&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`获取实例信息失败: ${data.message || '未知错误'}`); return; } const instanceInfo = data.data; let html = `

基础信息

实例名称: ${instanceInfo.name || '未命名'}

实例ID: ${instanceInfo.id}

实例UUID: ${serverUUID}

节点UUID: ${nodeUUID}

状态: ${instanceInfo.running ? '运行中' : '已停止'}

运行状态

${instanceInfo.running ? `

CPU使用率: ${instanceInfo.cpuUsage}%

内存使用: ${(instanceInfo.memoryUsage / 1024 / 1024).toFixed(2)} MB / ${(instanceInfo.totalMemory / 1024 / 1024).toFixed(2)} MB

运行时间: ${formatUptime(instanceInfo.uptime)}

` : `

实例未运行

`}
`; document.getElementById('instanceInfo').innerHTML = html; // 绑定按钮事件 document.getElementById('startInstance')?.addEventListener('click', startInstance); document.getElementById('stopInstance')?.addEventListener('click', stopInstance); // 显示模态框 document.getElementById('instanceModal').classList.remove('hidden'); }) .catch(error => { hideLoadingModal(); console.error('获取实例信息失败:', error); alert('获取实例信息失败,请检查网络连接或参数是否正确'); }); } // 格式化运行时间 function formatUptime(uptime) { const hours = Math.floor(uptime / 3600); const minutes = Math.floor((uptime % 3600) / 60); const seconds = uptime % 60; return `${hours}小时 ${minutes}分钟 ${seconds}秒`; } // 启动实例 function startInstance() { const { serverUUID, nodeUUID } = getQueryParams(); if (!confirm('确定要启动实例吗?')) return; showLoadingModal(); fetch(`php/api.php?action=startInstance&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`启动实例失败: ${data.message || '未知错误'}`); return; } alert('实例启动成功'); // 刷新实例信息 loadInstanceInfo(); }) .catch(error => { hideLoadingModal(); console.error('启动实例失败:', error); alert('启动实例失败,请检查网络连接或参数是否正确'); }); } // 停止实例 function stopInstance() { const { serverUUID, nodeUUID } = getQueryParams(); if (!confirm('确定要停止实例吗?')) return; showLoadingModal(); fetch(`php/api.php?action=stopInstance&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`停止实例失败: ${data.message || '未知错误'}`); return; } alert('实例停止成功'); // 刷新实例信息 loadInstanceInfo(); }) .catch(error => { hideLoadingModal(); console.error('停止实例失败:', error); alert('停止实例失败,请检查网络连接或参数是否正确'); }); } // 加载控制台 function loadConsole() { showLoadingModal(); const { serverUUID, nodeUUID } = getQueryParams(); fetch(`php/api.php?action=getConsole&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`获取控制台失败: ${data.message || '未知错误'}`); return; } // 清空控制台输出 document.getElementById('consoleOutput').innerHTML = ''; // 显示模态框 document.getElementById('consoleModal').classList.remove('hidden'); // 绑定发送命令事件 document.getElementById('sendConsoleCommand').addEventListener('click', sendConsoleCommand); // 监听输入框回车事件 document.getElementById('consoleInput').addEventListener('keypress', function(e) { if (e.key === 'Enter') { sendConsoleCommand(); } }); // 开始轮询控制台输出 startConsolePolling(); }) .catch(error => { hideLoadingModal(); console.error('获取控制台失败:', error); alert('获取控制台失败,请检查网络连接或参数是否正确'); }); } // 发送控制台命令 function sendConsoleCommand() { const { serverUUID, nodeUUID } = getQueryParams(); const command = document.getElementById('consoleInput').value.trim(); if (!command) return; showLoadingModal(); fetch(`php/api.php?action=sendConsoleCommand&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}&command=${encodeURIComponent(command)}`) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`发送命令失败: ${data.message || '未知错误'}`); return; } // 添加命令到输出 addConsoleOutput(`> ${command}\n`); // 清空输入框 document.getElementById('consoleInput').value = ''; }) .catch(error => { hideLoadingModal(); console.error('发送命令失败:', error); alert('发送命令失败,请检查网络连接或参数是否正确'); }); } // 添加控制台输出 function addConsoleOutput(text) { const output = document.getElementById('consoleOutput'); output.innerHTML += text; output.scrollTop = output.scrollHeight; } // 开始控制台轮询 function startConsolePolling() { const { serverUUID, nodeUUID } = getQueryParams(); // 清除之前的轮询 if (window.consolePollingInterval) { clearInterval(window.consolePollingInterval); } // 开始新的轮询 window.consolePollingInterval = setInterval(() => { fetch(`php/api.php?action=getConsoleOutput&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) .then(response => response.json()) .then(data => { if (data.status === 200) { addConsoleOutput(data.data); } }) .catch(error => { console.error('轮询控制台输出失败:', error); }); }, 1000); // 每秒轮询一次 } // 停止控制台轮询 function stopConsolePolling() { if (window.consolePollingInterval) { clearInterval(window.consolePollingInterval); window.consolePollingInterval = null; } } // 加载文件管理 function loadFiles() { showLoadingModal(); const { serverUUID, nodeUUID } = getQueryParams(); fetch(`php/api.php?action=getFiles&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`获取文件列表失败: ${data.message || '未知错误'}`); return; } const files = data.data; let html = `

文件管理

`; files.forEach(file => { html += ` `; }); html += `
名称 类型 大小 修改时间 操作
${file.name} ${file.type} ${formatFileSize(file.size)} ${new Date(file.modifiedTime).toLocaleString()} ${file.type === 'file' ? ` ` : ''}
`; document.getElementById('fileContent').innerHTML = html; // 显示模态框 document.getElementById('filesModal').classList.remove('hidden'); // 绑定事件 document.getElementById('refreshFiles').addEventListener('click', loadFiles); document.getElementById('uploadFile').addEventListener('click', showUploadFileDialog); // 绑定文件操作事件 document.querySelectorAll('.view-file').forEach(button => { button.addEventListener('click', function() { viewFile(this.dataset.path); }); }); document.querySelectorAll('.download-file').forEach(button => { button.addEventListener('click', function() { downloadFile(this.dataset.path); }); }); document.querySelectorAll('.edit-file').forEach(button => { button.addEventListener('click', function() { editFile(this.dataset.path); }); }); document.querySelectorAll('.delete-file').forEach(button => { button.addEventListener('click', function() { deleteFile(this.dataset.path); }); }); }) .catch(error => { hideLoadingModal(); console.error('获取文件列表失败:', error); alert('获取文件列表失败,请检查网络连接或参数是否正确'); }); } // 格式化文件大小 function formatFileSize(size) { if (size < 1024) { return `${size} B`; } else if (size < 1024 * 1024) { return `${(size / 1024).toFixed(2)} KB`; } else if (size < 1024 * 1024 * 1024) { return `${(size / 1024 / 1024).toFixed(2)} MB`; } else { return `${(size / 1024 / 1024 / 1024).toFixed(2)} GB`; } } // 显示上传文件对话框 function showUploadFileDialog() { const { serverUUID, nodeUUID } = getQueryParams(); const input = document.createElement('input'); input.type = 'file'; input.onchange = function() { if (this.files && this.files[0]) { uploadFile(this.files[0], serverUUID, nodeUUID); } }; input.click(); } // 上传文件 function uploadFile(file, serverUUID, nodeUUID) { const formData = new FormData(); formData.append('file', file); formData.append('serverUUID', serverUUID); formData.append('nodeUUID', nodeUUID); formData.append('path', '/'); // 默认上传到根目录 showLoadingModal(); fetch('php/api.php?action=uploadFile', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`上传文件失败: ${data.message || '未知错误'}`); return; } alert('文件上传成功'); loadFiles(); // 刷新文件列表 }) .catch(error => { hideLoadingModal(); console.error('上传文件失败:', error); alert('上传文件失败,请检查网络连接或参数是否正确'); }); } // 查看文件 function viewFile(path) { const { serverUUID, nodeUUID } = getQueryParams(); showLoadingModal(); fetch(`php/api.php?action=viewFile&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}&path=${encodeURIComponent(path)}`) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`查看文件失败: ${data.message || '未知错误'}`); return; } alert(`文件内容:\n${data.data}`); }) .catch(error => { hideLoadingModal(); console.error('查看文件失败:', error); alert('查看文件失败,请检查网络连接或参数是否正确'); }); } // 下载文件 function downloadFile(path) { const { serverUUID, nodeUUID } = getQueryParams(); window.location.href = `php/api.php?action=downloadFile&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}&path=${encodeURIComponent(path)}`; } // 编辑文件 function editFile(path) { const { serverUUID, nodeUUID } = getQueryParams(); showLoadingModal(); fetch(`php/api.php?action=viewFile&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}&path=${encodeURIComponent(path)}`) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`编辑文件失败: ${data.message || '未知错误'}`); return; } // 显示编辑模态框 const modalHtml = `

编辑文件: ${path.split('/').pop()}

`; document.body.insertAdjacentHTML('beforeend', modalHtml); // 绑定保存按钮事件 document.getElementById('saveEditFile').addEventListener('click', function() { const content = document.getElementById('editFileContent').value; saveEditFile(path, content); }); // 绑定取消按钮事件 document.getElementById('cancelEditFile').addEventListener('click', function() { document.getElementById('editFileModal').remove(); }); }) .catch(error => { hideLoadingModal(); console.error('编辑文件失败:', error); alert('编辑文件失败,请检查网络连接或参数是否正确'); }); } // 保存编辑的文件 function saveEditFile(path, content) { const { serverUUID, nodeUUID } = getQueryParams(); const formData = new FormData(); formData.append('content', content); formData.append('serverUUID', serverUUID); formData.append('nodeUUID', nodeUUID); formData.append('path', path); showLoadingModal(); fetch('php/api.php?action=saveEditFile', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`保存文件失败: ${data.message || '未知错误'}`); return; } alert('文件保存成功'); document.getElementById('editFileModal').remove(); loadFiles(); // 刷新文件列表 }) .catch(error => { hideLoadingModal(); console.error('保存文件失败:', error); alert('保存文件失败,请检查网络连接或参数是否正确'); }); } // 删除文件 function deleteFile(path) { const { serverUUID, nodeUUID } = getQueryParams(); if (!confirm('确定要删除此文件/文件夹吗?此操作不可撤销')) return; showLoadingModal(); fetch(`php/api.php?action=deleteFile&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}&path=${encodeURIComponent(path)}`) .then(response => response.json()) .then(data => { hideLoadingModal(); if (data.status !== 200) { alert(`删除文件失败: ${data.message || '未知错误'}`); return; } alert('文件删除成功'); loadFiles(); // 刷新文件列表 }) .catch(error => { hideLoadingModal(); console.error('删除文件失败:', error); alert('删除文件失败,请检查网络连接或参数是否正确'); }); } // 初始化页面 function initPage() { // 检查URL参数 if (!checkParams()) return; // 绑定菜单点击事件 document.getElementById('dashboardLink').addEventListener('click', function() { document.getElementById('contentArea').innerHTML = `

仪表盘

这里将显示实例的概览信息。

`; // 绑定按钮事件 document.getElementById('viewInstanceInfo').addEventListener('click', loadInstanceInfo); }); document.getElementById('instancesLink').addEventListener('click', function() { document.getElementById('contentArea').innerHTML = `

实例信息

`; // 加载实例信息 loadInstanceInfo(); // 绑定刷新按钮事件 document.getElementById('refreshInstanceInfo').addEventListener('click', loadInstanceInfo); }); document.getElementById('filesLink').addEventListener('click', function() { document.getElementById('contentArea').innerHTML = `

文件管理

`; // 绑定按钮事件 document.getElementById('openFilesModal').addEventListener('click', loadFiles); }); document.getElementById('consoleLink').addEventListener('click', function() { document.getElementById('contentArea').innerHTML = `

控制台

`; // 绑定按钮事件 document.getElementById('openConsoleModal').addEventListener('click', loadConsole); }); // 绑定模态框关闭事件 document.getElementById('closeInstanceModal')?.addEventListener('click', function() { document.getElementById('instanceModal').classList.add('hidden'); }); document.getElementById('closeConsoleModal')?.addEventListener('click', function() { document.getElementById('consoleModal').classList.add('hidden'); stopConsolePolling(); // 停止轮询 }); document.getElementById('closeFilesModal')?.addEventListener('click', function() { document.getElementById('filesModal').classList.add('hidden'); }); } // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', initPage);