import { useEffect } from 'react'; import { useTranslation } from 'react-i18next' import clsx from 'clsx'; import type { ReactShapeConfig } from '@antv/x6-react-shape'; import { Flex } from 'antd'; import { CheckCircleFilled, CloseCircleFilled, LoadingOutlined } from '@ant-design/icons'; import { graphNodeLibrary, edgeAttrs } from '../../constant'; import NodeTools from './NodeTools' const LoopNode: ReactShapeConfig['component'] = ({ node, graph }) => { const data = node.getData() || {}; const { t } = useTranslation() useEffect(() => { // 使用setTimeout确保在所有节点都添加完成后再创建连线 const timer = setTimeout(() => { initNodes() checkAndAddAddNode() }, 50) return () => clearTimeout(timer) }, [graph]) const checkAndAddAddNode = () => { if (!graph) return; const childNodes = graph.getNodes().filter((n: any) => n.getData()?.cycle === data.id); const cycleStartNodes = childNodes.filter((n: any) => n.getData()?.type === 'cycle-start'); // 如果只有一个cycle-start节点且没有其他类型的子节点,则添加add-node if (cycleStartNodes.length === 1 && childNodes.length === 1) { const cycleStartNode = cycleStartNodes[0]; const cycleStartBBox = cycleStartNode.getBBox(); const addNode = graph.addNode({ ...graphNodeLibrary.addStart, x: cycleStartBBox.x + 84, y: cycleStartBBox.y + 4, data: { type: 'add-node', label: t('workflow.addNode'), icon: '+', parentId: node.id, cycle: data.id, }, }); node.addChild(addNode); // 连接cycle-start和add-node const sourcePorts = cycleStartNode.getPorts(); const targetPorts = addNode.getPorts(); const sourcePort = sourcePorts.find((port: any) => port.group === 'right')?.id || 'right'; const targetPort = targetPorts.find((port: any) => port.group === 'left')?.id || 'left'; // 然后创建连线 graph.addEdge({ source: { cell: cycleStartNode.id, port: sourcePort }, target: { cell: addNode.id, port: targetPort }, ...edgeAttrs, }); cycleStartNode.toFront() addNode.toFront() } } const initNodes = () => { // 检查是否存在cycle为当前节点ID的子节点,若存在则不调用initNodes,避免重复创建 const existingCycleNodes = graph.getNodes().filter((n: any) => n.getData()?.cycle === data.id ); if (existingCycleNodes.length > 0) return; // 添加默认子节点 const parentBBox = node.getBBox(); const centerX = parentBBox.x + 24; const centerY = parentBBox.y + 70; const cycleStartNodeId = `cycle_start_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` const cycleStartNode = graph.addNode({ ...graphNodeLibrary.cycleStart, x: centerX, y: centerY, id: cycleStartNodeId, data: { id: cycleStartNodeId, type: 'cycle-start', parentId: node.id, isDefault: true, // 标记为默认节点,不可删除 cycle: data.id, }, }); const addNode = graph.addNode({ ...graphNodeLibrary.addStart, x: centerX + 84, y: centerY + 4, data: { type: 'add-node', label: t('workflow.addNode'), icon: '+', parentId: node.id, cycle: data.id, }, }); node.addChild(cycleStartNode) node.addChild(addNode) const sourcePorts = cycleStartNode.getPorts() const targetPorts = addNode.getPorts() let sourcePort = sourcePorts.find((port: any) => port.group === 'right')?.id || 'right'; const edgeConfig = { source: { cell: cycleStartNode.id, port: sourcePort }, target: { cell: addNode.id, port: targetPorts.find((port: any) => port.group === 'left')?.id || 'left' }, ...edgeAttrs } graph.addEdge(edgeConfig) setTimeout(() => { cycleStartNode.toFront() addNode.toFront() }, 0) } return (
{data.name ?? t(`workflow.${data.type}`)}
{data.executionStatus === 'completed' ? : data.executionStatus === 'failed' ? : data.executionStatus === 'running' ? : null }
); }; export default LoopNode;