|
|
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;
|
|
|
};
|