From 472c9862c42e9d1d84e3705b32453c5a0b78a58e Mon Sep 17 00:00:00 2001 From: dengqichen Date: Fri, 6 Dec 2024 17:51:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B7=A5=E5=85=B7=E6=A0=8F?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Workflow/Definition/Designer/index.tsx | 124 ++++++++++++------ .../Workflow/Definition/Designer/service.ts | 7 +- 2 files changed, 87 insertions(+), 44 deletions(-) diff --git a/frontend/src/pages/Workflow/Definition/Designer/index.tsx b/frontend/src/pages/Workflow/Definition/Designer/index.tsx index 59423a44..ca90a8fc 100644 --- a/frontend/src/pages/Workflow/Definition/Designer/index.tsx +++ b/frontend/src/pages/Workflow/Definition/Designer/index.tsx @@ -530,66 +530,110 @@ const FlowDesigner: React.FC = () => { // 创建节点 const node = graphRef.current.addNode({ - x: position.x - 90, // 节点宽度的一半,使节点中心对准鼠标 - y: position.y - 20, // 节点高度的一半,使节点中心对准鼠标 - width: 180, - height: 40, - shape: 'rect', + x: position.x - (nodeType.code === 'SHELL' ? 100 : 40), // Shell节点宽度的一半,其他节点40px + y: position.y - 40, + width: nodeType.code === 'SHELL' ? 200 : 80, + height: 80, + shape: nodeType.code === 'GATEWAY' ? 'polygon' : (nodeType.code === 'SHELL' ? 'rect' : 'circle'), attrs: { body: { - fill: '#fff', - stroke: nodeType.color, - strokeWidth: 1, - rx: 4, - ry: 4, + fill: nodeType.code === 'START' ? '#f6ffed' : + nodeType.code === 'END' ? '#fff1f0' : + nodeType.code === 'SHELL' ? '#e6f7ff' : '#f9f0ff', + stroke: nodeType.code === 'START' ? '#52c41a' : + nodeType.code === 'END' ? '#ff4d4f' : + nodeType.code === 'SHELL' ? '#1890ff' : '#722ed1', + strokeWidth: 2, + ...(nodeType.code === 'SHELL' ? { rx: 4, ry: 4 } : {}), + ...(nodeType.code === 'GATEWAY' ? { refPoints: '0,10 10,0 20,10 10,20' } : {}) }, label: { text: nodeType.name, - fill: '#333', + fill: '#000000', fontSize: 14, - refX: 0.5, - refY: 0.5, - textAnchor: 'middle', - textVerticalAnchor: 'middle', + fontWeight: 500, + ...(nodeType.code === 'SHELL' ? { + refX: 0.5, // 水平居中 + refY: 0.5, // 垂直居中 + textAnchor: 'middle', // 文本水平居中 + textVerticalAnchor: 'middle' // 文本垂直居中 + } : {}) }, + ...(nodeType.code === 'SHELL' ? { + image: { + 'xlink:href': 'data:image/svg+xml;base64,PHN2ZyB0PSIxNzAzODQ4NTM1NDY5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQxNjEiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNMTYwIDI1NnY1MTJoNzA0VjI1NkgxNjB6IG02NDAgNDQ4SDE5MlYyODhoNjA4djQxNnpNMjI0IDQ4MGwxMjgtMTI4IDQ1LjMgNDUuMy04Mi43IDgyLjcgODIuNyA4Mi43TDM1MiA2MDhsLTEyOC0xMjh6IG0yMzEuMSAxOTJsLTQ1LjMtNDUuMyAxNTItMTUyIDQ1LjMgNDUuM2wtMTUyIDE1MnoiIGZpbGw9IiMxODkwZmYiIHAtaWQ9IjQxNjIiPjwvcGF0aD48L3N2Zz4=', + width: 32, + height: 32, + x: 16, + y: 24 + } + } : {}) }, ports: { groups: { - in: { - position: 'left', + top: { + position: 'top', attrs: { circle: { r: 4, magnet: true, - stroke: '#5F95FF', - strokeWidth: 1, - fill: '#fff', - }, - }, + stroke: nodeType.code === 'START' ? '#52c41a' : + nodeType.code === 'END' ? '#ff4d4f' : + nodeType.code === 'SHELL' ? '#1890ff' : '#722ed1', + strokeWidth: 2, + fill: '#fff' + } + } }, - out: { + right: { position: 'right', attrs: { circle: { r: 4, magnet: true, - stroke: '#5F95FF', - strokeWidth: 1, - fill: '#fff', - }, - }, + stroke: nodeType.code === 'START' ? '#52c41a' : + nodeType.code === 'END' ? '#ff4d4f' : + nodeType.code === 'SHELL' ? '#1890ff' : '#722ed1', + strokeWidth: 2, + fill: '#fff' + } + } }, + bottom: { + position: 'bottom', + attrs: { + circle: { + r: 4, + magnet: true, + stroke: nodeType.code === 'START' ? '#52c41a' : + nodeType.code === 'END' ? '#ff4d4f' : + nodeType.code === 'SHELL' ? '#1890ff' : '#722ed1', + strokeWidth: 2, + fill: '#fff' + } + } + }, + left: { + position: 'left', + attrs: { + circle: { + r: 4, + magnet: true, + stroke: nodeType.code === 'START' ? '#52c41a' : + nodeType.code === 'END' ? '#ff4d4f' : + nodeType.code === 'SHELL' ? '#1890ff' : '#722ed1', + strokeWidth: 2, + fill: '#fff' + } + } + } }, items: [ - { - id: 'port-in', - group: 'in', - }, - { - id: 'port-out', - group: 'out', - }, - ], + { group: 'top' }, + { group: 'right' }, + { group: 'bottom' }, + { group: 'left' } + ] }, data: { type: nodeType.code, @@ -599,10 +643,8 @@ const FlowDesigner: React.FC = () => { }); // 选中新创建的节点 - graphRef.current.getNodes().forEach(n => { - n.setAttrByPath('body/strokeWidth', 1); - }); - node.setAttrByPath('body/strokeWidth', 2); + graphRef.current.cleanSelection(); + graphRef.current.select(node); // 打开配置抽屉 setCurrentNode(node); diff --git a/frontend/src/pages/Workflow/Definition/Designer/service.ts b/frontend/src/pages/Workflow/Definition/Designer/service.ts index 1f8fa331..8b63eb44 100644 --- a/frontend/src/pages/Workflow/Definition/Designer/service.ts +++ b/frontend/src/pages/Workflow/Definition/Designer/service.ts @@ -1,11 +1,12 @@ import request from '@/utils/request'; +import { NodeCategory } from '../../types'; export interface NodeExecutor { code: string; name: string; description: string; configSchema: string; - defaultConfig: string | null; + defaultConfig?: string; } export interface JsonSchemaProperty { @@ -33,7 +34,7 @@ export interface NodeType { id: number; code: string; name: string; - category: 'BASIC' | 'TASK' | 'EVENT' | 'GATEWAY'; + category: NodeCategory; description: string; enabled: boolean; icon: string; @@ -52,7 +53,7 @@ export interface NodeType { export interface NodeTypeQuery { enabled?: boolean; - category?: 'BASIC' | 'TASK' | 'EVENT' | 'GATEWAY'; + category?: NodeCategory; } // 获取节点类型列表