import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node'; import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; /** * 将提供的数据结构转换为适用于 flow editor 的 nodes 和 edges * @param flowData - 原始数据结构 * @returns 包含 nodes 和 edges 的对象 */ export const convertFlowData = (flowData: any) => { const nodes: any[] = []; const edges: any[] = []; if (!flowData || Object.keys(flowData).length === 0) return { nodes, edges }; // 处理节点配置 const nodeConfigs = flowData.main?.nodeConfigs || []; for (const nodeConfig of nodeConfigs) { // 确定节点类型 let nodeType = 'BASIC'; if (nodeConfig.nodeId === 'start') { nodeType = 'start'; } else if (nodeConfig.nodeId === 'end') { nodeType = 'end'; } else { nodeType = nodeConfig.component.type; } // 解析位置信息 let position = { x: 0, y: 0 }; try { const x6Data = JSON.parse(nodeConfig.x6); position = x6Data.position || { x: 0, y: 0 }; } catch (e) { console.warn('Failed to parse position for node:', nodeConfig.nodeId); } // 构造节点数据 const node: any = { id: nodeConfig.nodeId, type: nodeType, position, data: { title: nodeConfig.nodeName || nodeConfig.nodeId, parameters: { apiIns: [{ name: 'start', desc: '', dataType: '', defaultValue: '' }], apiOuts: [{ name: nodeConfig.nodeId === 'end' ? 'end' : 'done', desc: '', dataType: '', defaultValue: '' }], dataIns: nodeConfig.dataIns?.map((input: any) => ({ name: input.id, desc: input.desc, dataType: input.dataType, defaultValue: input.defaultValue })) || [], dataOuts: nodeConfig.dataOuts?.map((output: any) => ({ name: output.id, desc: output.desc, dataType: output.dataType, defaultValue: output.defaultValue })) || [] }, type: nodeType } }; // 如果是机械臂节点,添加组件标识信息 if (nodeConfig.component) { node.data.component = { compIdentifier: nodeConfig.component.compIdentifier, compInstanceIdentifier: nodeConfig.component.compInstanceIdentifier, customDef: nodeConfig.component?.customDef, type: nodeConfig.component.type }; } // 将未定义的节点动态追加进nodeTypes const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); // 目前默认添加的都是系统组件/本地组件 if (!nodeMap.includes(nodeType)) registerNodeType(nodeType, LocalNode, nodeConfig.nodeName); nodes.push(node); } // 处理连线配置 const lineConfigs = flowData.main?.lineConfigs || []; for (const lineConfig of lineConfigs) { const edge: any = { id: lineConfig.id, source: lineConfig.prev.nodeId, target: lineConfig.next.nodeId, sourceHandle: lineConfig.prev.endpointId, targetHandle: lineConfig.next.endpointId }; edges.push(edge); } return { nodes, edges }; }; /** * 将 flow editor 的 nodes 和 edges 数据结构转换回原始数据结构 * @param nodes - flow editor 的节点数组 * @param edges - flow editor 的连线数组 * @returns 原始数据结构 */ export const revertFlowData = (nodes: any[], edges: any[]) => { // 初始化返回的数据结构 const flowData: any = { id: 'main', nodeConfigs: [], lineConfigs: [] }; // 转换节点数据 if (nodes && nodes.length > 0) { flowData.nodeConfigs = nodes.map(node => { // 确定 nodeId 和 nodeName const nodeId = node.id; const nodeName = node.data?.title || nodeId; // 确定节点类型 let nodeType = node.type; // 特殊处理 start 和 end 节点 if (nodeId === 'start') { nodeType = 'start'; } else if (nodeId === 'end') { nodeType = 'end'; } // 构造 x6 数据(位置信息) const x6 = JSON.stringify({ position: node.position }); // 构造 nodeConfig 对象 const nodeConfig: any = { nodeId, nodeName, x6 }; // 处理 component 信息 if (node.data?.component) { nodeConfig.component = { type: nodeType, compIdentifier: node.data.component.compIdentifier, compInstanceIdentifier: node.data.component.compInstanceIdentifier }; if (node.data.component?.customDef) nodeConfig.component.customDef = node.data.component.customDef; } else if (nodeType !== 'start' && nodeType !== 'end') { // 对于非 start/end 节点,添加基本的 component 信息 nodeConfig.component = { type: nodeType }; } // 处理参数信息 const parameters = node.data?.parameters || {}; // 处理 dataIns(输入数据) if (parameters.dataIns && parameters.dataIns.length > 0) { nodeConfig.dataIns = parameters.dataIns.map((input: any) => ({ id: input.name, desc: input.desc, dataType: input.dataType, defaultValue: input.defaultValue })); } // 处理 dataOuts(输出数据) if (parameters.dataOuts && parameters.dataOuts.length > 0) { nodeConfig.dataOuts = parameters.dataOuts.map((output: any) => ({ id: output.name, desc: output.desc, dataType: output.dataType, defaultValue: output.defaultValue })); } return nodeConfig; }); } // 转换连线数据 if (edges && edges.length > 0) { flowData.lineConfigs = edges.map((edge, index) => { // 查找源节点和目标节点以确定连线类型 const sourceNode = nodes.find(node => node.id === edge.source); const targetNode = nodes.find(node => node.id === edge.target); let lineType = 'DATA'; // 默认为DATA类型 // 判断是否为CONVERT类型的连线 if (targetNode && ['JSONCONVERT', 'JSON2STR', 'STR2JSON'].includes(targetNode.type)) { lineType = 'CONVERT'; } // 判断是否为API类型的连线 else if (edge.sourceHandle && (edge.sourceHandle === 'apiOuts' || sourceNode?.data?.parameters?.apiOuts?.some((out: any) => out.name === edge.sourceHandle))) { lineType = 'API'; } else if (edge.targetHandle && (edge.targetHandle === 'apiIns' || targetNode?.data?.parameters?.apiIns?.some((inp: any) => inp.name === edge.targetHandle))) { lineType = 'API'; } return { id: edge.id || `edge_${index}`, // 如果没有 id,则生成一个 lineType, // 添加lineType属性 prev: { nodeId: edge.source, endpointId: edge.sourceHandle || 'done' // 默认使用 'done' }, next: { nodeId: edge.target, endpointId: edge.targetHandle || 'start' // 默认使用 'start' } }; }); } return flowData; };