import React from 'react'; type WorkflowRuntime = { mode?: string; }; const LOCAL_WORKFLOW_URL = '/workflow-ui/'; const DOCKER_WORKFLOW_URL = '/api/comfyui/proxy/'; export default function Workflows() { const [ready, setReady] = React.useState(false); const [loading, setLoading] = React.useState(true); const [message, setMessage] = React.useState('正在加载工作流前端...'); const [workflowUrl, setWorkflowUrl] = React.useState(LOCAL_WORKFLOW_URL); const [backendLabel, setBackendLabel] = React.useState(''); const [reloadKey, setReloadKey] = React.useState(0); const iframeRef = React.useRef(null); const openFullscreen = () => { window.open(workflowUrl, '_blank', 'noopener,noreferrer'); }; const reloadFrame = () => { if (iframeRef.current) { setLoading(true); iframeRef.current.src = workflowUrl; return; } setLoading(true); setMessage('正在重新检查工作流入口...'); setReloadKey((value) => value + 1); }; React.useEffect(() => { let cancelled = false; const controller = new AbortController(); const loadRuntime = async () => { const runtimeResponse = await fetch('/api/workflow-ui/runtime', { signal: controller.signal }); const runtime = runtimeResponse.ok ? ((await runtimeResponse.json()) as WorkflowRuntime) : {}; const dockerMode = runtime.mode === 'docker'; const targetUrl = dockerMode ? DOCKER_WORKFLOW_URL : LOCAL_WORKFLOW_URL; if (cancelled) return; setBackendLabel(resolveBackendLabel(runtime.mode)); setWorkflowUrl(targetUrl); const response = await fetch(targetUrl, { signal: controller.signal }); if (cancelled) return; setReady(response.ok); setLoading(false); setMessage(response.ok ? '' : 'Workflow Studio 前端未构建,请先执行 workflow-ui:install'); }; void loadRuntime().catch((error) => { if (cancelled || error?.name === 'AbortError') return; setReady(false); setLoading(false); setMessage('工作流入口不可用,请检查服务配置'); }); return () => { cancelled = true; controller.abort(); }; }, [reloadKey]); return (
工作流
{backendLabel &&
{backendLabel}
}
{ready ? (
{loading && (
正在连接工作流前端...
)}