/** * 将应用流程数据转换为适用于 flow editor 的 nodes 和 edges * @param appFlowData - 应用流程原始数据结构,长度为2的数组,每个元素代表一个节点 * @returns 包含 nodes 和 edges 的对象,格式与 convertFlowData 兼容 */ export const convertAppFlowData = (appFlowData: any[]) => { const nodes: any[] = []; const edges: any[] = []; // 如果没有数据,返回空数组 if (!appFlowData || appFlowData.length === 0) { return { nodes, edges }; } // 处理每个应用流程数据项(每个应用作为一个节点) appFlowData.forEach((app: any, index: number) => { // 构造节点数据 const node: any = { id: app.appId || `app_${index}`, type: 'APP', position: { x: 200 + index * 300, y: 200 }, data: { title: app.name || `应用${index + 1}`, parameters: { // eventListenes 作为 apiIns(输入) apiIns: app.eventListenes ? app.eventListenes.map((event: any) => ({ name: event.eventName, desc: event.description || '', dataType: '', defaultValue: '', topic: event.topic })) : [], // eventSends 作为 apiOuts(输出) apiOuts: app.eventSends ? app.eventSends.map((event: any) => ({ name: event.eventName, desc: event.description || '', dataType: '', defaultValue: '', topic: event.topic })) : [], // 提取 dataIns 和 dataOuts 属性 dataIns: [], dataOuts: [] }, type: 'APP', component: { type: 'APP', appId: app.appId, customDef: JSON.stringify({ eventListenes: app.eventListenes || [], eventSends: app.eventSends || [] }) } } }; // 处理 dataIns(来自 eventListenes 的 dataOuts) if (app.eventListenes && app.eventListenes.length > 0) { app.eventListenes.forEach((event: any) => { if (event.dataOuts && event.dataOuts.length > 0) { node.data.parameters.dataIns = [...node.data.parameters.dataIns, ...event.dataOuts]; } }); } // 处理 dataOuts(来自 eventSends 的 dataIns) if (app.eventSends && app.eventSends.length > 0) { app.eventSends.forEach((event: any) => { if (event.dataIns && event.dataIns.length > 0) { node.data.parameters.dataOuts = [...node.data.parameters.dataOuts, ...event.dataIns]; } }); } nodes.push(node); }); // 遍历所有节点对 for (let i = 0; i < nodes.length; i++) { for (let j = 0; j < nodes.length; j++) { if (i !== j) { // 不与自己比较 const sourceNode = nodes[i]; const targetNode = nodes[j]; // 检查源节点的 eventSends (apiOuts) 和目标节点的 eventListenes (apiIns) const sourceEvents = sourceNode.data.component?.customDef ? JSON.parse(sourceNode.data.component.customDef).eventSends || [] : []; const targetEvents = targetNode.data.component?.customDef ? JSON.parse(targetNode.data.component.customDef).eventListenes || [] : []; // 比较事件的 topic 是否匹配 sourceEvents.forEach((sourceEvent: any, outIndex: number) => { targetEvents.forEach((targetEvent: any, inIndex: number) => { // 当 topic 匹配且不是 **empty** 占位符时创建边 if (sourceEvent.topic && targetEvent.topic && sourceEvent.topic === targetEvent.topic && !sourceEvent.topic.includes('**empty**') && !targetEvent.topic.includes('**empty**')) { edges.push({ id: `e-${sourceNode.id}-${targetNode.id}-${outIndex}-${inIndex}`, source: sourceNode.id, target: targetNode.id, sourceHandle: sourceEvent.eventName, targetHandle: targetEvent.eventName, type: 'custom', lineType: 'lineType', data: { displayData: { name: '事件1', eventId: 'eventId', topic: 'topic' } } }); } }); }); } } } return { nodes, edges }; };