diff --git a/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue b/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue index ab5b62714213bb36453a1bbccbc1ed75bb664b43..07e94590891ac49452eb7362cc9a9d8038743847 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 a8a0ac61e498d30f64e2e420413bb36094745105..aef75a29c5115254945aae6d6c659a759589f5fe 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 8e715b44f7873fc2d3374abc8ca1d1776601be6c..db0efe9b5142429ad4b2e00b8cdac76abb5201ac 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,95 @@ 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) + + // 检查当前节点是否在并行分支的条件节点内 + for (let i = 0; i < path.length; i++) { + const node = path[i] + if (node.type === NodeType.PARALLEL_BRANCH_NODE) { + // 如果找到并行分支节点,检查当前节点是否在其条件节点内 + if (node.conditionNodes?.some(conditionNode => { + // 检查当前节点是否在这个条件分支的子树中 + const subPath = findNodePath(currentNode, conditionNode) + if (subPath.length > 0) { + // 如果在条件分支内,检查是否在包容节点内 + // 从当前节点向上查找最近的包容节点 + for (const pathNode of subPath) { + if (pathNode.type === NodeType.INCLUSIVE_BRANCH_NODE) { + // 如果在包容节点内,允许创建条件分支 + return false + } + } + return true + } + return false + })) { + return true + } + } + } + + // 不在任何并行分支的条件节点内 + return false +} + +/** + * 查找从根节点到目标节点的路径 + * @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 [] +}