From b9ddd1eaa68c94dc2aa57ccaa27b5cb99e6b51eb Mon Sep 17 00:00:00 2001 From: Lemon <1599456917@qq.com> Date: Fri, 21 Feb 2025 18:59:46 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=AE=A1=E6=89=B9=E8=B6=85=E6=97=B6?= =?UTF-8?q?=E5=BB=B6=E8=BF=9F=E5=99=A8=E5=BB=B6=E8=BF=9F=E8=B7=B3=E8=BD=AC?= =?UTF-8?q?=E4=BB=BB=E6=84=8F=E6=8C=87=E5=AE=9A=E7=9A=84=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/ProcessNodeTree.vue | 34 ++++++-- .../SimpleProcessDesignerV2/src/consts.ts | 23 +++++- .../SimpleProcessDesignerV2/src/node.ts | 1 + .../src/nodes-config/DelayTimerNodeConfig.vue | 77 ++++++++++++++++++- .../src/nodes-config/UserTaskNodeConfig.vue | 53 ++++++++++--- .../src/nodes/DelayTimerNode.vue | 76 ++++++++++++++++++ .../src/nodes/UserTaskNode.vue | 36 ++++++++- 7 files changed, 277 insertions(+), 23 deletions(-) diff --git a/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue b/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue index cdb540322..70de02b9c 100644 --- a/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue +++ b/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue @@ -75,6 +75,7 @@ /> diff --git a/src/components/SimpleProcessDesignerV2/src/consts.ts b/src/components/SimpleProcessDesignerV2/src/consts.ts index 7270b104e..34c4cbfbf 100644 --- a/src/components/SimpleProcessDesignerV2/src/consts.ts +++ b/src/components/SimpleProcessDesignerV2/src/consts.ts @@ -233,6 +233,8 @@ export type TimeoutHandler = { timeDuration?: string // 执行动作是自动提醒, 最大提醒次数 maxRemindCount?: number + // 执行动作是自动跳转时,跳转的节点ID + returnNodeId?: string } /** @@ -291,6 +293,16 @@ export enum RejectHandlerType { */ RETURN_USER_TASK = 2 } +export enum DelaySettingType { + /** + * 默认开启 + */ + FINISH_PROCESS = 1, + /** + * 延迟器指定节点 + */ + RETURN_USER_TASK = 2 +} // 用户任务超时处理类型枚举 export enum TimeoutHandlerType { /** @@ -304,7 +316,11 @@ export enum TimeoutHandlerType { /** * 自动拒绝 */ - REJECT = 3 + REJECT = 3, + /** + * 自动跳转 + */ + AUTO_JUMP = 4 } // 用户任务的审批人为空时,处理类型枚举 export enum AssignEmptyHandlerType { @@ -570,7 +586,8 @@ export const TIME_UNIT_TYPES: DictDataVO[] = [ export const TIMEOUT_HANDLER_TYPES: DictDataVO[] = [ { label: '自动提醒', value: 1 }, { label: '自动同意', value: 2 }, - { label: '自动拒绝', value: 3 } + { label: '自动拒绝', value: 3 }, + { label: '自动跳转', value: 4 } ] export const REJECT_HANDLER_TYPES: DictDataVO[] = [ { label: '终止流程', value: RejectHandlerType.FINISH_PROCESS }, @@ -700,6 +717,8 @@ export type DelaySetting = { delayType: number // 延迟时间表达式 delayTime: string + autoJumpEnable?: boolean + returnNodeId?: string } /** * 延迟类型 diff --git a/src/components/SimpleProcessDesignerV2/src/node.ts b/src/components/SimpleProcessDesignerV2/src/node.ts index e3ac7c263..bbbca9855 100644 --- a/src/components/SimpleProcessDesignerV2/src/node.ts +++ b/src/components/SimpleProcessDesignerV2/src/node.ts @@ -156,6 +156,7 @@ export type UserTaskFormType = { assignStartUserHandlerType?: AssignStartUserHandlerType timeDuration?: number maxRemindCount?: number + timeoutReturnNodeId?: string buttonsSetting: any[] taskCreateListenerEnable?: boolean taskCreateListenerPath?: string diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/DelayTimerNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/DelayTimerNodeConfig.vue index 741796d3a..6517f84c3 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/DelayTimerNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/DelayTimerNodeConfig.vue @@ -65,6 +65,36 @@ /> 后进入下一节点 + + 延迟结束后 + + + + + + + + + @@ -65,11 +66,16 @@ const props = defineProps({ flowNode: { type: Object as () => SimpleFlowNode, required: true + }, + parentNode: { + type: Object as () => SimpleFlowNode, + default: null } }) // 定义事件,更新父组件。 const emits = defineEmits<{ 'update:flowNode': [node: SimpleFlowNode | undefined] + 'find:parentNode': [nodeList: SimpleFlowNode[], nodeType: NodeType] }>() // 是否只读 const readonly = inject('readonly') @@ -92,6 +98,76 @@ const openNodeConfig = () => { const deleteNode = () => { emits('update:flowNode', currentNode.value.childNode) } + +// 查找可跳转节点 +const findReturnTaskNodes = (matchNodeList: SimpleFlowNode[]) => { + // 从父节点查找所有用户任务节点(向上查找) + emits('find:parentNode', matchNodeList, NodeType.USER_TASK_NODE) + + // 从根节点开始查找所有用户任务节点(向下查找) + const rootNode = findRootNode(currentNode.value) + if (rootNode.type === NodeType.USER_TASK_NODE) { + // 如果找到了起始节点,从它的子节点开始查找 + if (rootNode.childNode) { + findAllUserTaskNodes(rootNode.childNode, matchNodeList) + } + } else { + // 否则从当前找到的最上层节点开始查找 + findAllUserTaskNodes(rootNode, matchNodeList) + } + + // 过滤掉当前节点 + const currentNodeId = currentNode.value.id + const filteredList = matchNodeList.filter(node => node.id !== currentNodeId) + matchNodeList.length = 0 + matchNodeList.push(...filteredList) +} + +// 查找根节点 +const findRootNode = (node: SimpleFlowNode): SimpleFlowNode => { + let parent: SimpleFlowNode | null = props.parentNode + let current: SimpleFlowNode = node + + while (parent !== null) { + current = parent + parent = findParentNode(current) + } + + return current +} + +// 查找父节点 +const findParentNode = (node: SimpleFlowNode): SimpleFlowNode | null => { + if (!props.parentNode) return null + if (props.parentNode.childNode === node) return props.parentNode + return null +} + +// 递归查找所有用户任务节点 +const findAllUserTaskNodes = (node: SimpleFlowNode, matchNodeList: SimpleFlowNode[]) => { + if (!node) return + + // 检查当前节点 + if (node.type === NodeType.USER_TASK_NODE) { + if (!matchNodeList.some(n => n.id === node.id)) { + matchNodeList.push(node) + } + } + + // 检查子节点 + if (node.childNode) { + findAllUserTaskNodes(node.childNode, matchNodeList) + } + + // 检查条件分支节点的子节点 + if (node.type === NodeType.CONDITION_BRANCH_NODE && node.conditionNodes) { + node.conditionNodes.forEach(conditionNode => { + if (conditionNode.childNode) { + findAllUserTaskNodes(conditionNode.childNode, matchNodeList) + } + }) + } +} diff --git a/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue b/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue index ae1af6c28..2ec34bedd 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue @@ -169,8 +169,42 @@ const deleteNode = () => { const findReturnTaskNodes = ( matchNodeList: SimpleFlowNode[] // 匹配的节点 ) => { - // 从父节点查找 + // 从父节点查找所有用户任务节点 emits('find:parentNode', matchNodeList, NodeType.USER_TASK_NODE) + + // 递归查找当前节点的子节点 + findChildUserTaskNodes(currentNode.value, matchNodeList) + + // 过滤掉当前节点 + const currentNodeId = currentNode.value.id + const filteredList = matchNodeList.filter(node => node.id !== currentNodeId) + matchNodeList.length = 0 // 清空原数组 + matchNodeList.push(...filteredList) // 将过滤后的节点重新加入数组 +} + +// 递归查找子节点中的用户任务节点 +const findChildUserTaskNodes = (node: SimpleFlowNode, matchNodeList: SimpleFlowNode[]) => { + if (!node) return + + // 检查子节点 + if (node.childNode) { + if (node.childNode.type === NodeType.USER_TASK_NODE) { + matchNodeList.push(node.childNode) + } + findChildUserTaskNodes(node.childNode, matchNodeList) + } + + // 检查条件分支节点的子节点 + if (node.type === NodeType.CONDITION_BRANCH_NODE && node.conditionNodes) { + node.conditionNodes.forEach(conditionNode => { + if (conditionNode.childNode && conditionNode.childNode.type === NodeType.USER_TASK_NODE) { + matchNodeList.push(conditionNode.childNode) + } + if (conditionNode.childNode) { + findChildUserTaskNodes(conditionNode.childNode, matchNodeList) + } + }) + } } // 任务的弹窗显示,用于只读模式 -- Gitee From 16c35012c1327a993c48b7127bfede7506ee1941 Mon Sep 17 00:00:00 2001 From: Lemon <1599456917@qq.com> Date: Sat, 22 Feb 2025 09:48:04 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=20?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E7=82=B9=E5=87=BB=E6=9D=A1=E4=BB=B6=E5=88=86?= =?UTF-8?q?=E6=94=AF=E5=90=8E=E5=B8=A6=E6=9D=A5=E7=9A=84=20=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E5=88=87=E6=8D=A2=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/nodes-config/ConditionNodeConfig.vue | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue index 6efed2604..9871aa953 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue @@ -63,9 +63,43 @@ const props = defineProps({ }) const settingVisible = ref(false) const currentNode = ref(props.conditionNode) -const condition = ref() +const condition = ref({ + conditionType: ConditionType.RULE, // 设置默认值 + conditionExpression: '', + conditionGroups: { + and: true, + conditions: [{ + and: true, + rules: [{ + opCode: '==', + leftSide: '', + rightSide: '' + }] + }] + } +}) const open = () => { - condition.value = currentNode.value.conditionSetting + // 如果有已存在的配置则使用,否则使用默认值 + if (currentNode.value.conditionSetting) { + condition.value = JSON.parse(JSON.stringify(currentNode.value.conditionSetting)) + } else { + // 重置为默认值 + condition.value = { + conditionType: ConditionType.RULE, + conditionExpression: '', + conditionGroups: { + and: true, + conditions: [{ + and: true, + rules: [{ + opCode: '==', + leftSide: '', + rightSide: '' + }] + }] + } + } + } settingVisible.value = true } @@ -123,15 +157,13 @@ const saveConfig = async () => { return false } currentNode.value.showText = showText - currentNode.value.conditionSetting!.conditionType = condition.value?.conditionType - if (currentNode.value.conditionSetting?.conditionType === ConditionType.EXPRESSION) { - currentNode.value.conditionSetting.conditionGroups = undefined - currentNode.value.conditionSetting.conditionExpression = condition.value?.conditionExpression - } - if (currentNode.value.conditionSetting!.conditionType === ConditionType.RULE) { - currentNode.value.conditionSetting!.conditionExpression = undefined - currentNode.value.conditionSetting!.conditionGroups = condition.value?.conditionGroups - } + // 深拷贝保存的条件设置,避免引用问题 + currentNode.value.conditionSetting = JSON.parse(JSON.stringify({ + ...currentNode.value.conditionSetting, + conditionType: condition.value?.conditionType, + conditionExpression: condition.value?.conditionType === ConditionType.EXPRESSION ? condition.value?.conditionExpression : undefined, + conditionGroups: condition.value?.conditionType === ConditionType.RULE ? condition.value?.conditionGroups : undefined + })) } settingVisible.value = false return true -- Gitee