refactor(flowEditor): 重构流程编辑器节点组件
- 提取公共组件 NodeContent 用于渲染节点内容和连接端点 -重构 StartNode 和 EndNode 组件,使用新的 NodeContent 组件- 添加 convertFlowData 工具函数用于转换流程数据 - 新增 exampleFlowData 作为测试数据 - 更新 FlowEditor 组件,使用转换后的流程数据初始化节点和边master
parent
b784cb158b
commit
b9b5ec2f19
@ -0,0 +1,96 @@
|
||||
import React from 'react';
|
||||
import styles from '@/pages/flowEditor/node/style/base.module.less';
|
||||
import { Handle, Position } from '@xyflow/react';
|
||||
|
||||
|
||||
interface NodeContentData {
|
||||
parameters?: {
|
||||
inputs?: any[];
|
||||
outputs?: any[];
|
||||
};
|
||||
showFooter?: boolean;
|
||||
type?: string;
|
||||
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const NodeContent = ({ data }: { data: NodeContentData }) => {
|
||||
const inputs = data.parameters?.inputs || [];
|
||||
const outputs = data.parameters?.outputs || [];
|
||||
const showFooter = data.showFooter || false;
|
||||
return (
|
||||
<>
|
||||
{/*content栏*/}
|
||||
<div className={styles['node-content']}>
|
||||
{inputs.length > 0 && (
|
||||
<div className={styles['node-inputs']}>
|
||||
{inputs.map((input, index) => (
|
||||
<div key={`input-${index}`} className={styles['node-input-label']}>
|
||||
{input.name || `输入${index + 1}`}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{outputs.length > 0 && (
|
||||
<div className={styles['node-outputs']}>
|
||||
{outputs.map((output, index) => (
|
||||
<div key={`output-${index}`} style={{ fontSize: '12px', padding: '2px 0' }}>
|
||||
{output.name || `输出${index + 1}`}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/*footer栏*/}
|
||||
{showFooter && (
|
||||
<div className={styles['node-footer']}>
|
||||
暂定的footer
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 默认连接端点*/}
|
||||
<Handle
|
||||
type={data.type === 'start' ? 'source' : 'target'}
|
||||
position={data.type === 'start' ? Position.Right : Position.Left}
|
||||
id={data.type === 'start' ? 'start-source' : 'end-target'}
|
||||
style={{
|
||||
background: '#555',
|
||||
top: '40px'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/*输入参数连接端点*/}
|
||||
{inputs.map((_, index) => (
|
||||
<Handle
|
||||
key={`input-handle-${index}`}
|
||||
type="target"
|
||||
position={Position.Left}
|
||||
id={`input-${index}`}
|
||||
style={{
|
||||
background: '#555',
|
||||
top: `${60 + index * 20}px`
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/*输出参数连接端点*/}
|
||||
{outputs.map((_, index) => (
|
||||
<Handle
|
||||
key={`output-handle-${index}`}
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
id={`output-${index}`}
|
||||
style={{
|
||||
background: '#555',
|
||||
// top: `${80 + inputs.length * 20 + index * 20}px`
|
||||
top: `${60 + index * 20}px`
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default NodeContent;
|
||||
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* 将提供的数据结构转换为适用于 flow editor 的 nodes 和 edges
|
||||
* @param flowData - 原始数据结构
|
||||
* @returns 包含 nodes 和 edges 的对象
|
||||
*/
|
||||
export const convertFlowData = (flowData: any) => {
|
||||
const nodes: any[] = [];
|
||||
const edges: any[] = [];
|
||||
|
||||
// 处理节点配置
|
||||
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: {
|
||||
inputs: nodeConfig.dataIns?.map((input: any) => ({
|
||||
name: input.id,
|
||||
desc: input.desc,
|
||||
dataType: input.dataType,
|
||||
defaultValue: input.defaultValue
|
||||
})) || [],
|
||||
outputs: nodeConfig.dataOuts?.map((output: any) => ({
|
||||
name: output.id,
|
||||
desc: output.desc,
|
||||
dataType: output.dataType,
|
||||
defaultValue: output.defaultValue
|
||||
})) || []
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 如果是机械臂节点,添加组件标识信息
|
||||
if (nodeConfig.component) {
|
||||
node.data.component = {
|
||||
compIdentifier: nodeConfig.component.compIdentifier,
|
||||
compInstanceIdentifier: nodeConfig.component.compInstanceIdentifier
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
console.log('nodes, edges:', nodes, edges);
|
||||
|
||||
return { nodes, edges };
|
||||
};
|
||||
Loading…
Reference in New Issue