增加工具栏提示。
This commit is contained in:
parent
387c4d6ddd
commit
ffc8e412d8
@ -29,13 +29,15 @@ const WorkflowDesign: React.FC = () => {
|
||||
const [configModalVisible, setConfigModalVisible] = useState(false);
|
||||
const [definitionData, setDefinitionData] = useState<any>(null);
|
||||
const [nodeDefinitions, setNodeDefinitions] = useState<NodeDefinition[]>([]);
|
||||
const [isNodeDefinitionsLoaded, setIsNodeDefinitionsLoaded] = useState(false);
|
||||
|
||||
// 加载节点定义列表
|
||||
// 首先加载节点定义列表
|
||||
useEffect(() => {
|
||||
const loadNodeDefinitions = async () => {
|
||||
try {
|
||||
const data = await getNodeDefinitionList();
|
||||
setNodeDefinitions(data);
|
||||
setIsNodeDefinitionsLoaded(true);
|
||||
} catch (error) {
|
||||
console.error('加载节点定义失败:', error);
|
||||
message.error('加载节点定义失败');
|
||||
@ -44,74 +46,77 @@ const WorkflowDesign: React.FC = () => {
|
||||
loadNodeDefinitions();
|
||||
}, []);
|
||||
|
||||
// 等待节点定义加载完成后再初始化图形
|
||||
useEffect(() => {
|
||||
if (graphContainerRef.current) {
|
||||
const graph = new Graph({
|
||||
container: graphContainerRef.current,
|
||||
grid: GRID_CONFIG,
|
||||
connecting: CONNECTING_CONFIG,
|
||||
highlighting: HIGHLIGHTING_CONFIG,
|
||||
snapline: true,
|
||||
history: true,
|
||||
clipboard: true,
|
||||
selecting: true,
|
||||
keyboard: true,
|
||||
background: {
|
||||
color: '#f5f5f5',
|
||||
},
|
||||
mousewheel: {
|
||||
enabled: true,
|
||||
modifiers: ['ctrl', 'meta'],
|
||||
factor: 1.1,
|
||||
maxScale: 1.5,
|
||||
minScale: 0.5,
|
||||
},
|
||||
panning: {
|
||||
enabled: true,
|
||||
eventTypes: ['rightMouseDown'],
|
||||
},
|
||||
preventDefaultContextMenu: true,
|
||||
});
|
||||
|
||||
// 显示/隐藏连接桩
|
||||
graph.on('node:mouseenter', ({ node }) => {
|
||||
const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`);
|
||||
ports.forEach((port) => {
|
||||
port.setAttribute('style', 'visibility: visible');
|
||||
});
|
||||
});
|
||||
|
||||
graph.on('node:mouseleave', ({ node }) => {
|
||||
const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`);
|
||||
ports.forEach((port) => {
|
||||
port.setAttribute('style', 'visibility: hidden');
|
||||
});
|
||||
});
|
||||
|
||||
// 节点双击事件
|
||||
graph.on('node:dblclick', ({ node }) => {
|
||||
const nodeType = node.getProp('type');
|
||||
// 从节点定义列表中找到对应的定义
|
||||
const definition = nodeDefinitions.find(def => def.type === nodeType);
|
||||
if (definition) {
|
||||
setSelectedNode(node);
|
||||
setSelectedNodeDefinition(definition);
|
||||
setConfigModalVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
setGraph(graph);
|
||||
|
||||
// 在 graph 初始化完成后加载数据
|
||||
if (id) {
|
||||
loadDefinitionDetail(graph, id);
|
||||
}
|
||||
|
||||
return () => {
|
||||
graph.dispose();
|
||||
};
|
||||
if (!isNodeDefinitionsLoaded || !graphContainerRef.current) {
|
||||
return;
|
||||
}
|
||||
}, [graphContainerRef, id, nodeDefinitions]);
|
||||
|
||||
const graph = new Graph({
|
||||
container: graphContainerRef.current,
|
||||
grid: GRID_CONFIG,
|
||||
connecting: CONNECTING_CONFIG,
|
||||
highlighting: HIGHLIGHTING_CONFIG,
|
||||
snapline: true,
|
||||
history: true,
|
||||
clipboard: true,
|
||||
selecting: true,
|
||||
keyboard: true,
|
||||
background: {
|
||||
color: '#f5f5f5',
|
||||
},
|
||||
mousewheel: {
|
||||
enabled: true,
|
||||
modifiers: ['ctrl', 'meta'],
|
||||
factor: 1.1,
|
||||
maxScale: 1.5,
|
||||
minScale: 0.5,
|
||||
},
|
||||
panning: {
|
||||
enabled: true,
|
||||
eventTypes: ['rightMouseDown'],
|
||||
},
|
||||
preventDefaultContextMenu: true,
|
||||
});
|
||||
|
||||
// 显示/隐藏连接桩
|
||||
graph.on('node:mouseenter', ({ node }) => {
|
||||
const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`);
|
||||
ports.forEach((port) => {
|
||||
port.setAttribute('style', 'visibility: visible');
|
||||
});
|
||||
});
|
||||
|
||||
graph.on('node:mouseleave', ({ node }) => {
|
||||
const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`);
|
||||
ports.forEach((port) => {
|
||||
port.setAttribute('style', 'visibility: hidden');
|
||||
});
|
||||
});
|
||||
|
||||
// 节点双击事件
|
||||
graph.on('node:dblclick', ({ node }) => {
|
||||
const nodeType = node.getProp('type');
|
||||
// 从节点定义列表中找到对应的定义
|
||||
const definition = nodeDefinitions.find(def => def.type === nodeType);
|
||||
if (definition) {
|
||||
setSelectedNode(node);
|
||||
setSelectedNodeDefinition(definition);
|
||||
setConfigModalVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
setGraph(graph);
|
||||
|
||||
// 在 graph 初始化完成后加载数据
|
||||
if (id) {
|
||||
loadDefinitionDetail(graph, id);
|
||||
}
|
||||
|
||||
return () => {
|
||||
graph.dispose();
|
||||
};
|
||||
}, [graphContainerRef, id, nodeDefinitions, isNodeDefinitionsLoaded]);
|
||||
|
||||
const loadDefinitionDetail = async (graphInstance: Graph, definitionId: number) => {
|
||||
try {
|
||||
@ -124,12 +129,13 @@ const WorkflowDesign: React.FC = () => {
|
||||
const nodeMap = new Map();
|
||||
|
||||
// 创建节点
|
||||
response.graph.nodes.forEach((nodeData: any) => {
|
||||
console.log('Creating node with data:', nodeData); // 添加日志
|
||||
const node = addNodeToGraph(graphInstance, nodeData);
|
||||
response.graph.nodes.forEach((workflowDefinitionNode: any) => {
|
||||
console.log('Creating node with data:', workflowDefinitionNode); // 添加日志
|
||||
|
||||
const node = addNodeToGraph(false, graphInstance, workflowDefinitionNode, nodeDefinitions);
|
||||
// 保存节点配置
|
||||
node.setProp('config', nodeData.config);
|
||||
nodeMap.set(nodeData.id, node);
|
||||
node.setProp('config', workflowDefinitionNode.config);
|
||||
nodeMap.set(workflowDefinitionNode.id, node);
|
||||
});
|
||||
|
||||
// 创建边
|
||||
@ -171,8 +177,7 @@ const WorkflowDesign: React.FC = () => {
|
||||
const node = JSON.parse(nodeData);
|
||||
const { clientX, clientY } = e;
|
||||
const point = graph.clientToLocal({ x: clientX, y: clientY });
|
||||
|
||||
addNodeToGraph(graph, node, point);
|
||||
addNodeToGraph(true, graph, node, nodeDefinitions, point);
|
||||
} catch (error) {
|
||||
console.error('创建节点失败:', error);
|
||||
message.error('创建节点失败');
|
||||
|
||||
@ -1,65 +1,15 @@
|
||||
import { Graph } from '@antv/x6';
|
||||
import { convertPortConfig } from '../constants';
|
||||
import {Graph} from '@antv/x6';
|
||||
import {convertPortConfig} from '../constants';
|
||||
|
||||
interface NodeStyle {
|
||||
shape: string;
|
||||
style: any;
|
||||
size: {
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
ports: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一获取节点样式配置
|
||||
* @param node 节点数据
|
||||
* @returns 统一的节点样式配置
|
||||
*/
|
||||
const getNodeStyle = (node: any): NodeStyle => {
|
||||
// 如果是从已保存的定义加载的节点
|
||||
if (node.graph) {
|
||||
return {
|
||||
shape: node.graph.shape,
|
||||
style: node.graph.style,
|
||||
size: node.graph.size,
|
||||
ports: node.graph.ports
|
||||
};
|
||||
}
|
||||
// 如果是从面板拖拽创建的新节点
|
||||
return {
|
||||
shape: node.graphConfig.uiSchema.shape,
|
||||
style: node.graphConfig.uiSchema.style,
|
||||
size: node.graphConfig.uiSchema.size,
|
||||
ports: node.graphConfig.uiSchema.ports
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建节点配置
|
||||
*/
|
||||
const createNodeConfig = (node: any) => {
|
||||
const style = getNodeStyle(node);
|
||||
|
||||
const createNodeConfig = (uiGraph: any) => {
|
||||
return {
|
||||
inherit: 'rect', // 默认使用矩形
|
||||
width: style.size.width,
|
||||
height: style.size.height,
|
||||
attrs: {
|
||||
body: {
|
||||
...style.style,
|
||||
// 如果是菱形,添加多边形的点
|
||||
...(style.shape === 'diamond' ? {
|
||||
refPoints: '0,10 10,0 20,10 10,20',
|
||||
} : {})
|
||||
},
|
||||
label: {
|
||||
text: node.name,
|
||||
fill: '#000000',
|
||||
fontSize: 12,
|
||||
}
|
||||
},
|
||||
ports: convertPortConfig(style.ports)
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@ -71,33 +21,50 @@ const createNodeConfig = (node: any) => {
|
||||
* @returns 创建的节点实例
|
||||
*/
|
||||
export const addNodeToGraph = (
|
||||
graph: Graph,
|
||||
node: any,
|
||||
isNew: Boolean,
|
||||
graph: Graph,
|
||||
workflowDefinitionNode: any,
|
||||
workflowNodeDefinitionList: any,
|
||||
position?: { x: number, y: number }
|
||||
) => {
|
||||
const style = getNodeStyle(node);
|
||||
const nodeConfig = createNodeConfig(node);
|
||||
|
||||
let nodeDefinition = workflowNodeDefinitionList.find(def => def.type === workflowDefinitionNode.type);
|
||||
console.log(nodeDefinition.graphConfig.uiSchema, workflowDefinitionNode.graph)
|
||||
let uiGraph = isNew ? nodeDefinition.graphConfig.uiSchema : workflowDefinitionNode.graph;
|
||||
// 根据形状类型设置正确的 shape
|
||||
let shape = 'rect'; // 默认使用矩形
|
||||
if (style.shape === 'circle') {
|
||||
if (uiGraph.shape === 'circle') {
|
||||
shape = 'circle';
|
||||
} else if (style.shape === 'diamond') {
|
||||
} else if (uiGraph.shape === 'diamond') {
|
||||
shape = 'polygon';
|
||||
}
|
||||
|
||||
const nodeConfig = createNodeConfig(uiGraph);
|
||||
// 创建节点
|
||||
const newNode = graph.addNode({
|
||||
return graph.addNode({
|
||||
...nodeConfig,
|
||||
width: uiGraph.size.width,
|
||||
height: uiGraph.size.height,
|
||||
label: {
|
||||
text: isNew ? workflowDefinitionNode.name : nodeDefinition.name,
|
||||
fill: '#000000',
|
||||
fontSize: 12,
|
||||
},
|
||||
attrs: {
|
||||
body: {
|
||||
...uiGraph.style,
|
||||
// 如果是菱形,添加多边形的点
|
||||
...(uiGraph.shape === 'diamond' ? {
|
||||
refPoints: '0,10 10,0 20,10 10,20',
|
||||
} : {})
|
||||
}
|
||||
},
|
||||
shape, // 使用映射后的形状
|
||||
...(position && { x: position.x, y: position.y }),
|
||||
...(position && {x: position.x, y: position.y}),
|
||||
// 如果是已保存的节点,使用其ID和位置
|
||||
...(node.id && { id: node.id }),
|
||||
...(node.graph?.position && { position: node.graph.position }),
|
||||
type: node.type,
|
||||
code: node.code,
|
||||
nodeDefinition: node,
|
||||
...(uiGraph.id && {id: uiGraph.id}),
|
||||
...(uiGraph.graph?.position && {position: uiGraph.graph.position}),
|
||||
type: uiGraph.type,
|
||||
code: uiGraph.code,
|
||||
ports: convertPortConfig(uiGraph.ports),
|
||||
nodeDefinition: nodeDefinition,
|
||||
});
|
||||
|
||||
return newNode;
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user