增加工具栏提示。

This commit is contained in:
dengqichen 2024-12-11 18:41:40 +08:00
parent 664641283c
commit 5a7eff8b97
2 changed files with 138 additions and 35 deletions

View File

@ -12,7 +12,7 @@ import NodeConfig from './components/NodeConfig';
import Toolbar from './components/Toolbar';
import EdgeConfig from './components/EdgeConfig';
import { validateFlow, hasCycle } from './validate';
import { generateNodeStyle, generatePorts, calculateNodePosition, calculateCanvasPosition, getNodeShape } from './utils/nodeUtils';
import { generateNodeStyle, generatePorts, calculateNodePosition, calculateCanvasPosition, getNodeShape, getNodeSize } from './utils/nodeUtils';
import { NODE_CONFIG } from './configs/nodeConfig';
import { isWorkflowError } from './utils/errors';
import { initGraph } from './utils/graphUtils';
@ -272,22 +272,28 @@ const FlowDesigner: React.FC = () => {
}
);
// 获取节点配置
const position = calculateNodePosition(nodeType.type, dropPosition);
const nodeStyle = generateNodeStyle(nodeType.type);
const ports = generatePorts(nodeType.type);
// 获取节点大小
let size;
if (nodeType.type === 'start' || nodeType.type === 'end') {
size = { width: 40, height: 40 };
} else {
size = { width: 100, height: 60 };
}
// 创建节点
const node = graphRef.current.addNode({
...position,
...nodeStyle,
ports,
shape: getNodeShape(nodeType.type),
attrs: generateNodeStyle(nodeType.type, nodeType.name),
data: {
type: nodeType.type,
name: nodeType.name,
description: nodeType.description,
config: nodeType.flowableConfig ? JSON.parse(nodeType.flowableConfig) : {},
config: {
type: nodeType.type,
name: nodeType.name
}
},
position: dropPosition,
size: size,
ports: generatePorts(nodeType.type),
});
// 选中新创建的节点并打开配置
@ -300,18 +306,8 @@ const FlowDesigner: React.FC = () => {
message.success('节点创建成功');
} catch (error) {
console.error('Error creating node:', error);
if (isWorkflowError(error)) {
message.error(`创建节点失败:${error.message}`);
} else {
message.error('创建节点失败:未知错误');
}
// 清理状态
setCurrentNode(undefined);
setCurrentNodeType(undefined);
setConfigVisible(false);
console.error('创建节点失败:', error);
message.error('创建节点失败');
}
};
@ -435,11 +431,7 @@ const FlowDesigner: React.FC = () => {
const loadGraphData = (graph: Graph, detail: WorkflowDefinition) => {
try {
console.log('Loading graph data:', detail);
// 加载图数据
if (detail.bpmnJson) {
graph.fromJSON(detail.bpmnJson);
} else if (detail.graph) {
// 如果没有 bpmnJson尝试使用新的 graph 数据结构
if (detail.graph) {
const cells = [
...detail.graph.nodes.map(node => ({
id: node.id,
@ -450,7 +442,7 @@ const FlowDesigner: React.FC = () => {
config: node.config
},
position: node.position,
size: node.size || { width: 100, height: 60 }
size: node.size // 直接使用数据中的 size
})),
...detail.graph.edges.map(edge => ({
id: edge.id,
@ -526,19 +518,21 @@ const FlowDesigner: React.FC = () => {
.filter((cell: any) => cell.shape !== 'edge')
.map((node: any) => ({
id: node.id,
type: node.shape,
name: node.data?.label || '',
type: node.data.type,
name: node.data?.name || '',
position: node.position,
config: node.data?.serviceTask || {}
size: node.size,
config: node.data?.config || {}
}));
const edges = graphData.cells
.filter((cell: any) => cell.shape === 'edge')
.map((edge: any) => ({
id: edge.id,
source: edge.source,
target: edge.target,
name: edge.data?.label || ''
source: edge.source.cell,
target: edge.target.cell,
name: edge.data?.name || '',
config: edge.data?.config || {}
}));
return { nodes, edges };

View File

@ -60,6 +60,106 @@ const NODE_THEMES: Record<string, { fill: string; stroke: string }> = {
parallelGateway: { fill: '#f9f0ff', stroke: '#722ed1' },
};
// 节点配置映射
const NODE_CONFIG: Record<string, NodeConfig> = {
startEvent: {
size: { width: 80, height: 80 },
shape: 'circle',
theme: NODE_THEMES.startEvent,
label: 'startEvent',
extras: {
icon: {
'xlink:href': NODE_ICONS.startEvent,
width: 32,
height: 32,
x: 8,
y: 24,
},
},
},
endEvent: {
size: { width: 80, height: 80 },
shape: 'circle',
theme: NODE_THEMES.endEvent,
label: 'endEvent',
extras: {
icon: {
'xlink:href': NODE_ICONS.endEvent,
width: 32,
height: 32,
x: 8,
y: 24,
},
},
},
userTask: {
size: { width: 200, height: 80 },
shape: 'rect',
theme: NODE_THEMES.userTask,
label: 'userTask',
extras: {
rx: 4,
ry: 4,
icon: {
'xlink:href': NODE_ICONS.userTask,
width: 32,
height: 32,
x: 8,
y: 24,
},
},
},
shellTask: {
size: { width: 200, height: 80 },
shape: 'rect',
theme: NODE_THEMES.shellTask,
label: 'shellTask',
extras: {
rx: 4,
ry: 4,
icon: {
'xlink:href': NODE_ICONS.shellTask,
width: 32,
height: 32,
x: 8,
y: 24,
},
},
},
exclusiveGateway: {
size: { width: 60, height: 60 },
shape: 'polygon',
theme: NODE_THEMES.exclusiveGateway,
label: 'exclusiveGateway',
extras: {
refPoints: '0,30 30,0 60,30 30,60',
icon: {
'xlink:href': NODE_ICONS.exclusiveGateway,
width: 32,
height: 32,
x: 14,
y: 14,
},
},
},
parallelGateway: {
size: { width: 60, height: 60 },
shape: 'polygon',
theme: NODE_THEMES.parallelGateway,
label: 'parallelGateway',
extras: {
refPoints: '0,30 30,0 60,30 30,60',
icon: {
'xlink:href': NODE_ICONS.parallelGateway,
width: 32,
height: 32,
x: 14,
y: 14,
},
},
},
};
// 获取节点配置
export const getNodeConfig = (nodeType: string): NodeConfig => {
// 根据节点类型动态生成配置
@ -88,6 +188,15 @@ export const getNodeConfig = (nodeType: string): NodeConfig => {
return baseConfig;
};
// 获取节点默认大小
export const getNodeSize = (nodeType: string) => {
const config = NODE_CONFIG[nodeType];
if (!config) {
return { width: 100, height: 60 }; // 默认大小
}
return config.size;
};
interface NodeStyle {
body: {
fill: string;