增加工具栏提示。
This commit is contained in:
parent
664641283c
commit
5a7eff8b97
@ -12,7 +12,7 @@ import NodeConfig from './components/NodeConfig';
|
|||||||
import Toolbar from './components/Toolbar';
|
import Toolbar from './components/Toolbar';
|
||||||
import EdgeConfig from './components/EdgeConfig';
|
import EdgeConfig from './components/EdgeConfig';
|
||||||
import { validateFlow, hasCycle } from './validate';
|
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 { NODE_CONFIG } from './configs/nodeConfig';
|
||||||
import { isWorkflowError } from './utils/errors';
|
import { isWorkflowError } from './utils/errors';
|
||||||
import { initGraph } from './utils/graphUtils';
|
import { initGraph } from './utils/graphUtils';
|
||||||
@ -272,22 +272,28 @@ const FlowDesigner: React.FC = () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取节点配置
|
// 获取节点大小
|
||||||
const position = calculateNodePosition(nodeType.type, dropPosition);
|
let size;
|
||||||
const nodeStyle = generateNodeStyle(nodeType.type);
|
if (nodeType.type === 'start' || nodeType.type === 'end') {
|
||||||
const ports = generatePorts(nodeType.type);
|
size = { width: 40, height: 40 };
|
||||||
|
} else {
|
||||||
|
size = { width: 100, height: 60 };
|
||||||
|
}
|
||||||
|
|
||||||
// 创建节点
|
// 创建节点
|
||||||
const node = graphRef.current.addNode({
|
const node = graphRef.current.addNode({
|
||||||
...position,
|
shape: getNodeShape(nodeType.type),
|
||||||
...nodeStyle,
|
attrs: generateNodeStyle(nodeType.type, nodeType.name),
|
||||||
ports,
|
|
||||||
data: {
|
data: {
|
||||||
type: nodeType.type,
|
type: nodeType.type,
|
||||||
name: nodeType.name,
|
config: {
|
||||||
description: nodeType.description,
|
type: nodeType.type,
|
||||||
config: nodeType.flowableConfig ? JSON.parse(nodeType.flowableConfig) : {},
|
name: nodeType.name
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
position: dropPosition,
|
||||||
|
size: size,
|
||||||
|
ports: generatePorts(nodeType.type),
|
||||||
});
|
});
|
||||||
|
|
||||||
// 选中新创建的节点并打开配置
|
// 选中新创建的节点并打开配置
|
||||||
@ -300,18 +306,8 @@ const FlowDesigner: React.FC = () => {
|
|||||||
|
|
||||||
message.success('节点创建成功');
|
message.success('节点创建成功');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error creating node:', error);
|
console.error('创建节点失败:', error);
|
||||||
|
message.error('创建节点失败');
|
||||||
if (isWorkflowError(error)) {
|
|
||||||
message.error(`创建节点失败:${error.message}`);
|
|
||||||
} else {
|
|
||||||
message.error('创建节点失败:未知错误');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理状态
|
|
||||||
setCurrentNode(undefined);
|
|
||||||
setCurrentNodeType(undefined);
|
|
||||||
setConfigVisible(false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -435,11 +431,7 @@ const FlowDesigner: React.FC = () => {
|
|||||||
const loadGraphData = (graph: Graph, detail: WorkflowDefinition) => {
|
const loadGraphData = (graph: Graph, detail: WorkflowDefinition) => {
|
||||||
try {
|
try {
|
||||||
console.log('Loading graph data:', detail);
|
console.log('Loading graph data:', detail);
|
||||||
// 加载图数据
|
if (detail.graph) {
|
||||||
if (detail.bpmnJson) {
|
|
||||||
graph.fromJSON(detail.bpmnJson);
|
|
||||||
} else if (detail.graph) {
|
|
||||||
// 如果没有 bpmnJson,尝试使用新的 graph 数据结构
|
|
||||||
const cells = [
|
const cells = [
|
||||||
...detail.graph.nodes.map(node => ({
|
...detail.graph.nodes.map(node => ({
|
||||||
id: node.id,
|
id: node.id,
|
||||||
@ -450,7 +442,7 @@ const FlowDesigner: React.FC = () => {
|
|||||||
config: node.config
|
config: node.config
|
||||||
},
|
},
|
||||||
position: node.position,
|
position: node.position,
|
||||||
size: node.size || { width: 100, height: 60 }
|
size: node.size // 直接使用数据中的 size
|
||||||
})),
|
})),
|
||||||
...detail.graph.edges.map(edge => ({
|
...detail.graph.edges.map(edge => ({
|
||||||
id: edge.id,
|
id: edge.id,
|
||||||
@ -526,19 +518,21 @@ const FlowDesigner: React.FC = () => {
|
|||||||
.filter((cell: any) => cell.shape !== 'edge')
|
.filter((cell: any) => cell.shape !== 'edge')
|
||||||
.map((node: any) => ({
|
.map((node: any) => ({
|
||||||
id: node.id,
|
id: node.id,
|
||||||
type: node.shape,
|
type: node.data.type,
|
||||||
name: node.data?.label || '',
|
name: node.data?.name || '',
|
||||||
position: node.position,
|
position: node.position,
|
||||||
config: node.data?.serviceTask || {}
|
size: node.size,
|
||||||
|
config: node.data?.config || {}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const edges = graphData.cells
|
const edges = graphData.cells
|
||||||
.filter((cell: any) => cell.shape === 'edge')
|
.filter((cell: any) => cell.shape === 'edge')
|
||||||
.map((edge: any) => ({
|
.map((edge: any) => ({
|
||||||
id: edge.id,
|
id: edge.id,
|
||||||
source: edge.source,
|
source: edge.source.cell,
|
||||||
target: edge.target,
|
target: edge.target.cell,
|
||||||
name: edge.data?.label || ''
|
name: edge.data?.name || '',
|
||||||
|
config: edge.data?.config || {}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return { nodes, edges };
|
return { nodes, edges };
|
||||||
|
|||||||
@ -60,6 +60,106 @@ const NODE_THEMES: Record<string, { fill: string; stroke: string }> = {
|
|||||||
parallelGateway: { fill: '#f9f0ff', stroke: '#722ed1' },
|
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 => {
|
export const getNodeConfig = (nodeType: string): NodeConfig => {
|
||||||
// 根据节点类型动态生成配置
|
// 根据节点类型动态生成配置
|
||||||
@ -88,6 +188,15 @@ export const getNodeConfig = (nodeType: string): NodeConfig => {
|
|||||||
return baseConfig;
|
return baseConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取节点默认大小
|
||||||
|
export const getNodeSize = (nodeType: string) => {
|
||||||
|
const config = NODE_CONFIG[nodeType];
|
||||||
|
if (!config) {
|
||||||
|
return { width: 100, height: 60 }; // 默认大小
|
||||||
|
}
|
||||||
|
return config.size;
|
||||||
|
};
|
||||||
|
|
||||||
interface NodeStyle {
|
interface NodeStyle {
|
||||||
body: {
|
body: {
|
||||||
fill: string;
|
fill: string;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user