From 9b3ffe70f5ede801ff63b9c1377e1a7abc2ce3a1 Mon Sep 17 00:00:00 2001 From: iHeyTang Date: Tue, 19 Aug 2025 15:26:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E7=9B=91=E6=8E=A7?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=88=B7=E6=96=B0=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E5=92=8C=E4=BB=BB=E5=8A=A1=E5=88=97=E8=A1=A8=E7=9A=84=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E6=A0=BC=E5=BC=8F=EF=BC=8C=E6=8F=90=E5=8D=87=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BD=93=E9=AA=8C=E5=92=8C=E5=8F=AF=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- workflow_service/static/js/monitor.js | 299 +++++++++++++++----------- 1 file changed, 170 insertions(+), 129 deletions(-) diff --git a/workflow_service/static/js/monitor.js b/workflow_service/static/js/monitor.js index f40beb9..65823ce 100644 --- a/workflow_service/static/js/monitor.js +++ b/workflow_service/static/js/monitor.js @@ -1,168 +1,209 @@ async function refreshData() { - try { - // 获取运行概览 - 更新为新的API路径 - const runMetrics = await fetch('/api/run/metrics').then(r => r.json()); - document.getElementById('running-tasks').textContent = runMetrics.running_tasks; - document.getElementById('pending-tasks').textContent = runMetrics.pending_tasks; - document.getElementById('completed-tasks').textContent = runMetrics.completed_tasks; - document.getElementById('total-tasks').textContent = runMetrics.total_tasks_24h; - - // 获取服务器状态 - 使用现有的list接口 - const serverStatus = await fetch('/api/comfy/list').then(r => r.json()); - updateServerStatus(serverStatus); - - // 获取运行列表 - 更新为新的API路径 - const runs = await fetch('/api/run').then(r => r.json()); - updateRecentTasks(runs); - - } catch (error) { - console.error('刷新数据失败:', error); - } + try { + // 获取运行概览 - 更新为新的API路径 + const runMetrics = await fetch("/api/run/metrics").then((r) => r.json()); + document.getElementById("running-tasks").textContent = + runMetrics.running_tasks; + document.getElementById("pending-tasks").textContent = + runMetrics.pending_tasks; + document.getElementById("completed-tasks").textContent = + runMetrics.completed_tasks; + document.getElementById("total-tasks").textContent = + runMetrics.total_tasks_24h; + + // 获取服务器状态 - 使用现有的list接口 + const serverStatus = await fetch("/api/comfy/list").then((r) => r.json()); + updateServerStatus(serverStatus); + + // 获取运行列表 - 更新为新的API路径 + const runs = await fetch("/api/run").then((r) => r.json()); + updateRecentTasks(runs); + } catch (error) { + console.error("刷新数据失败:", error); + } } function updateServerStatus(servers) { - const container = document.getElementById('server-status'); - container.innerHTML = ''; - - if (servers.length === 0) { - container.innerHTML = '

暂无服务器信息

'; - return; - } - - servers.forEach(server => { - const statusClass = server.status === 'online' ? 'online' : 'offline'; - const statusColor = server.status === 'online' ? 'status-online' : 'status-offline'; - - // 格式化时间 - const formatTime = (timeStr) => { - if (!timeStr) return 'N/A'; - try { - const date = new Date(timeStr); - const now = new Date(); - const diff = now - date; - - if (diff < 60000) return '刚刚'; - if (diff < 3600000) return Math.floor(diff / 60000) + '分钟前'; - if (diff < 86400000) return Math.floor(diff / 3600000) + '小时前'; - return date.toLocaleDateString(); - } catch { - return timeStr; - } - }; - - // 格式化健康检查时间 - const formatHealthCheck = (timeStr) => { - if (!timeStr) return 'N/A'; - try { - const date = new Date(timeStr); - const now = new Date(); - const diff = now - date; - - if (diff > 86400000) return '⚠️ 检查超时'; // 超过1天 - if (diff > 3600000) return '⚠️ 检查延迟'; // 超过1小时 - if (diff < 60000) return '✅ 刚刚'; - if (diff < 3600000) return `✅ ${Math.floor(diff / 60000)}分钟前`; - return `✅ ${Math.floor(diff / 3600000)}小时前`; - } catch { - return timeStr; - } - }; - - container.innerHTML += ` + const container = document.getElementById("server-status"); + container.innerHTML = ""; + + if (servers.length === 0) { + container.innerHTML = + '

暂无服务器信息

'; + return; + } + + servers.forEach((server) => { + const statusClass = server.status === "online" ? "online" : "offline"; + const statusColor = + server.status === "online" ? "status-online" : "status-offline"; + + // 格式化时间 + const formatTime = (timeStr) => { + if (!timeStr) return "N/A"; + try { + const date = new Date(timeStr); + const now = new Date(); + const diff = now - date; + + if (diff < 60000) return "刚刚"; + if (diff < 3600000) return Math.floor(diff / 60000) + "分钟前"; + if (diff < 86400000) return Math.floor(diff / 3600000) + "小时前"; + return date.toLocaleDateString(); + } catch { + return timeStr; + } + }; + + // 格式化健康检查时间 + const formatHealthCheck = (timeStr) => { + if (!timeStr) return "N/A"; + try { + const date = new Date(timeStr); + const now = new Date(); + const diff = now - date; + + if (diff > 86400000) return "⚠️ 检查超时"; // 超过1天 + if (diff > 3600000) return "⚠️ 检查延迟"; // 超过1小时 + if (diff < 60000) return "✅ 刚刚"; + if (diff < 3600000) return `✅ ${Math.floor(diff / 60000)}分钟前`; + return `✅ ${Math.floor(diff / 3600000)}小时前`; + } catch { + return timeStr; + } + }; + + container.innerHTML += `
-

${server.name || '未命名'}

+

${server.name || "未命名"}

📍 ${server.http_url}
- ${server.status === 'online' ? '🟢' : '🔴'} - ${server.status === 'online' ? '在线' : '离线'} + ${ + server.status === "online" ? "🟢" : "🔴" + } + ${ + server.status === "online" ? "在线" : "离线" + }
|
- 任务: ${server.current_tasks || 0}/${server.max_concurrent_tasks || 1} + 任务: ${ + server.current_tasks || 0 + }/${server.max_concurrent_tasks || 1}
|
- 检查: ${formatHealthCheck(server.last_health_check)} + 检查: ${formatHealthCheck( + server.last_health_check + )}
- ${server.error ? `
${server.error}
` : ''} + ${ + server.error + ? `
${server.error}
` + : "" + }
`; - }); + }); } function updateRecentTasks(tasks) { - const container = document.getElementById('recent-tasks'); - container.innerHTML = ''; - - if (tasks.length === 0) { - container.innerHTML = '

暂无任务记录

'; - return; - } - - tasks.forEach(task => { - const statusClass = 'status-' + task.status.toLowerCase(); - const statusText = { - 'pending': '等待中', - 'running': '运行中', - 'completed': '已完成', - 'failed': '失败' - }[task.status] || task.status; - - // 格式化时间 - const formatTime = (timeStr) => { - if (!timeStr) return 'N/A'; - try { - return new Date(timeStr).toLocaleString(); - } catch { - return timeStr; - } - }; - - // 格式化结果数据 - const formatResult = (result) => { - if (!result) return '暂无结果'; - try { - const parsed = JSON.parse(result); - if (typeof parsed === 'object') { - // 如果是对象,尝试提取关键信息 - if (parsed.images && Array.isArray(parsed.images)) { - return `生成图片: ${parsed.images.length} 张\n完整结果: ${JSON.stringify(parsed, null, 2)}`; - } - if (parsed.output && typeof parsed.output === 'object') { - return `输出数据: ${Object.keys(parsed.output).length} 项\n完整结果: ${JSON.stringify(parsed, null, 2)}`; - } - return `完整结果: ${JSON.stringify(parsed, null, 2)}`; - } - return `完整结果: ${String(result)}`; - } catch { - return `完整结果: ${String(result)}`; - } - }; - - container.innerHTML += ` + const container = document.getElementById("recent-tasks"); + container.innerHTML = ""; + + if (tasks.length === 0) { + container.innerHTML = + '

暂无任务记录

'; + return; + } + + tasks.forEach((task) => { + const statusClass = "status-" + task.status.toLowerCase(); + const statusText = + { + pending: "等待中", + running: "运行中", + completed: "已完成", + failed: "失败", + }[task.status] || task.status; + + // 格式化时间 + const formatTime = (timeStr) => { + if (!timeStr) return "N/A"; + try { + return new Date(timeStr).toLocaleString(); + } catch { + return timeStr; + } + }; + + // 格式化结果数据 + const formatResult = (result) => { + if (!result) return "暂无结果"; + try { + const parsed = JSON.parse(result); + if (typeof parsed === "object") { + // 如果是对象,尝试提取关键信息 + if (parsed.images && Array.isArray(parsed.images)) { + return `生成图片: ${ + parsed.images.length + } 张\n完整结果: ${JSON.stringify(parsed, null, 2)}`; + } + if (parsed.output && typeof parsed.output === "object") { + return `输出数据: ${ + Object.keys(parsed.output).length + } 项\n完整结果: ${JSON.stringify(parsed, null, 2)}`; + } + return `完整结果: ${JSON.stringify(parsed, null, 2)}`; + } + return `完整结果: ${String(result)}`; + } catch { + return `完整结果: ${String(result)}`; + } + }; + + container.innerHTML += `
-
${task.workflow_name || '未命名工作流'}
+
${ + task.workflow_name || "未命名工作流" + }
${statusText}
ID: ${task.id}
创建时间: ${formatTime(task.created_at)}
- ${task.completed_at ? `
完成时间: ${formatTime(task.completed_at)}
` : ''} + ${ + task.completed_at + ? `
完成时间: ${formatTime( + task.completed_at + )}
` + : "" + }
- ${task.error_message ? `
❌ 错误: ${task.error_message}
` : ''} - ${task.result ? `
📊 ${formatResult(task.result)}
` : ''} + ${ + task.error_message + ? `
❌ 错误: ${task.error_message}
` + : "" + } + ${ + task.result + ? `
📊 ${formatResult( + task.result + )}
` + : "" + }
`; - }); + }); } // 页面加载时自动刷新数据 -document.addEventListener('DOMContentLoaded', refreshData); +document.addEventListener("DOMContentLoaded", refreshData); // 每30秒自动刷新一次 setInterval(refreshData, 30000);