diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/config/FlowableConfig.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/config/FlowableConfig.java index 957f254e..21cef66f 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/config/FlowableConfig.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/config/FlowableConfig.java @@ -2,11 +2,13 @@ package com.qqchen.deploy.backend.workflow.config; import com.qqchen.deploy.backend.workflow.listener.event.FlowableEventDispatcher; import jakarta.annotation.Resource; +import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; import org.flowable.spring.SpringProcessEngineConfiguration; import org.flowable.spring.boot.EngineConfigurationConfigurer; import org.springframework.context.annotation.Configuration; import java.util.Collections; +import java.util.Map; /** * Flowable配置类 @@ -46,5 +48,13 @@ public class FlowableConfig implements EngineConfigurationConfigurer activity.getActivityId()) +// .orElse(null); +// +// log.info("Job full details - executionId: {}, elementId: {}, jobHandlerType: {}, jobHandlerConfiguration: {}, currentActivityId: {}, lastActivityId: {}", +// executionId, +// job.getElementId(), +// job.getJobHandlerType(), +// job.getJobHandlerConfiguration(), +// execution != null ? execution.getActivityId() : "null", +// lastActivityId); +// +// String processInstanceId = job.getProcessInstanceId(); +// String errorMessage = job.getExceptionMessage(); +// eventPublisher.publishEvent(new ProcessInstanceDeleteEvent(job.getId(), processInstanceId, errorMessage)); +// } +// } +//} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/event/handler/JobEventHandler.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/event/handler/JobEventHandler.java index 0500f837..26e63f3e 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/event/handler/JobEventHandler.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/event/handler/JobEventHandler.java @@ -1,16 +1,24 @@ package com.qqchen.deploy.backend.workflow.listener.event.handler; -import cn.hutool.json.JSONUtil; import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums; +import com.qqchen.deploy.backend.workflow.event.TerminationProcessInstanceListenerEvent; import lombok.extern.slf4j.Slf4j; import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; import org.flowable.common.engine.api.delegate.event.FlowableEvent; +import org.flowable.common.engine.impl.event.FlowableEntityExceptionEventImpl; +import org.flowable.engine.ManagementService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.runtime.Execution; +import org.flowable.job.api.Job; import org.flowable.job.service.impl.persistence.entity.JobEntityImpl; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; import jakarta.annotation.Resource; +import java.util.List; +import java.util.Map; + @Slf4j @Component public class JobEventHandler implements IFlowableEventHandler { @@ -18,6 +26,12 @@ public class JobEventHandler implements IFlowableEventHandler { @Resource private ApplicationEventPublisher publisher; + @Resource + private RuntimeService runtimeService; + + @Resource + private ManagementService managementService; + @Override public boolean canHandle(String eventType) { return eventType.startsWith("JOB_EXECUTION_"); @@ -29,11 +43,14 @@ public class JobEventHandler implements IFlowableEventHandler { if (!(event instanceof FlowableEngineEntityEvent entityEvent)) { return; } - //log.info("Processing job event: {}, jobType: {}", eventType, entityEvent.getType()); JobEntityImpl job = (JobEntityImpl) entityEvent.getEntity(); - //log.info("Processing job event: {}", JSONUtil.toJsonStr(job)); WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType); - if (status != null) { + switch (status) { + case FAILED -> { + publisher.publishEvent(new TerminationProcessInstanceListenerEvent(job.getId(), job.getProcessInstanceId(), ((FlowableEntityExceptionEventImpl) event).getCause().getMessage())); + } + } +// if (status != null) { // publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder() // .processInstanceId(job.getProcessInstanceId()) // .executionId(job.getExecutionId()) @@ -45,17 +62,17 @@ public class JobEventHandler implements IFlowableEventHandler { // .endTime(status.isFinalState() ? LocalDateTime.now() : null) // .build() // ); - } +// } } private WorkflowNodeInstanceStatusEnums convertToNodeStatus(String eventType) { return switch (eventType) { - case "JOB_EXECUTION_SUCCESS" -> WorkflowNodeInstanceStatusEnums.RUNNING; +// case "JOB_EXECUTION_SUCCESS" -> WorkflowNodeInstanceStatusEnums.RUNNING; // case "JOB_EXECUTION_START" -> WorkflowNodeInstanceStatusEnums.RUNNING; -// case "JOB_EXECUTION_FAILURE" -> WorkflowNodeInstanceStatusEnums.FAILED; + case "JOB_EXECUTION_FAILURE" -> WorkflowNodeInstanceStatusEnums.FAILED; // case "JOB_EXECUTION_REJECTED" -> WorkflowNodeInstanceStatusEnums.FAILED; // case "JOB_EXECUTION_NOJOB_FOUND" -> WorkflowNodeInstanceStatusEnums.FAILED; default -> null; }; } -} \ No newline at end of file +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/event/handler/ProcessEventHandler.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/event/handler/ProcessEventHandler.java index 666593da..fca31311 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/event/handler/ProcessEventHandler.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/event/handler/ProcessEventHandler.java @@ -5,6 +5,7 @@ import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.event.WorkflowInstanceStatusChangeEvent; import lombok.extern.slf4j.Slf4j; import org.flowable.common.engine.api.delegate.event.FlowableEvent; +import org.flowable.engine.HistoryService; import org.flowable.engine.ProcessEngine; import org.flowable.engine.delegate.event.FlowableProcessEngineEvent; import org.flowable.engine.history.HistoricProcessInstance; @@ -25,6 +26,9 @@ public class ProcessEventHandler implements IFlowableEventHandler { @Lazy private ProcessEngine processEngine; + @Resource + private HistoryService historyService; + @Override public boolean canHandle(String eventType) { return eventType.startsWith("PROCESS_"); @@ -37,6 +41,7 @@ public class ProcessEventHandler implements IFlowableEventHandler { WorkflowInstanceStatusEnums status = convertToWorkflowStatus(eventType); if (status != null) { + HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService() .createHistoricProcessInstanceQuery() .processInstanceId(processEvent.getProcessInstanceId()) diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/repository/IWorkflowNodeInstanceRepository.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/repository/IWorkflowNodeInstanceRepository.java index 13aa68f2..5118046e 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/repository/IWorkflowNodeInstanceRepository.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/repository/IWorkflowNodeInstanceRepository.java @@ -18,4 +18,6 @@ public interface IWorkflowNodeInstanceRepository extends IBaseRepository findByWorkflowInstanceId(Long workflowInstanceId); + + WorkflowNodeInstance findTop1ByProcessInstanceIdOrderByStartTimeDesc(String processInstanceId); } diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/BpmnConverter.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/BpmnConverter.java index 1b2d4204..be614620 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/BpmnConverter.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/BpmnConverter.java @@ -173,6 +173,9 @@ public class BpmnConverter { // 步骤2:根据节点类型进行特定配置 if (element instanceof ServiceTask) { configureServiceTask((ServiceTask) element, node, process, extensionElements); + } else if (element instanceof Gateway) { + // 为网关节点只添加监听器,不添加边界事件 + element.setExtensionElements(extensionElements); } else if (element instanceof StartEvent || element instanceof EndEvent) { // 为开始节点和结束节点设置监听器 element.setExtensionElements(extensionElements); @@ -347,15 +350,15 @@ public class BpmnConverter { } /** - * 为服务任务添加错误边界事件和错误结束事件 - * 当服务任务执行失败时,会触发错误边界事件,并流转到错误结束事件 + * 为活动节点添加错误边界事件和错误结束事件 + * 当节点执行失败时,会触发错误边界事件,并流转到错误结束事件 * * @param process BPMN流程定义 - * @param serviceTask 需要添加错误处理的服务任务 + * @param activity 需要添加错误处理的活动节点 */ - private void addErrorBoundaryEventHandler(Process process, ServiceTask serviceTask) { - BoundaryEvent boundaryEvent = createErrorBoundaryEvent(serviceTask); - EndEvent errorEndEvent = createErrorEndEvent(serviceTask); + private void addErrorBoundaryEventHandler(Process process, Activity activity) { + BoundaryEvent boundaryEvent = createErrorBoundaryEvent(activity); + EndEvent errorEndEvent = createErrorEndEvent(activity); SequenceFlow errorFlow = createErrorSequenceFlow(boundaryEvent, errorEndEvent); process.addFlowElement(boundaryEvent); @@ -366,15 +369,15 @@ public class BpmnConverter { /** * 创建错误边界事件 * - * @param serviceTask 关联的服务任务 + * @param activity 关联的活动节点 * @return 配置好的错误边界事件 */ - private BoundaryEvent createErrorBoundaryEvent(ServiceTask serviceTask) { + private BoundaryEvent createErrorBoundaryEvent(Activity activity) { BoundaryEvent boundaryEvent = new BoundaryEvent(); - boundaryEvent.setId(WorkFlowConstants.BOUNDARY_EVENT_ERROR_PREFIX + serviceTask.getId()); + boundaryEvent.setId(WorkFlowConstants.BOUNDARY_EVENT_ERROR_PREFIX + activity.getId()); boundaryEvent.setName("边界事件异常"); - boundaryEvent.setAttachedToRef(serviceTask); - boundaryEvent.setAttachedToRefId(serviceTask.getId()); + boundaryEvent.setAttachedToRef(activity); + boundaryEvent.setAttachedToRefId(activity.getId()); boundaryEvent.setCancelActivity(true); // 确保取消原有活动 // 配置错误事件定义 @@ -388,12 +391,12 @@ public class BpmnConverter { /** * 创建错误结束事件 * - * @param serviceTask 关联的服务任务 + * @param activity 关联的活动节点 * @return 配置好的错误结束事件 */ - private EndEvent createErrorEndEvent(ServiceTask serviceTask) { + private EndEvent createErrorEndEvent(Activity activity) { EndEvent errorEndEvent = new EndEvent(); - errorEndEvent.setId(WorkFlowConstants.END_EVENT_ERROR_PREFIX + serviceTask.getId()); + errorEndEvent.setId(WorkFlowConstants.END_EVENT_ERROR_PREFIX + activity.getId()); errorEndEvent.setName("结束事件异常"); // 添加终止定义 TerminateEventDefinition terminateEventDefinition = new TerminateEventDefinition(); @@ -438,7 +441,6 @@ public class BpmnConverter { String gatewayTypeCode = node.getPanelVariables().get("gatewayType").asText(); GatewayTypeEnums gatewayType = GatewayTypeEnums.fromCode(gatewayTypeCode); - // 根据网关类型创建对应的网关 Gateway gateway; switch (gatewayType) { case EXCLUSIVE_GATEWAY: