Browse Source

【缺陷修复】 解决并行分支拒绝任务时,流程未结束问题

jason 7 months ago
parent
commit
610f39de05

+ 8 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java

@@ -6,6 +6,7 @@ import jakarta.annotation.Resource;
 import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
 import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
 import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
+import org.flowable.engine.delegate.event.FlowableCancelledEvent;
 import org.flowable.engine.runtime.ProcessInstance;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Component;
@@ -22,6 +23,7 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
 
     public static final Set<FlowableEngineEventType> PROCESS_INSTANCE_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
             .add(FlowableEngineEventType.PROCESS_COMPLETED)
+            .add(FlowableEngineEventType.PROCESS_CANCELLED)
             .build();
 
     @Resource
@@ -37,4 +39,10 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
         processInstanceService.processProcessInstanceCompleted((ProcessInstance)event.getEntity());
     }
 
+    @Override
+    // 特殊情况:当跳转到 EndEvent 流程实例未结束, 会执行 deleteProcessInstance 方法。
+    protected void processCancelled(FlowableCancelledEvent event) {
+        ProcessInstance processInstance = processInstanceService.getProcessInstance(event.getProcessInstanceId());
+        processInstanceService.processProcessInstanceCompleted(processInstance);
+    }
 }

+ 1 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java

@@ -668,7 +668,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
         runtimeService.setVariable(id, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON, reason);
 
         // 2. 结束流程
-        taskService.moveTaskToEnd(id);
+        taskService.moveTaskToEnd(id, reason);
     }
 
     @Override

+ 2 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java

@@ -195,8 +195,9 @@ public interface BpmTaskService {
      * 将指定流程实例的、进行中的流程任务,移动到结束节点
      *
      * @param processInstanceId 流程编号
+     * @param reason 原因
      */
-    void moveTaskToEnd(String processInstanceId);
+    void moveTaskToEnd(String processInstanceId, String reason);
 
     /**
      * 将任务退回到指定的 targetDefinitionKey 位置

+ 11 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

@@ -166,7 +166,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
 
         // 4. 任务表单
         BpmFormDO taskForm = null;
-        if (StrUtil.isNotBlank(todoTask.getFormKey())){
+        if (StrUtil.isNotBlank(todoTask.getFormKey())) {
             taskForm = formService.getForm(NumberUtils.parseLong(todoTask.getFormKey()));
         }
 
@@ -652,7 +652,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         }
         // 3.2 情况二:直接结束,审批不通过
         processInstanceService.updateProcessInstanceReject(instance, reqVO.getReason()); // 标记不通过
-        moveTaskToEnd(task.getProcessInstanceId()); // 结束流程
+        moveTaskToEnd(task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason())); // 结束流程
     }
 
     /**
@@ -823,7 +823,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
     }
 
     @Override
-    public void moveTaskToEnd(String processInstanceId) {
+    public void moveTaskToEnd(String processInstanceId, String reason) {
         List<Task> taskList = getRunningTaskListByProcessInstanceId(processInstanceId, null, null);
         if (CollUtil.isEmpty(taskList)) {
             return;
@@ -849,6 +849,13 @@ public class BpmTaskServiceImpl implements BpmTaskService {
                 .processInstanceId(processInstanceId)
                 .moveActivityIdsToSingleActivityId(activityIds, endEvent.getId())
                 .changeState();
+
+        // 3. 如果跳转到 EndEvent 流程还未结束, 执行 deleteProcessInstance 方法。
+        List<Execution> executionList = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).list();
+        if (CollUtil.isNotEmpty(executionList)) {
+            log.warn("执行跳转到 EndEvent 后, 流程实例未结束。执行 [deleteProcessInstance] 方法");
+            runtimeService.deleteProcessInstance(processInstanceId, reason);
+        }
     }
 
     @Override
@@ -1197,7 +1204,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
                     }
                 }
                 // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
-                FlowableUtils.execute(processInstance.getTenantId(),()-> {
+                FlowableUtils.execute(processInstance.getTenantId(), () -> {
                     AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));
                     messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));
                 });