From 2c43e9f678ee079b0c9c6817d64fe1876f2cacc7 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Thu, 30 Oct 2025 21:29:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=94=9F=E6=88=90=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E6=9C=8D=E5=8A=A1=E4=BB=A3=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enums/WorkflowInstanceStatusEnums.java | 11 +++-- .../event/handler/ProcessEventHandler.java | 44 ++++++++++++++++++- .../db/changelog/changes/v1.0.0-schema.sql | 3 +- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/WorkflowInstanceStatusEnums.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/WorkflowInstanceStatusEnums.java index f65264cd..b8602440 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/WorkflowInstanceStatusEnums.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/WorkflowInstanceStatusEnums.java @@ -28,17 +28,22 @@ public enum WorkflowInstanceStatusEnums { SUSPENDED("SUSPENDED", "已暂停"), /** - * 已完成:流程实例正常完成 + * 已完成:流程实例正常完成,所有节点均成功 */ COMPLETED("COMPLETED", "已完成"), + /** + * 部分成功:流程实例完成,但存在失败的节点 + */ + COMPLETED_WITH_ERRORS("COMPLETED_WITH_ERRORS", "部分成功"), + /** * 已终止:流程实例被手动终止 */ TERMINATED("TERMINATED", "已终止"), /** - * 执行失败:流程实例执行过程中发生错误 + * 执行失败:流程实例执行过程中发生错误或被中断 */ FAILED("FAILED", "执行失败"); @@ -76,7 +81,7 @@ public enum WorkflowInstanceStatusEnums { * 判断是否为终态(不可再变化的状态) */ public boolean isFinalState() { - return this == COMPLETED || this == TERMINATED || this == FAILED; + return this == COMPLETED || this == COMPLETED_WITH_ERRORS || this == TERMINATED || this == FAILED; } /** diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ProcessEventHandler.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ProcessEventHandler.java index 14d02f28..ac9bfecc 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ProcessEventHandler.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ProcessEventHandler.java @@ -1,8 +1,11 @@ package com.qqchen.deploy.backend.workflow.event.handler; import cn.hutool.core.date.DateUtil; +import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeInstance; import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums; +import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.dto.event.WorkflowInstanceStatusChangeEvent; +import com.qqchen.deploy.backend.workflow.repository.IWorkflowNodeInstanceRepository; import lombok.extern.slf4j.Slf4j; import org.flowable.common.engine.api.delegate.event.FlowableEvent; import org.flowable.engine.ProcessEngine; @@ -13,6 +16,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import jakarta.annotation.Resource; +import java.util.List; @Slf4j @Component @@ -25,6 +29,9 @@ public class ProcessEventHandler implements IFlowableEventHandler { @Lazy private ProcessEngine processEngine; + @Resource + private IWorkflowNodeInstanceRepository workflowNodeInstanceRepository; + @Override public boolean canHandle(String eventType) { return eventType.startsWith("PROCESS_"); @@ -34,15 +41,24 @@ public class ProcessEventHandler implements IFlowableEventHandler { public void handle(FlowableEvent event) { String eventType = event.getType().name(); FlowableProcessEngineEvent processEvent = (FlowableProcessEngineEvent) event; - WorkflowInstanceStatusEnums status = convertToWorkflowStatus(eventType); + + // 对于 PROCESS_COMPLETED 事件,需要检查节点状态来决定最终状态 + WorkflowInstanceStatusEnums status; + if ("PROCESS_COMPLETED".equals(eventType)) { + status = determineCompletionStatus(processEvent.getProcessInstanceId()); + } else { + status = convertToWorkflowStatus(eventType); + } if (status != null) { - HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService() .createHistoricProcessInstanceQuery() .processInstanceId(processEvent.getProcessInstanceId()) .singleResult(); + log.info("工作流实例状态变更: processInstanceId={}, eventType={}, status={}", + processEvent.getProcessInstanceId(), eventType, status); + publisher.publishEvent(WorkflowInstanceStatusChangeEvent.builder() .processInstanceId(processEvent.getProcessInstanceId()) .status(status) @@ -53,6 +69,30 @@ public class ProcessEventHandler implements IFlowableEventHandler { } } + /** + * 判断流程完成时的最终状态 + * + * @param processInstanceId 流程实例ID + * @return 如果所有节点成功返回 COMPLETED,如果有节点失败返回 COMPLETED_WITH_ERRORS + */ + private WorkflowInstanceStatusEnums determineCompletionStatus(String processInstanceId) { + // 查询该流程的所有节点实例 + List nodeInstances = workflowNodeInstanceRepository.findByProcessInstanceId(processInstanceId); + + // 检查是否有失败的节点(排除开始和结束节点) + boolean hasFailedNode = nodeInstances.stream() + .filter(node -> !"StartEvent".equals(node.getNodeType()) && !"EndEvent".equals(node.getNodeType())) + .anyMatch(node -> WorkflowNodeInstanceStatusEnums.FAILED.equals(node.getStatus())); + + if (hasFailedNode) { + log.warn("工作流实例 {} 完成,但存在失败的节点", processInstanceId); + return WorkflowInstanceStatusEnums.COMPLETED_WITH_ERRORS; + } else { + log.info("工作流实例 {} 完成,所有节点均成功", processInstanceId); + return WorkflowInstanceStatusEnums.COMPLETED; + } + } + private WorkflowInstanceStatusEnums convertToWorkflowStatus(String eventType) { return switch (eventType) { case "PROCESS_CREATED" -> WorkflowInstanceStatusEnums.CREATED; diff --git a/backend/src/main/resources/db/changelog/changes/v1.0.0-schema.sql b/backend/src/main/resources/db/changelog/changes/v1.0.0-schema.sql index 39f8cf2f..59c9bc16 100644 --- a/backend/src/main/resources/db/changelog/changes/v1.0.0-schema.sql +++ b/backend/src/main/resources/db/changelog/changes/v1.0.0-schema.sql @@ -610,8 +610,9 @@ CREATE TABLE workflow_instance workflow_definition_id BIGINT NOT NULL COMMENT '工作流定义ID', business_key VARCHAR(64) NULL COMMENT '业务标识', form_data_id BIGINT NULL COMMENT '启动表单数据ID(外键关联form_data)', - status VARCHAR(100) NOT NULL COMMENT '实例状态', + status ENUM('NOT_STARTED','CREATED','RUNNING','SUSPENDED','COMPLETED','COMPLETED_WITH_ERRORS','TERMINATED','FAILED') NOT NULL COMMENT '实例状态', variables TEXT NULL COMMENT '流程变量(JSON)', + form_data JSON NULL COMMENT '表单数据(JSON)', graph_snapshot JSON NULL COMMENT '流程图数据快照(启动时保存,用于画布还原)', start_time DATETIME(6) NULL COMMENT '开始时间', end_time DATETIME(6) NULL COMMENT '结束时间',