# 新增 LOOP 类节点模板(基于当前重构版本) 这份模板用于你现在这套 Flow Core(`loopFactory + nodeRegistry + useFlowCallbacks`)下,新增“成对节点/分支类”能力。 > 适用场景:像 `LOOP_START/LOOP_END` 这种需要一次创建多个节点和连边的节点族。 --- ## 1. 推荐做法(先看) 不要在 `useFlowCallbacks` 里直接手写大段节点/边构造。按现在的模式: 1. 在 `src/utils/flow/` 新增工厂(如 `xxxFactory.ts`) 2. 暴露: - 节点对(或节点组)构造函数 - 组内连接边构造函数 - 外部插入连接边构造函数(可选) 3. 在 `useFlowCallbacks` 只负责调用工厂 + setNodes/setEdges + snapshot --- ## 2. 工厂模板 **路径示例**:`src/utils/flow/retryFactory.ts` ```ts import { Edge } from '@xyflow/react'; export const createRetryNodePair = (position: { x: number; y: number }) => { const retryStartNode: any = { id: `RETRY_START-${Date.now()}`, type: 'RETRY', position: { x: position.x, y: position.y }, data: { title: '重试开始', type: 'RETRY_START', parameters: { apiIns: [{ name: 'start', desc: '', dataType: '', defaultValue: '' }], apiOuts: [{ name: 'done', desc: '', dataType: '', defaultValue: '' }], dataIns: [], dataOuts: [], }, component: {}, }, }; const retryEndNode: any = { id: `RETRY_END-${Date.now()}`, type: 'RETRY', position: { x: position.x + 400, y: position.y }, data: { title: '重试结束', type: 'RETRY_END', parameters: { apiIns: [ { name: 'continue', desc: '', dataType: '', defaultValue: '' }, ], apiOuts: [{ name: 'break', desc: '', dataType: '', defaultValue: '' }], dataIns: [], dataOuts: [], }, component: { type: 'RETRY_END', customDef: JSON.stringify({ retryStartNodeId: retryStartNode.id }), retryStartNodeId: retryStartNode.id, }, }, }; retryStartNode.data.component = { type: 'RETRY_START', customDef: JSON.stringify({ retryEndNodeId: retryEndNode.id }), }; return { retryStartNode, retryEndNode }; }; export const createRetryGroupEdge = ( retryStartId: string, retryEndId: string ): Edge => ({ id: `${retryStartId}-${retryEndId}-group`, source: retryStartId, target: retryEndId, sourceHandle: `${retryStartId}-group`, targetHandle: `${retryEndId}-group`, type: 'custom', }); ``` --- ## 3. useFlowCallbacks 接入模板 ```ts import { createRetryNodePair, createRetryGroupEdge, } from '@/utils/flow/retryFactory'; import { ensureNodeTypeRegistered } from '@/utils/flow/nodeRegistry'; import { dispatchFlowSnapshotAsync } from '@/utils/flow/snapshot'; const addRetryNodeWithStartEnd = useCallback( (position: { x: number; y: number }) => { const { retryStartNode, retryEndNode } = createRetryNodePair(position); const groupEdge = createRetryGroupEdge(retryStartNode.id, retryEndNode.id); ensureNodeTypeRegistered('RETRY', '重试'); setNodes((nds) => { const newNodes = [...nds, retryStartNode, retryEndNode]; dispatchFlowSnapshotAsync({ nodes: [...newNodes], edges: [...edges, groupEdge], }); return newNodes; }); setEdges((eds) => [...eds, groupEdge]); }, [edges] ); ``` --- ## 4. 类型映射模板 **文件**:`src/utils/flow/nodeRegistry.ts` ```ts case 'RETRY': return LoopNode; // 或你自己的专用节点组件 ``` > 早期可复用 `LoopNode/LocalNode`,后续再拆专用展示组件。 --- ## 5. 新增“边上插入该类节点”的模板(可选) 如需在边上插入节点组,建议像 `LOOP` 一样提供工厂函数: - `createXxxNodePair(position)` - `createXxxGroupEdge(startId, endId)` - `createXxxInsertConnectionEdges({ sourceId, sourceHandle, targetId, targetHandle, ... })` 这样 `addNodeOnEdge` 里只拼装调用,不再手写边结构。