import { useState } from 'react'; import { Popover } from 'antd'; import clsx from 'clsx'; import type { ReactShapeConfig } from '@antv/x6-react-shape'; import { nodeLibrary, graphNodeLibrary } from '../../constant'; import { useTranslation } from 'react-i18next'; const AddNode: ReactShapeConfig['component'] = ({ node, graph }) => { const data = node?.getData() || {}; const { t } = useTranslation(); const [open, setOpen] = useState(false); const handleNodeSelect = (selectedNodeType: any) => { const parentBBox = node.getBBox(); const cycleId = data.cycle; const id = `${selectedNodeType.type.replace(/-/g, '_') }_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` const newNode = graph.addNode({ ...(graphNodeLibrary[selectedNodeType.type] || graphNodeLibrary.default), x: parentBBox.x, y: parentBBox.y, id, data: { id, type: selectedNodeType.type, icon: selectedNodeType.icon, name: t(`workflow.${selectedNodeType.type}`), cycle: cycleId, parentId: data.parentId, config: selectedNodeType.config || {} }, }); // 将新节点添加为父节点的子节点 if (cycleId) { const parentNode = graph.getNodes().find((n: any) => n.getData()?.id === cycleId); if (parentNode) { parentNode.addChild(newNode); } } const incomingEdges = graph.getIncomingEdges(node); const outgoingEdges = graph.getOutgoingEdges(node); incomingEdges?.forEach(edge => { graph.addEdge({ source: { cell: edge.getSourceCellId(), port: edge.getSourcePortId() }, target: { cell: newNode.id, port: newNode.getPorts().find((port: any) => port.group === 'left')?.id || 'left' }, attrs: edge.getAttrs() }); }); outgoingEdges?.forEach(edge => { const targetCell = graph.getCellById(edge.getTargetCellId()) as any; const targetPortId = targetCell?.getPorts?.()?.find((port: any) => port.group === 'left')?.id || edge.getTargetPortId(); graph.addEdge({ source: { cell: newNode.id, port: newNode.getPorts().find((port: any) => port.group === 'right')?.id || 'right' }, target: { cell: edge.getTargetCellId(), port: targetPortId }, attrs: edge.getAttrs(), zIndex: 3 }); }); // 删除所有add-node类型的节点 graph.getNodes().forEach((n: any) => { if (n.getData()?.type === 'add-node' && n.getData()?.cycle === cycleId) { n.remove(); } }); // 自动调整循环节点大小 const loopNode = graph.getNodes().find((n: any) => n.getData()?.id === cycleId); if (loopNode) { const adjustLoopSize = () => { const childNodes = graph.getNodes().filter((n: any) => n.getData()?.cycle === cycleId); if (childNodes.length > 0) { const bounds = childNodes.reduce((acc, child) => { const bbox = child.getBBox(); return { minX: Math.min(acc.minX, bbox.x), minY: Math.min(acc.minY, bbox.y), maxX: Math.max(acc.maxX, bbox.x + bbox.width), maxY: Math.max(acc.maxY, bbox.y + bbox.height) }; }, { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }); const padding = 20; const newWidth = Math.max(240, bounds.maxX - bounds.minX + padding * 2); const newHeight = Math.max(120, bounds.maxY - bounds.minY + padding * 2); loopNode.prop('size', { width: newWidth, height: newHeight }); } }; adjustLoopSize(); // 监听子节点移动事件 const childNodes = graph.getNodes().filter((n: any) => n.getData()?.cycle === cycleId); childNodes.forEach((childNode: any) => { childNode.on('change:position', adjustLoopSize); }); } setOpen(false); }; const content = (