feat(flowEditor): 新增自定义节点并优化节点类型注册

- 新增 LocalNode 组件用于系统组件节点
- 在 flowEditor/index.tsx 中实现节点类型动态注册
- 更新 sideBar/config/localNodeData.ts,修正 JSON 封装节点类型
- 删除未使用的 handleNode 组件
- 优化 draggableNode 组件,移除冗余代码
master
钟良源 5 months ago
parent e4ff51fdb3
commit 88f6b9f4eb

@ -14,10 +14,11 @@ import {
SelectionMode SelectionMode
} from '@xyflow/react'; } from '@xyflow/react';
import '@xyflow/react/dist/style.css'; import '@xyflow/react/dist/style.css';
import { nodeTypes } from './node'; import { nodeTypeMap, nodeTypes, registerNodeType } from './node';
import SideBar from './sideBar/sideBar'; import SideBar from './sideBar/sideBar';
import { convertFlowData } from '@/utils/convertFlowData'; import { convertFlowData } from '@/utils/convertFlowData';
import { exampleFlowData } from '@/pages/flowEditor/test/exampleFlowData'; import { exampleFlowData } from '@/pages/flowEditor/test/exampleFlowData';
import LocalNode from '@/pages/flowEditor/node/localNode/LocalNode';
import CustomEdge from './components/customEdge'; import CustomEdge from './components/customEdge';
const edgeTypes: EdgeTypes = { const edgeTypes: EdgeTypes = {
@ -84,10 +85,11 @@ const FlowEditor: React.FC = () => {
data: { ...nodeData.data, title: nodeData.nodeName, type: nodeData.nodeType } data: { ...nodeData.data, title: nodeData.nodeName, type: nodeData.nodeType }
}; };
console.log('newNode:', newNode); // 将未定义的节点动态追加进nodeTypes
const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key));
if (!nodeMap.includes(nodeData.nodeType)) registerNodeType(nodeData.nodeType, LocalNode, nodeData.nodeName);
setNodes((nds) => nds.concat(newNode)); setNodes((nds) => nds.concat(newNode));
console.log('nodes:', nodes);
}, },
[reactFlowInstance] [reactFlowInstance]
); );

@ -1,10 +1,9 @@
import React from 'react'; import React from 'react';
import { Handle, Position, useStore } from '@xyflow/react'; import { useStore } from '@xyflow/react';
import styles from '@/pages/flowEditor/node/style/base.module.less'; import styles from '@/pages/flowEditor/node/style/base.module.less';
import NodeContent from '@/pages/flowEditor/components/nodeContent'; import NodeContent from '@/pages/flowEditor/components/nodeContent';
const DraggableNode = ({ data, id }: { data: any; id: string }) => { const DraggableNode = ({ data, id }: { data: any; id: string }) => {
console.log(data, id );
const title = data.title || '任务节点'; const title = data.title || '任务节点';
// 获取节点选中状态 - 适配React Flow v12 API // 获取节点选中状态 - 适配React Flow v12 API

@ -1,14 +0,0 @@
import React from 'react';
import { Handle, Position } from '@xyflow/react';
const CustomNode = ({ data }) => {
return (
<>
<div style={{ padding: '10px 20px' }}>
{data.label}
</div>
</>
);
};
export default CustomNode;

@ -4,6 +4,7 @@ import StartNode from './startNode/StartNode';
import EndNode from './endNode/EndNode'; import EndNode from './endNode/EndNode';
import DraggableNode from './draggableNode/DraggableNode'; import DraggableNode from './draggableNode/DraggableNode';
import BasicNode from './basicNode/BasicNode'; import BasicNode from './basicNode/BasicNode';
import LocalNode from './localNode/LocalNode';
// 定义所有可用的节点类型 // 定义所有可用的节点类型
export const nodeTypes: NodeTypes = { export const nodeTypes: NodeTypes = {

@ -0,0 +1,25 @@
import React from 'react';
import { useStore } from '@xyflow/react';
import styles from '@/pages/flowEditor/node/style/base.module.less';
import NodeContent from '@/pages/flowEditor/components/nodeContent';
const LocalNode = ({ data, id }: { data: any; id: string }) => {
const title = data.title || '系统组件';
// 获取节点选中状态 - 适配React Flow v12 API
const isSelected = useStore((state) =>
state.nodeLookup.get(id)?.selected || false
);
return (
<div className={`${styles['node-container']} ${isSelected ? styles.selected : ''}`}>
<div className={styles['node-header']} style={{ backgroundColor: '#1890ff' }}>
{title}
</div>
<NodeContent data={data} />
</div>
);
};
export default LocalNode;

@ -27,7 +27,7 @@ const nodeDefinitions = [
{ nodeName: '事件发送', nodeType: 'EVENTSEND', nodeGroup: 'common' }, { nodeName: '事件发送', nodeType: 'EVENTSEND', nodeGroup: 'common' },
{ nodeName: 'JSON转字符串', nodeType: 'JSON2STR', nodeGroup: 'common' }, { nodeName: 'JSON转字符串', nodeType: 'JSON2STR', nodeGroup: 'common' },
{ nodeName: '字符串转JSON', nodeType: 'STR2JSON', nodeGroup: 'common' }, { nodeName: '字符串转JSON', nodeType: 'STR2JSON', nodeGroup: 'common' },
{ nodeName: 'JSON封装', nodeType: 'JSON_CONVERT', nodeGroup: 'common' }, { nodeName: 'JSON封装', nodeType: 'JSONCONVERT', nodeGroup: 'common' },
{ nodeName: '结果展示', nodeType: 'RESULT', nodeGroup: 'common' }, { nodeName: '结果展示', nodeType: 'RESULT', nodeGroup: 'common' },
{ nodeName: '图片展示', nodeType: 'IMAGE', nodeGroup: 'common' }, { nodeName: '图片展示', nodeType: 'IMAGE', nodeGroup: 'common' },
{ nodeName: '代码编辑器', nodeType: 'CODE', nodeGroup: 'common' }, { nodeName: '代码编辑器', nodeType: 'CODE', nodeGroup: 'common' },

Loading…
Cancel
Save