1
This commit is contained in:
parent
2df3cb3074
commit
0893ea614a
@ -3,13 +3,13 @@ import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { Button, Space, Card, Row, Col, message } from 'antd';
|
||||
import { ArrowLeftOutlined, SaveOutlined, PlayCircleOutlined } from '@ant-design/icons';
|
||||
import { Graph, Cell } from '@antv/x6';
|
||||
import { DagreLayout } from '@antv/layout';
|
||||
import { getDefinitionDetail, saveDefinition } from '../service';
|
||||
import NodePanel from './components/NodePanel';
|
||||
import NodeConfigDrawer from './components/NodeConfigModal';
|
||||
import { NodeDefinition } from './types';
|
||||
import { validateWorkflow } from './utils/validator';
|
||||
import {
|
||||
NODE_REGISTRY_CONFIG,
|
||||
GRID_CONFIG,
|
||||
CONNECTING_CONFIG,
|
||||
HIGHLIGHTING_CONFIG,
|
||||
@ -27,59 +27,13 @@ const WorkflowDesign: React.FC = () => {
|
||||
const [configModalVisible, setConfigModalVisible] = useState(false);
|
||||
const [definitionData, setDefinitionData] = useState<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (id) {
|
||||
loadDefinitionDetail();
|
||||
}
|
||||
}, [id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (graphContainerRef.current) {
|
||||
// 注册自定义节点
|
||||
Object.entries(NODE_REGISTRY_CONFIG).forEach(([name, config]) => {
|
||||
Graph.registerNode(name, config, true);
|
||||
});
|
||||
|
||||
const graph = new Graph({
|
||||
container: graphContainerRef.current,
|
||||
grid: GRID_CONFIG,
|
||||
connecting: {
|
||||
...CONNECTING_CONFIG,
|
||||
validateConnection({ sourceView, targetView, sourceMagnet, targetMagnet }) {
|
||||
if (!sourceMagnet || !targetMagnet) {
|
||||
return false;
|
||||
}
|
||||
if (sourceView === targetView) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
validateMagnet({ magnet }) {
|
||||
const portGroup = magnet?.getAttribute('port-group');
|
||||
return !!portGroup;
|
||||
},
|
||||
createEdge() {
|
||||
return this.createEdge({
|
||||
attrs: {
|
||||
line: DEFAULT_STYLES.edge,
|
||||
},
|
||||
zIndex: -1,
|
||||
});
|
||||
},
|
||||
},
|
||||
highlighting: {
|
||||
...HIGHLIGHTING_CONFIG,
|
||||
magnetAdsorbed: {
|
||||
name: 'stroke',
|
||||
args: {
|
||||
attrs: {
|
||||
fill: '#fff',
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
connecting: CONNECTING_CONFIG,
|
||||
highlighting: HIGHLIGHTING_CONFIG,
|
||||
snapline: true,
|
||||
history: true,
|
||||
clipboard: true,
|
||||
@ -115,19 +69,110 @@ const WorkflowDesign: React.FC = () => {
|
||||
|
||||
setGraph(graph);
|
||||
|
||||
// 在 graph 初始化完成后加载数据
|
||||
if (id) {
|
||||
loadDefinitionDetail(graph, id);
|
||||
}
|
||||
|
||||
return () => {
|
||||
graph.dispose();
|
||||
};
|
||||
}
|
||||
}, [graphContainerRef]);
|
||||
}, [graphContainerRef, id]);
|
||||
|
||||
const loadDefinitionDetail = async () => {
|
||||
const loadDefinitionDetail = async (graphInstance: Graph, definitionId: number) => {
|
||||
try {
|
||||
const response = await getDefinitionDetail(id);
|
||||
const response = await getDefinitionDetail(definitionId);
|
||||
console.log('加载到的工作流数据:', response);
|
||||
setTitle(`工作流设计 - ${response.name}`);
|
||||
setDefinitionData(response);
|
||||
|
||||
// 清空画布
|
||||
graphInstance.clearCells();
|
||||
|
||||
const nodeMap = new Map();
|
||||
|
||||
// 动态注册节点类型
|
||||
response.graph.nodes.forEach((nodeData: any) => {
|
||||
// 根据节点类型动态注册
|
||||
const nodeConfig = {
|
||||
inherit: 'rect', // 使用基础的矩形节点作为默认继承
|
||||
width: nodeData.graph.size.width,
|
||||
height: nodeData.graph.size.height,
|
||||
attrs: {
|
||||
body: nodeData.graph.style,
|
||||
},
|
||||
ports: nodeData.graph.ports
|
||||
};
|
||||
|
||||
// 根据形状选择不同的基础节点类型
|
||||
if (nodeData.graph.shape === 'circle') {
|
||||
nodeConfig.inherit = 'circle';
|
||||
} else if (nodeData.graph.shape === 'polygon') {
|
||||
nodeConfig.inherit = 'polygon';
|
||||
}
|
||||
|
||||
// 注册节点类型
|
||||
Graph.registerNode(nodeData.code, nodeConfig, true);
|
||||
|
||||
// 创建节点
|
||||
const node = graphInstance.addNode({
|
||||
id: nodeData.id,
|
||||
shape: nodeData.code,
|
||||
position: nodeData.graph.position || { x: 100, y: 100 },
|
||||
attrs: {
|
||||
body: nodeData.graph.style,
|
||||
label: {
|
||||
text: nodeData.name,
|
||||
fill: '#000000',
|
||||
fontSize: 12,
|
||||
}
|
||||
},
|
||||
nodeDefinition: nodeData,
|
||||
});
|
||||
nodeMap.set(nodeData.id, node);
|
||||
});
|
||||
|
||||
// 创建边
|
||||
response.graph.edges.forEach((edge: any) => {
|
||||
const sourceNode = nodeMap.get(edge.from);
|
||||
const targetNode = nodeMap.get(edge.to);
|
||||
if (sourceNode && targetNode) {
|
||||
graphInstance.addEdge({
|
||||
source: { cell: sourceNode.id },
|
||||
target: { cell: targetNode.id },
|
||||
attrs: {
|
||||
line: DEFAULT_STYLES.edge
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
attrs: {
|
||||
label: {
|
||||
text: edge.name || '',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 自动布局
|
||||
const layout = new DagreLayout({
|
||||
type: 'dagre',
|
||||
rankdir: 'LR',
|
||||
align: 'UL',
|
||||
ranksep: 80,
|
||||
nodesep: 50,
|
||||
});
|
||||
|
||||
const cells = graphInstance.getCells();
|
||||
layout.layout(cells);
|
||||
graphInstance.resetCells(cells);
|
||||
graphInstance.centerContent();
|
||||
} catch (error) {
|
||||
console.error('Failed to load workflow definition:', error);
|
||||
console.error('加载工作流定义失败:', error);
|
||||
message.error('加载工作流定义失败');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user