From 60e1b8271d55295eb79652462e1daa9c73b87f99 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Fri, 6 Jun 2025 07:22:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20[BPM=20=E5=B7=A5=E4=BD=9C=E6=B5=81]=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B5=81=E7=A8=8B=E6=A8=A1=E5=9E=8B=E6=9B=B4?= =?UTF-8?q?=E5=A4=9A=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodes-config/copy-task-node-config.vue | 7 +- .../nodes-config/delay-timer-node-config.vue | 5 +- .../nodes-config/router-node-config.vue | 12 +- .../nodes-config/start-user-node-config.vue | 10 +- .../nodes-config/trigger-node-config.vue | 5 +- .../nodes-config/user-task-node-config.vue | 28 +- .../components/nodes/copy-task-node.vue | 8 +- .../components/nodes/delay-timer-node.vue | 8 +- .../components/nodes/exclusive-node.vue | 9 +- .../components/nodes/inclusive-node.vue | 9 +- .../components/nodes/node-handler.vue | 100 ++-- .../components/nodes/parallel-node.vue | 10 +- .../components/nodes/router-node.vue | 8 +- .../components/nodes/start-user-node.vue | 8 +- .../components/nodes/trigger-node.vue | 8 +- .../components/nodes/user-task-node.vue | 14 +- .../components/process-node-tree.vue | 35 +- .../components/simple-process-designer.vue | 16 +- .../components/simple-process-model.vue | 20 +- .../simple-process-design/consts.ts | 166 +----- .../simple-process-design/helpers.ts | 32 +- .../components/simple-process-design/index.ts | 4 + apps/web-antd/src/utils/constants.ts | 18 + .../src/views/bpm/model/form/index.vue | 31 +- .../bpm/model/form/modules/extra-setting.vue | 498 ++++++++++++++++++ 25 files changed, 767 insertions(+), 302 deletions(-) create mode 100644 apps/web-antd/src/views/bpm/model/form/modules/extra-setting.vue diff --git a/apps/web-antd/src/components/simple-process-design/components/nodes-config/copy-task-node-config.vue b/apps/web-antd/src/components/simple-process-design/components/nodes-config/copy-task-node-config.vue index 03f454c52..3e548c97f 100644 --- a/apps/web-antd/src/components/simple-process-design/components/nodes-config/copy-task-node-config.vue +++ b/apps/web-antd/src/components/simple-process-design/components/nodes-config/copy-task-node-config.vue @@ -27,14 +27,13 @@ import { TreeSelect, } from 'ant-design-vue'; -import { BpmModelFormType } from '#/utils'; +import { BpmModelFormType, BpmNodeTypeEnum } from '#/utils'; import { CANDIDATE_STRATEGY, CandidateStrategy, FieldPermissionType, MULTI_LEVEL_DEPT, - NodeType, } from '../../consts'; import { useFormFieldsPermission, @@ -77,7 +76,7 @@ const currentNode = useWatchNode(props); // 节点名称 const { nodeName, showInput, clickIcon, blurEvent } = useNodeName( - NodeType.COPY_TASK_NODE, + BpmNodeTypeEnum.COPY_TASK_NODE, ); // 激活的 Tab 标签页 @@ -137,7 +136,7 @@ const { getShowText, handleCandidateParam, parseCandidateParam, -} = useNodeForm(NodeType.COPY_TASK_NODE); +} = useNodeForm(BpmNodeTypeEnum.COPY_TASK_NODE); const configForm = tempConfigForm as Ref; // 抄送人策略, 去掉发起人自选 和 发起人自己 diff --git a/apps/web-antd/src/components/simple-process-design/components/nodes-config/delay-timer-node-config.vue b/apps/web-antd/src/components/simple-process-design/components/nodes-config/delay-timer-node-config.vue index 2dca15fba..95ffc5098 100644 --- a/apps/web-antd/src/components/simple-process-design/components/nodes-config/delay-timer-node-config.vue +++ b/apps/web-antd/src/components/simple-process-design/components/nodes-config/delay-timer-node-config.vue @@ -22,10 +22,11 @@ import { SelectOption, } from 'ant-design-vue'; +import { BpmNodeTypeEnum } from '#/utils'; + import { DELAY_TYPE, DelayTypeEnum, - NodeType, TIME_UNIT_TYPES, TimeUnitType, } from '../../consts'; @@ -45,7 +46,7 @@ const props = defineProps({ const currentNode = useWatchNode(props); // 节点名称 const { nodeName, showInput, clickIcon, blurEvent } = useNodeName( - NodeType.DELAY_TIMER_NODE, + BpmNodeTypeEnum.DELAY_TIMER_NODE, ); // 抄送人表单配置 const formRef = ref(); // 表单 Ref diff --git a/apps/web-antd/src/components/simple-process-design/components/nodes-config/router-node-config.vue b/apps/web-antd/src/components/simple-process-design/components/nodes-config/router-node-config.vue index e42df7d24..0b96375d6 100644 --- a/apps/web-antd/src/components/simple-process-design/components/nodes-config/router-node-config.vue +++ b/apps/web-antd/src/components/simple-process-design/components/nodes-config/router-node-config.vue @@ -21,7 +21,9 @@ import { SelectOption, } from 'ant-design-vue'; -import { ConditionType, NodeType } from '../../consts'; +import { BpmNodeTypeEnum } from '#/utils'; + +import { ConditionType } from '../../consts'; import { useNodeName, useWatchNode } from '../../helpers'; import Condition from './modules/condition.vue'; @@ -40,7 +42,7 @@ const processNodeTree = inject>('processNodeTree'); const currentNode = useWatchNode(props); /** 节点名称 */ const { nodeName, showInput, clickIcon, blurEvent } = useNodeName( - NodeType.ROUTER_BRANCH_NODE, + BpmNodeTypeEnum.ROUTER_BRANCH_NODE, ); const routerGroups = ref([]); const nodeOptions = ref([]); @@ -176,15 +178,15 @@ function getRouterNode(node: any) { while (true) { if (!node) break; if ( - node.type !== NodeType.ROUTER_BRANCH_NODE && - node.type !== NodeType.CONDITION_NODE + node.type !== BpmNodeTypeEnum.ROUTER_BRANCH_NODE && + node.type !== BpmNodeTypeEnum.CONDITION_NODE ) { nodeOptions.value.push({ label: node.name, value: node.id, }); } - if (!node.childNode || node.type === NodeType.END_EVENT_NODE) { + if (!node.childNode || node.type === BpmNodeTypeEnum.END_EVENT_NODE) { break; } if (node.conditionNodes && node.conditionNodes.length > 0) { diff --git a/apps/web-antd/src/components/simple-process-design/components/nodes-config/start-user-node-config.vue b/apps/web-antd/src/components/simple-process-design/components/nodes-config/start-user-node-config.vue index bcdb3d9a2..eb6feeb8b 100644 --- a/apps/web-antd/src/components/simple-process-design/components/nodes-config/start-user-node-config.vue +++ b/apps/web-antd/src/components/simple-process-design/components/nodes-config/start-user-node-config.vue @@ -23,13 +23,9 @@ import { TypographyText, } from 'ant-design-vue'; -import { BpmModelFormType } from '#/utils'; +import { BpmModelFormType, BpmNodeTypeEnum } from '#/utils'; -import { - FieldPermissionType, - NodeType, - START_USER_BUTTON_SETTING, -} from '../../consts'; +import { FieldPermissionType, START_USER_BUTTON_SETTING } from '../../consts'; import { useFormFieldsPermission, useNodeName, @@ -57,7 +53,7 @@ const deptOptions = inject>('deptList'); const currentNode = useWatchNode(props); // 节点名称 const { nodeName, showInput, clickIcon, blurEvent } = useNodeName( - NodeType.COPY_TASK_NODE, + BpmNodeTypeEnum.START_USER_NODE, ); // 激活的 Tab 标签页 const activeTabName = ref('user'); diff --git a/apps/web-antd/src/components/simple-process-design/components/nodes-config/trigger-node-config.vue b/apps/web-antd/src/components/simple-process-design/components/nodes-config/trigger-node-config.vue index 85b0726aa..eb7d40476 100644 --- a/apps/web-antd/src/components/simple-process-design/components/nodes-config/trigger-node-config.vue +++ b/apps/web-antd/src/components/simple-process-design/components/nodes-config/trigger-node-config.vue @@ -29,9 +29,10 @@ import { Tag, } from 'ant-design-vue'; +import { BpmNodeTypeEnum } from '#/utils'; + import { DEFAULT_CONDITION_GROUP_VALUE, - NodeType, TRIGGER_TYPES, TriggerTypeEnum, } from '../../consts'; @@ -72,7 +73,7 @@ const [Drawer, drawerApi] = useVbenDrawer({ const currentNode = useWatchNode(props); // 节点名称 const { nodeName, showInput, clickIcon, blurEvent } = useNodeName( - NodeType.TRIGGER_NODE, + BpmNodeTypeEnum.TRIGGER_NODE, ); // 触发器表单配置 const formRef = ref(); // 表单 Ref diff --git a/apps/web-antd/src/components/simple-process-design/components/nodes-config/user-task-node-config.vue b/apps/web-antd/src/components/simple-process-design/components/nodes-config/user-task-node-config.vue index 1ee36fb1f..d9376bb3c 100644 --- a/apps/web-antd/src/components/simple-process-design/components/nodes-config/user-task-node-config.vue +++ b/apps/web-antd/src/components/simple-process-design/components/nodes-config/user-task-node-config.vue @@ -34,7 +34,11 @@ import { TypographyText, } from 'ant-design-vue'; -import { BpmModelFormType } from '#/utils'; +import { + BpmModelFormType, + BpmNodeTypeEnum, + ProcessVariableEnum, +} from '#/utils'; import { APPROVE_METHODS, @@ -49,9 +53,7 @@ import { DEFAULT_BUTTON_SETTING, FieldPermissionType, MULTI_LEVEL_DEPT, - NodeType, OPERATION_BUTTON_NAME, - ProcessVariableEnum, REJECT_HANDLER_TYPES, RejectHandlerType, TIME_UNIT_TYPES, @@ -113,7 +115,7 @@ const [Drawer, drawerApi] = useVbenDrawer({ // 节点名称配置 const { nodeName, showInput, clickIcon, blurEvent } = useNodeName( - NodeType.USER_TASK_NODE, + BpmNodeTypeEnum.USER_TASK_NODE, ); // 激活的 Tab 标签页 @@ -245,7 +247,9 @@ const userTaskListenerRef = ref(); /** 节点类型名称 */ const nodeTypeName = computed(() => { - return currentNode.value.type === NodeType.TRANSACTOR_NODE ? '办理' : '审批'; + return currentNode.value.type === BpmNodeTypeEnum.TRANSACTOR_NODE + ? '办理' + : '审批'; }); /** 校验节点配置 */ @@ -407,7 +411,7 @@ function showUserTaskNodeConfig(node: SimpleFlowNode) { // 3. 操作按钮设置 buttonsSetting.value = cloneDeep(node.buttonsSetting) || - (node.type === NodeType.TRANSACTOR_NODE + (node.type === BpmNodeTypeEnum.TRANSACTOR_NODE ? TRANSACTOR_DEFAULT_BUTTON_SETTING : DEFAULT_BUTTON_SETTING); // 4. 表单字段权限配置 @@ -595,7 +599,7 @@ onMounted(() => {
审批类型 : @@ -860,7 +864,7 @@ onMounted(() => { -
+
审批人拒绝时 {
-
+
审批人超时未处理时 { -
+
审批人与提交人为同一人时 @@ -1081,7 +1085,7 @@ onMounted(() => {
-
+
审批意见 {
diff --git a/apps/web-antd/src/components/simple-process-design/components/nodes/copy-task-node.vue b/apps/web-antd/src/components/simple-process-design/components/nodes/copy-task-node.vue index c9bd17190..4e4e482a0 100644 --- a/apps/web-antd/src/components/simple-process-design/components/nodes/copy-task-node.vue +++ b/apps/web-antd/src/components/simple-process-design/components/nodes/copy-task-node.vue @@ -7,7 +7,9 @@ import { IconifyIcon } from '@vben/icons'; import { Input } from 'ant-design-vue'; -import { NODE_DEFAULT_TEXT, NodeType } from '../../consts'; +import { BpmNodeTypeEnum } from '#/utils'; + +import { NODE_DEFAULT_TEXT } from '../../consts'; import { useNodeName2, useTaskStatusClass, useWatchNode } from '../../helpers'; import CopyTaskNodeConfig from '../nodes-config/copy-task-node-config.vue'; import NodeHandler from './node-handler.vue'; @@ -32,7 +34,7 @@ const currentNode = useWatchNode(props); // 节点名称编辑 const { showInput, blurEvent, clickTitle } = useNodeName2( currentNode, - NodeType.COPY_TASK_NODE, + BpmNodeTypeEnum.COPY_TASK_NODE, ); const nodeSetting = ref(); @@ -85,7 +87,7 @@ function deleteNode() { {{ currentNode.showText }}
- {{ NODE_DEFAULT_TEXT.get(NodeType.COPY_TASK_NODE) }} + {{ NODE_DEFAULT_TEXT.get(BpmNodeTypeEnum.COPY_TASK_NODE) }}
diff --git a/apps/web-antd/src/components/simple-process-design/components/nodes/delay-timer-node.vue b/apps/web-antd/src/components/simple-process-design/components/nodes/delay-timer-node.vue index fa83d4ebe..3a4227d4f 100644 --- a/apps/web-antd/src/components/simple-process-design/components/nodes/delay-timer-node.vue +++ b/apps/web-antd/src/components/simple-process-design/components/nodes/delay-timer-node.vue @@ -7,7 +7,9 @@ import { IconifyIcon } from '@vben/icons'; import { Input } from 'ant-design-vue'; -import { NODE_DEFAULT_TEXT, NodeType } from '../../consts'; +import { BpmNodeTypeEnum } from '#/utils'; + +import { NODE_DEFAULT_TEXT } from '../../consts'; import { useNodeName2, useTaskStatusClass, useWatchNode } from '../../helpers'; import DelayTimerNodeConfig from '../nodes-config/delay-timer-node-config.vue'; import NodeHandler from './node-handler.vue'; @@ -30,7 +32,7 @@ const currentNode = useWatchNode(props); // 节点名称编辑 const { showInput, blurEvent, clickTitle } = useNodeName2( currentNode, - NodeType.DELAY_TIMER_NODE, + BpmNodeTypeEnum.DELAY_TIMER_NODE, ); const nodeSetting = ref(); @@ -82,7 +84,7 @@ function deleteNode() { {{ currentNode.showText }}
- {{ NODE_DEFAULT_TEXT.get(NodeType.DELAY_TIMER_NODE) }} + {{ NODE_DEFAULT_TEXT.get(BpmNodeTypeEnum.DELAY_TIMER_NODE) }}
diff --git a/apps/web-antd/src/components/simple-process-design/components/nodes/exclusive-node.vue b/apps/web-antd/src/components/simple-process-design/components/nodes/exclusive-node.vue index e37edc298..1dc18e528 100644 --- a/apps/web-antd/src/components/simple-process-design/components/nodes/exclusive-node.vue +++ b/apps/web-antd/src/components/simple-process-design/components/nodes/exclusive-node.vue @@ -8,11 +8,12 @@ import { cloneDeep, buildShortUUID as generateUUID } from '@vben/utils'; import { Button, Input } from 'ant-design-vue'; +import { BpmNodeTypeEnum } from '#/utils'; + import { ConditionType, DEFAULT_CONDITION_GROUP_VALUE, NODE_DEFAULT_TEXT, - NodeType, } from '../../consts'; import { getDefaultConditionNodeName, useTaskStatusClass } from '../../helpers'; import ConditionNodeConfig from '../nodes-config/condition-node-config.vue'; @@ -90,7 +91,7 @@ function addCondition() { id: `Flow_${generateUUID()}`, name: `条件${len}`, showText: '', - type: NodeType.CONDITION_NODE, + type: BpmNodeTypeEnum.CONDITION_NODE, childNode: undefined, conditionNodes: [], conditionSetting: { @@ -138,7 +139,7 @@ function recursiveFindParentNode( node: SimpleFlowNode, nodeType: number, ) { - if (!node || node.type === NodeType.START_USER_NODE) { + if (!node || node.type === BpmNodeTypeEnum.START_USER_NODE) { return; } if (node.type === nodeType) { @@ -210,7 +211,7 @@ function recursiveFindParentNode( {{ item.showText }}
- {{ NODE_DEFAULT_TEXT.get(NodeType.CONDITION_NODE) }} + {{ NODE_DEFAULT_TEXT.get(BpmNodeTypeEnum.CONDITION_NODE) }}
- {{ NODE_DEFAULT_TEXT.get(NodeType.CONDITION_NODE) }} + {{ NODE_DEFAULT_TEXT.get(BpmNodeTypeEnum.CONDITION_NODE) }}
('readonly'); // 是否只读 function addNode(type: number) { // 校验:条件分支、包容分支后面,不允许直接添加并行分支 if ( - type === NodeType.PARALLEL_BRANCH_NODE && - [NodeType.CONDITION_BRANCH_NODE, NodeType.INCLUSIVE_BRANCH_NODE].includes( - props.currentNode?.type, - ) + type === BpmNodeTypeEnum.PARALLEL_BRANCH_NODE && + [ + BpmNodeTypeEnum.CONDITION_BRANCH_NODE, + BpmNodeTypeEnum.INCLUSIVE_BRANCH_NODE, + ].includes(props.currentNode?.type) ) { message.error('条件分支、包容分支后面,不允许直接添加并行分支'); return; } popoverShow.value = false; - if (type === NodeType.USER_TASK_NODE || type === NodeType.TRANSACTOR_NODE) { + if ( + type === BpmNodeTypeEnum.USER_TASK_NODE || + type === BpmNodeTypeEnum.TRANSACTOR_NODE + ) { const id = `Activity_${generateUUID()}`; const data: SimpleFlowNode = { id, @@ -83,20 +88,20 @@ function addNode(type: number) { }; emits('update:childNode', data); } - if (type === NodeType.COPY_TASK_NODE) { + if (type === BpmNodeTypeEnum.COPY_TASK_NODE) { const data: SimpleFlowNode = { id: `Activity_${generateUUID()}`, - name: NODE_DEFAULT_NAME.get(NodeType.COPY_TASK_NODE) as string, + name: NODE_DEFAULT_NAME.get(BpmNodeTypeEnum.COPY_TASK_NODE) as string, showText: '', - type: NodeType.COPY_TASK_NODE, + type: BpmNodeTypeEnum.COPY_TASK_NODE, childNode: props.childNode, }; emits('update:childNode', data); } - if (type === NodeType.CONDITION_BRANCH_NODE) { + if (type === BpmNodeTypeEnum.CONDITION_BRANCH_NODE) { const data: SimpleFlowNode = { name: '条件分支', - type: NodeType.CONDITION_BRANCH_NODE, + type: BpmNodeTypeEnum.CONDITION_BRANCH_NODE, id: `GateWay_${generateUUID()}`, childNode: props.childNode, conditionNodes: [ @@ -104,7 +109,7 @@ function addNode(type: number) { id: `Flow_${generateUUID()}`, name: '条件1', showText: '', - type: NodeType.CONDITION_NODE, + type: BpmNodeTypeEnum.CONDITION_NODE, childNode: undefined, conditionSetting: { defaultFlow: false, @@ -116,7 +121,7 @@ function addNode(type: number) { id: `Flow_${generateUUID()}`, name: '其它情况', showText: '未满足其它条件时,将进入此分支', - type: NodeType.CONDITION_NODE, + type: BpmNodeTypeEnum.CONDITION_NODE, childNode: undefined, conditionSetting: { defaultFlow: true, @@ -126,10 +131,10 @@ function addNode(type: number) { }; emits('update:childNode', data); } - if (type === NodeType.PARALLEL_BRANCH_NODE) { + if (type === BpmNodeTypeEnum.PARALLEL_BRANCH_NODE) { const data: SimpleFlowNode = { name: '并行分支', - type: NodeType.PARALLEL_BRANCH_NODE, + type: BpmNodeTypeEnum.PARALLEL_BRANCH_NODE, id: `GateWay_${generateUUID()}`, childNode: props.childNode, conditionNodes: [ @@ -137,24 +142,24 @@ function addNode(type: number) { id: `Flow_${generateUUID()}`, name: '并行1', showText: '无需配置条件同时执行', - type: NodeType.CONDITION_NODE, + type: BpmNodeTypeEnum.CONDITION_NODE, childNode: undefined, }, { id: `Flow_${generateUUID()}`, name: '并行2', showText: '无需配置条件同时执行', - type: NodeType.CONDITION_NODE, + type: BpmNodeTypeEnum.CONDITION_NODE, childNode: undefined, }, ], }; emits('update:childNode', data); } - if (type === NodeType.INCLUSIVE_BRANCH_NODE) { + if (type === BpmNodeTypeEnum.INCLUSIVE_BRANCH_NODE) { const data: SimpleFlowNode = { name: '包容分支', - type: NodeType.INCLUSIVE_BRANCH_NODE, + type: BpmNodeTypeEnum.INCLUSIVE_BRANCH_NODE, id: `GateWay_${generateUUID()}`, childNode: props.childNode, conditionNodes: [ @@ -162,7 +167,7 @@ function addNode(type: number) { id: `Flow_${generateUUID()}`, name: '包容条件1', showText: '', - type: NodeType.CONDITION_NODE, + type: BpmNodeTypeEnum.CONDITION_NODE, childNode: undefined, conditionSetting: { defaultFlow: false, @@ -174,7 +179,7 @@ function addNode(type: number) { id: `Flow_${generateUUID()}`, name: '其它情况', showText: '未满足其它条件时,将进入此分支', - type: NodeType.CONDITION_NODE, + type: BpmNodeTypeEnum.CONDITION_NODE, childNode: undefined, conditionSetting: { defaultFlow: true, @@ -184,42 +189,42 @@ function addNode(type: number) { }; emits('update:childNode', data); } - if (type === NodeType.DELAY_TIMER_NODE) { + if (type === BpmNodeTypeEnum.DELAY_TIMER_NODE) { const data: SimpleFlowNode = { id: `Activity_${generateUUID()}`, - name: NODE_DEFAULT_NAME.get(NodeType.DELAY_TIMER_NODE) as string, + name: NODE_DEFAULT_NAME.get(BpmNodeTypeEnum.DELAY_TIMER_NODE) as string, showText: '', - type: NodeType.DELAY_TIMER_NODE, + type: BpmNodeTypeEnum.DELAY_TIMER_NODE, childNode: props.childNode, }; emits('update:childNode', data); } - if (type === NodeType.ROUTER_BRANCH_NODE) { + if (type === BpmNodeTypeEnum.ROUTER_BRANCH_NODE) { const data: SimpleFlowNode = { id: `GateWay_${generateUUID()}`, - name: NODE_DEFAULT_NAME.get(NodeType.ROUTER_BRANCH_NODE) as string, + name: NODE_DEFAULT_NAME.get(BpmNodeTypeEnum.ROUTER_BRANCH_NODE) as string, showText: '', - type: NodeType.ROUTER_BRANCH_NODE, + type: BpmNodeTypeEnum.ROUTER_BRANCH_NODE, childNode: props.childNode, }; emits('update:childNode', data); } - if (type === NodeType.TRIGGER_NODE) { + if (type === BpmNodeTypeEnum.TRIGGER_NODE) { const data: SimpleFlowNode = { id: `Activity_${generateUUID()}`, - name: NODE_DEFAULT_NAME.get(NodeType.TRIGGER_NODE) as string, + name: NODE_DEFAULT_NAME.get(BpmNodeTypeEnum.TRIGGER_NODE) as string, showText: '', - type: NodeType.TRIGGER_NODE, + type: BpmNodeTypeEnum.TRIGGER_NODE, childNode: props.childNode, }; emits('update:childNode', data); } - if (type === NodeType.CHILD_PROCESS_NODE) { + if (type === BpmNodeTypeEnum.CHILD_PROCESS_NODE) { const data: SimpleFlowNode = { id: `Activity_${generateUUID()}`, - name: NODE_DEFAULT_NAME.get(NodeType.CHILD_PROCESS_NODE) as string, + name: NODE_DEFAULT_NAME.get(BpmNodeTypeEnum.CHILD_PROCESS_NODE) as string, showText: '', - type: NodeType.CHILD_PROCESS_NODE, + type: BpmNodeTypeEnum.CHILD_PROCESS_NODE, childNode: props.childNode, childProcessSetting: { calledProcessDefinitionKey: '', @@ -247,7 +252,10 @@ function addNode(type: number) {