From f44dca25c993f47de714a166359df68c597d0588 Mon Sep 17 00:00:00 2001 From: Lemon <1599456917@qq.com> Date: Tue, 4 Mar 2025 12:05:07 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=AE=A1=E6=A0=B8=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=B9=B6=E8=A1=8C=E4=B8=8D=E5=85=81=E8=AE=B8=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/NodeHandler.vue | 20 +++- .../src/SimpleProcessModel.vue | 3 + .../SimpleProcessDesignerV2/src/utils.ts | 91 +++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue b/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue index ab5b62714..07e945908 100644 --- a/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue +++ b/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue @@ -85,6 +85,7 @@ import { DEFAULT_CONDITION_GROUP_VALUE } from './consts' import { generateUUID } from '@/utils' +import { isNodeInParallelBranch } from './utils' defineOptions({ name: 'NodeHandler' @@ -107,7 +108,24 @@ const emits = defineEmits(['update:childNode']) const readonly = inject('readonly') // 是否只读 -const addNode = (type: number) => { +// 注入根节点 +const rootNode = inject>('rootNode') + +const addNode = async (type: number) => { + // 验证条件分支 + if (type === NodeType.CONDITION_BRANCH_NODE) { + if (!rootNode?.value) { + console.warn('No root node found') + return + } + + // 检查是否在并行分支内 + if (isNodeInParallelBranch(props.currentNode, rootNode.value)) { + message.error('并行网关中不能执行条件分支,请转换为包容网关') + return + } + } + // 校验:条件分支、包容分支后面,不允许直接添加并行分支 if ( type === NodeType.PARALLEL_BRANCH_NODE && diff --git a/src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue b/src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue index a8a0ac61e..aef75a29c 100644 --- a/src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue +++ b/src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue @@ -86,6 +86,9 @@ const processNodeTree = useWatchNode(props) provide('readonly', props.readonly) +// 提供根节点给所有子组件 +provide('rootNode', processNodeTree) + // TODO 可优化:拖拽有点卡顿 /** 拖拽、放大缩小等操作 */ let scaleValue = ref(100) diff --git a/src/components/SimpleProcessDesignerV2/src/utils.ts b/src/components/SimpleProcessDesignerV2/src/utils.ts index 8e715b44f..2411f33ca 100644 --- a/src/components/SimpleProcessDesignerV2/src/utils.ts +++ b/src/components/SimpleProcessDesignerV2/src/utils.ts @@ -1,4 +1,5 @@ import { TimeUnitType, ApproveType, APPROVE_TYPE } from './consts' +import { SimpleFlowNode, NodeType } from './consts' // 获取条件节点默认的名称 export const getDefaultConditionNodeName = (index: number, defaultFlow: boolean | undefined): string => { @@ -39,3 +40,93 @@ export const getApproveTypeText = (approveType: ApproveType): string => { }) return approveTypeText } + +/** + * 检查节点是否在并行分支内且不在包容分支下 + * @param currentNode 当前节点 + * @param rootNode 流程根节点 + * @returns boolean + */ +export function isNodeInParallelBranch( + currentNode: SimpleFlowNode, + rootNode: SimpleFlowNode +): boolean { + const path = findNodePath(currentNode, rootNode) + + // 找到最近的包容分支节点和并行分支节点的位置 + let inclusiveIndex = -1 + let parallelIndex = -1 + + path.forEach((node, index) => { + if (node.type === NodeType.INCLUSIVE_BRANCH_NODE) { + inclusiveIndex = index + } + if (node.type === NodeType.PARALLEL_BRANCH_NODE) { + parallelIndex = index + } + }) + + // 如果没有并行分支,直接返回 false + if (parallelIndex === -1) { + return false + } + + // 如果有包容分支,且包容分支在并行分支之后,则允许添加条件分支 + // 即:包容分支是并行分支的子节点 + if (inclusiveIndex > parallelIndex) { + return false + } + + // 其他情况(在并行分支内且不在包容分支下)不允许添加条件分支 + return true +} + +/** + * 查找从根节点到目标节点的路径 + * @param targetNode 目标节点 + * @param currentNode 当前节点(通常是根节点) + * @param path 路径数组 + * @returns SimpleFlowNode[] + */ +export function findNodePath( + targetNode: SimpleFlowNode, + currentNode: SimpleFlowNode, + path: SimpleFlowNode[] = [] +): SimpleFlowNode[] { + // 如果找到目标节点,返回路径 + if (currentNode === targetNode) { + return [...path, currentNode] + } + + // 检查条件分支节点 + if (currentNode.conditionNodes) { + for (const conditionNode of currentNode.conditionNodes) { + // 在当前分支中搜索 + const newPath = [...path, currentNode] + + // 检查条件节点本身 + if (conditionNode === targetNode) { + return [...newPath, conditionNode] + } + + // 检查条件节点的子节点 + if (conditionNode.childNode) { + const result = findNodePath(targetNode, conditionNode.childNode, newPath) + if (result.length > 0) { + return result + } + } + } + } + + // 检查子节点 + if (currentNode.childNode) { + const newPath = [...path, currentNode] + const result = findNodePath(targetNode, currentNode.childNode, newPath) + if (result.length > 0) { + return result + } + } + + return [] +}