refactor(flowEditor): 重构节点编辑器

- 将 LocalNodeEditor 组件拆分为多个独立的编辑器组件
- 新增 ConditionEditor、AndEditor、OrEditor等多个组件用于不同类型的节点编辑
- 优化节点编辑器的结构和样式,使用 ParamsTable 组件统一参数编辑界面
- 调整 NodeEditorProps接口,使 node 属性可选
master
钟良源 5 months ago
parent f9a8b66e8c
commit d92beca5c1

@ -1,87 +1,62 @@
import React from 'react'; import React from 'react';
import { NodeEditorProps } from './index'; import { NodeEditorProps } from './index';
import { Form, Input, Switch, Select } from '@arco-design/web-react'; import { Form, Input } from '@arco-design/web-react';
import ConditionEditor from './components/ConditionEditor';
import AndEditor from './components/AndEditor';
import OrEditor from './components/OrEditor';
import WaitEditor from './components/WaitEditor';
import LoopEditor from './components/LoopEditor';
import CycleEditor from './components/CycleEditor';
import EventListenEditor from './components/EventListenEditor';
import EventSendEditor from './components/EventSendEditor';
import JsonToStringEditor from './components/JsonToStringEditor';
import StringToJsonEditor from './components/StringToJsonEditor';
import JsonConvertEditor from './components/JsonConvertEditor';
import ResultEditor from './components/ResultEditor';
import ImageEditor from './components/ImageEditor';
import CodeEditor from './components/CodeEditor';
import RestEditor from './components/RestEditor';
const LocalNodeEditor: React.FC<NodeEditorProps> = ({ const LocalNodeEditor: React.FC<NodeEditorProps> = ({
node, node,
nodeData, nodeData,
updateNodeData updateNodeData
}) => { }) => {
// 根据LocalNode的不同类型渲染不同的编辑界面 // 根据LocalNode的不同类型渲染不同的编辑界面
const renderLocalNodeEditor = () => { const renderLocalNodeEditor = () => {
const localNodeType = nodeData.type || ''; const localNodeType = nodeData.type || '';
switch (localNodeType) { switch (localNodeType) {
case 'CONDITION': case 'CONDITION': // 条件选择
return ( return <ConditionEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
<> case 'AND': // 与门
<Form.Item label="节点标题"> return <AndEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
<Input case 'OR': // 或门
value={nodeData.title || ''} return <OrEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
onChange={(value) => updateNodeData('title', value)} case 'WAIT': // 等待
/> return <WaitEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
</Form.Item> case 'LOOP': // 循环
<Form.Item label="条件表达式"> return <LoopEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
<Input.TextArea case 'CYCLE': // 周期
value={nodeData.expression || ''} return <CycleEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
onChange={(value) => updateNodeData('expression', value)} case 'EVENTLISTENE': // 事件接收
placeholder="请输入条件表达式" return <EventListenEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
/> case 'EVENTSEND': // 事件发送
</Form.Item> return <EventSendEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
<Form.Item label="是否启用"> case 'JSON2STR': // JSON转字符串
<Switch return <JsonToStringEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
checked={nodeData.enabled || false} case 'STR2JSON': // 字符串转JSON
onChange={(value) => updateNodeData('enabled', value)} return <StringToJsonEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
/> case 'JSONCONVERT': // JSON封装
</Form.Item> return <JsonConvertEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
</> case 'RESULT': // 结果展示
); return <ResultEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
case 'IMAGE': // 图片展示
case 'WAIT': return <ImageEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
return ( case 'CODE': // 代码编辑器
<> return <CodeEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
<Form.Item label="节点标题"> case 'REST': // REST调用
<Input return <RestEditor nodeData={nodeData} updateNodeData={updateNodeData} />;
value={nodeData.title || ''}
onChange={(value) => updateNodeData('title', value)}
/>
</Form.Item>
<Form.Item label="等待时间(秒)">
<Input
value={nodeData.waitTime || ''}
onChange={(value) => updateNodeData('waitTime', value)}
type="number"
/>
</Form.Item>
</>
);
case 'LOOP':
return (
<>
<Form.Item label="节点标题">
<Input
value={nodeData.title || ''}
onChange={(value) => updateNodeData('title', value)}
/>
</Form.Item>
<Form.Item label="循环次数">
<Input
value={nodeData.loopCount || ''}
onChange={(value) => updateNodeData('loopCount', value)}
type="number"
/>
</Form.Item>
<Form.Item label="循环条件">
<Input.TextArea
value={nodeData.condition || ''}
onChange={(value) => updateNodeData('condition', value)}
placeholder="请输入循环条件"
/>
</Form.Item>
</>
);
default: default:
return ( return (
<> <>

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const AndEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default AndEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const CodeEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default CodeEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const ConditionEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default ConditionEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const CycleEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default CycleEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const EventListenEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default EventListenEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const EventSendEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default EventSendEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const ImageEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default ImageEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const JsonConvertEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default JsonConvertEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const JsonToStringEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default JsonToStringEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const LoopEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default LoopEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const OrEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default OrEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const RestEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default RestEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const ResultEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default ResultEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const StringToJsonEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default StringToJsonEditor;

@ -0,0 +1,24 @@
import React from 'react';
import { NodeEditorProps } from '@/pages/flowEditor/nodeEditors';
import { Typography } from '@arco-design/web-react';
import { IconUnorderedList } from '@arco-design/web-react/icon';
import ParamsTable from './ParamsTable';
const WaitEditor: React.FC<NodeEditorProps> = ({ nodeData, updateNodeData }) => {
return (
<>
<Typography.Title heading={5}><IconUnorderedList style={{ marginRight: 5 }} /></Typography.Title>
<ParamsTable
initialData={nodeData.parameters.dataIns || []}
onUpdateData={(data) => {
updateNodeData('parameters', {
...nodeData.parameters,
dataIns: data
});
}}
/>
</>
);
};
export default WaitEditor;

@ -7,7 +7,7 @@ import LocalNodeEditor from './LocalNodeEditor';
// 定义节点编辑器的属性接口 // 定义节点编辑器的属性接口
export interface NodeEditorProps { export interface NodeEditorProps {
node: Node; node?: Node;
nodeData: any; nodeData: any;
updateNodeData: (key: string, value: any) => void; updateNodeData: (key: string, value: any) => void;
} }

Loading…
Cancel
Save