This commit is contained in:
asp_ly 2024-12-15 20:37:07 +08:00
parent a18e84b4a7
commit b065e35d5f
5 changed files with 77 additions and 63 deletions

View File

@ -0,0 +1,20 @@
package com.qqchen.deploy.backend.workflow.event;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import lombok.Builder;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
@Data
@Builder
public class WorkflowInstanceStatusChangeEvent {
private String processInstanceId;
private WorkflowInstanceStatusEnums status;
private LocalDateTime endTime;
}

View File

@ -1,59 +1,55 @@
package com.qqchen.deploy.backend.workflow.listener; package com.qqchen.deploy.backend.workflow.listener;
import cn.hutool.core.date.DateUtil;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.event.WorkflowInstanceStatusChangeEvent;
import com.qqchen.deploy.backend.workflow.service.IWorkflowInstanceService;
import com.qqchen.deploy.backend.workflow.service.IWorkflowNodeInstanceService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEvent; import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventListener; import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
import org.flowable.common.engine.api.delegate.event.FlowableEventType; import org.flowable.common.engine.api.delegate.event.FlowableEventType;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
@Component @Component
@Slf4j @Slf4j
public class FlowableJobEventListener implements FlowableEventListener { public class FlowableJobEventListener implements FlowableEventListener {
@Resource @Resource
@Lazy private ApplicationEventPublisher publisher;
private IWorkflowInstanceService workflowInstanceService;
@Resource @Resource
@Lazy @Lazy
private IWorkflowNodeInstanceService workflowNodeInstanceService; private HistoryService historyService;
@Override @Override
@EventListener
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT, fallbackExecution = true)
public void onEvent(FlowableEvent event) { public void onEvent(FlowableEvent event) {
log.info("FlowableJobEventListener: {}", event);
FlowableEventType eventType = event.getType(); FlowableEventType eventType = event.getType();
if (isProcessLevelEvent(eventType.name())) { if (isProcessLevelEvent(eventType.name())) {
FlowableEngineEntityEvent entity = (FlowableEngineEntityEvent) event;
String processInstanceId = entity.getProcessInstanceId();
WorkflowInstanceStatusEnums status = convertProcessLevelEventToStatus(eventType.name()); WorkflowInstanceStatusEnums status = convertProcessLevelEventToStatus(eventType.name());
FlowableEngineEntityEvent entity = (FlowableEngineEntityEvent) event; log.info("Process level event received: {} -> {}, processInstanceId: {}", eventType, status, processInstanceId);
log.info("Process level event received: {} -> {}, processInstanceId: {}", eventType, status, entity.getProcessInstanceId()); HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
workflowInstanceService.updateInstanceStatus(entity.getProcessInstanceId(), status); log.info("historicProcessInstance: {}", historicProcessInstance.getEndTime());
return; publisher.publishEvent(WorkflowInstanceStatusChangeEvent.builder()
} .processInstanceId(processInstanceId)
.status(status)
if (isActivityInstanceEvent(eventType.name())) { .endTime(DateUtil.toLocalDateTime(historicProcessInstance.getEndTime()))
FlowableEngineEntityEvent entity = (FlowableEngineEntityEvent) event; .build()
log.info("Activity level event received: {}, processInstanceId: {}", eventType, entity.getProcessInstanceId()); );
WorkflowNodeInstanceStatusEnums status = convertActivityEventToStatus(eventType.name());
if (status != null) {
workflowNodeInstanceService.updateNodeStatus(
entity.getProcessInstanceId(),
entity.getExecutionId(),
status
);
}
} }
//
// if (isActivityInstanceEvent(flowableEvent.name())) {
// System.out.println("节点:" + flowableEvent.name());
// return;
// }
} }
@Override @Override
@ -63,22 +59,18 @@ public class FlowableJobEventListener implements FlowableEventListener {
@Override @Override
public boolean isFireOnTransactionLifecycleEvent() { public boolean isFireOnTransactionLifecycleEvent() {
return false; return true;
} }
@Override @Override
public String getOnTransaction() { public String getOnTransaction() {
return ""; return "committed";
} }
private boolean isProcessLevelEvent(String eventType) { private boolean isProcessLevelEvent(String eventType) {
return eventType.startsWith("PROCESS_"); return eventType.startsWith("PROCESS_");
} }
private boolean isActivityInstanceEvent(String eventType) {
return eventType.startsWith("ACTIVITY_");
}
/** /**
* 将Flowable流程级别事件类型转换为工作流实例状态 * 将Flowable流程级别事件类型转换为工作流实例状态
* 只处理流程实例级别的事件不处理活动节点级别的事件 * 只处理流程实例级别的事件不处理活动节点级别的事件
@ -121,29 +113,4 @@ public class FlowableJobEventListener implements FlowableEventListener {
return null; return null;
} }
} }
/**
* 将Flowable活动节点事件类型转换为工作流节点实例状态
*
* @param eventType Flowable事件类型
* @return 工作流节点实例状态枚举如果不是节点级别事件则返回null
*/
private WorkflowNodeInstanceStatusEnums convertActivityEventToStatus(String eventType) {
switch (eventType) {
case "ACTIVITY_STARTED":
return WorkflowNodeInstanceStatusEnums.RUNNING;
case "ACTIVITY_COMPLETED":
return WorkflowNodeInstanceStatusEnums.COMPLETED;
case "ACTIVITY_CANCELLED":
return WorkflowNodeInstanceStatusEnums.TERMINATED;
case "ACTIVITY_ERROR_RECEIVED":
return WorkflowNodeInstanceStatusEnums.FAILED;
default:
return null;
}
}
} }

View File

@ -0,0 +1,25 @@
package com.qqchen.deploy.backend.workflow.listener;
import com.qqchen.deploy.backend.workflow.event.WorkflowInstanceStatusChangeEvent;
import com.qqchen.deploy.backend.workflow.service.IWorkflowInstanceService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Slf4j
@Component
public class WorkflowInstanceStatusChangeListener {
@Resource
private IWorkflowInstanceService workflowInstanceService;
@EventListener
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handleWorkflowStatusChange(WorkflowInstanceStatusChangeEvent event) {
log.info("Handling workflow status change event: {}", event);
workflowInstanceService.updateInstanceStatus(event.getProcessInstanceId(), event.getStatus(), event.getEndTime());
}
}

View File

@ -8,6 +8,8 @@ import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import org.flowable.engine.runtime.ProcessInstance; import org.flowable.engine.runtime.ProcessInstance;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -28,7 +30,7 @@ public interface IWorkflowInstanceService extends IBaseService<WorkflowInstance,
* @param status 新状态 * @param status 新状态
* @return 更新后的工作流实例 * @return 更新后的工作流实例
*/ */
WorkflowInstance updateInstanceStatus(String processInstanceId, WorkflowInstanceStatusEnums status); WorkflowInstance updateInstanceStatus(String processInstanceId, WorkflowInstanceStatusEnums status, LocalDateTime endTime);
/** /**
* 获取工作流实例详情 * 获取工作流实例详情

View File

@ -66,11 +66,11 @@ public class WorkflowInstanceServiceImpl extends BaseServiceImpl<WorkflowInstanc
} }
@Override @Override
public WorkflowInstance updateInstanceStatus(String processInstanceId, WorkflowInstanceStatusEnums status) { public WorkflowInstance updateInstanceStatus(String processInstanceId, WorkflowInstanceStatusEnums status, LocalDateTime endTime) {
WorkflowInstance instance = workflowInstanceRepository.findByProcessInstanceId(processInstanceId) WorkflowInstance instance = workflowInstanceRepository.findByProcessInstanceId(processInstanceId)
.orElseThrow(() -> new RuntimeException("Workflow instance not found: " + processInstanceId)); .orElseThrow(() -> new RuntimeException("Workflow instance not found: " + processInstanceId));
instance.setStatus(status); instance.setStatus(status);
instance.setEndTime(endTime);
return workflowInstanceRepository.save(instance); return workflowInstanceRepository.save(instance);
} }