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); } } 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 += `

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

📍 ${server.http_url}
${server.status === 'online' ? '🟢' : '🔴'} ${server.status === 'online' ? '在线' : '离线'}
|
任务: ${server.current_tasks || 0}/${server.max_concurrent_tasks || 1}
|
检查: ${formatHealthCheck(server.last_health_check)}
${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 += `
${task.workflow_name || '未命名工作流'}
${statusText}
ID: ${task.id}
创建时间: ${formatTime(task.created_at)}
${task.completed_at ? `
完成时间: ${formatTime(task.completed_at)}
` : ''}
${task.error_message ? `
❌ 错误: ${task.error_message}
` : ''} ${task.result ? `
📊 ${formatResult(task.result)}
` : ''}
`; }); } // 页面加载时自动刷新数据 document.addEventListener('DOMContentLoaded', refreshData); // 每30秒自动刷新一次 setInterval(refreshData, 30000);