Ver código fonte

工作流 Flowable 取消流程实例实现

jason 3 anos atrás
pai
commit
d30bf0601c

+ 9 - 4
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java

@@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task;
 
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParam;
@@ -50,4 +47,12 @@ public class BpmProcessInstanceController {
     public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) {
     public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) {
         return success(processInstanceService.getProcessInstanceVO(id));
         return success(processInstanceService.getProcessInstanceVO(id));
     }
     }
+
+    @DeleteMapping("/cancel")
+    @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")
+    @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")
+    public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
+        processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
+        return success(true);
+    }
 }
 }

+ 21 - 1
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java

@@ -5,18 +5,23 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessI
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
+import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent;
+import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.flowable.engine.repository.ProcessDefinition;
+import org.flowable.engine.runtime.ProcessInstance;
 import org.flowable.task.api.Task;
 import org.flowable.task.api.Task;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.Mapping;
 import org.mapstruct.MappingTarget;
 import org.mapstruct.MappingTarget;
+import org.mapstruct.Mappings;
 import org.mapstruct.factory.Mappers;
 import org.mapstruct.factory.Mappers;
 
 
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.Optional;
 
 
 /**
 /**
  * 流程实例 Convert
  * 流程实例 Convert
@@ -73,7 +78,22 @@ public interface BpmProcessInstanceConvert {
 
 
     BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean);
     BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean);
 
 
+    default BpmProcessInstanceResultEvent convert(Object source, HistoricProcessInstance instance, Integer result) {
+        BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
+        event.setId(instance.getId());
+        event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
+        event.setBusinessKey(instance.getBusinessKey());
+        event.setResult(result);
+        return event;
+    }
 
 
-
+    default BpmMessageSendWhenProcessInstanceApproveReqDTO convert2ApprovedReq(ProcessInstance instance){
+        Long startUserId = instance.getStartUserId() == null ? null : Long.valueOf(instance.getStartUserId());
+        BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO = new BpmMessageSendWhenProcessInstanceApproveReqDTO()
+                .setStartUserId(startUserId)
+                .setProcessInstanceId(instance.getId())
+                .setProcessInstanceName(instance.getName());
+        return reqDTO;
+    }
 
 
 }
 }

+ 11 - 1
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java

@@ -101,7 +101,17 @@ public interface BpmTaskConvert {
     })
     })
     BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, AdminUserRespDTO startUser);
     BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, AdminUserRespDTO startUser);
 
 
-
+    default BpmTaskExtDO convert2TaskExt(Task task){
+        Long assigneeUserId = task.getAssignee() == null ? null : Long.valueOf(task.getAssignee());
+        BpmTaskExtDO taskExtDO = new BpmTaskExtDO()
+                .setTaskId(task.getId())
+                .setAssigneeUserId(assigneeUserId)
+                .setName(task.getName())
+                .setProcessDefinitionId(task.getProcessDefinitionId())
+                .setProcessInstanceId(task.getProcessInstanceId());
+        taskExtDO.setCreateTime(task.getCreateTime());
+        return taskExtDO;
+    }
 }
 }
 
 
 
 

+ 5 - 6
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java

@@ -28,8 +28,8 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
 
 
     public static final Set<FlowableEngineEventType> PROCESS_INSTANCE_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
     public static final Set<FlowableEngineEventType> PROCESS_INSTANCE_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
                      .add(FlowableEngineEventType.PROCESS_CREATED)
                      .add(FlowableEngineEventType.PROCESS_CREATED)
-                     .add(FlowableEngineEventType.PROCESS_STARTED)
                      .add(FlowableEngineEventType.PROCESS_CANCELLED)
                      .add(FlowableEngineEventType.PROCESS_CANCELLED)
+                     .add(FlowableEngineEventType.PROCESS_COMPLETED)
                      .build();
                      .build();
 
 
     public BpmProcessInstanceEventListener(){
     public BpmProcessInstanceEventListener(){
@@ -42,13 +42,12 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
     }
     }
 
 
     @Override
     @Override
-    protected void processStarted(FlowableProcessStartedEvent event) {
-        super.processStarted(event);
+    protected void processCancelled(FlowableCancelledEvent event) {
+        processInstanceService.updateProcessInstanceExtCancel(event);
     }
     }
 
 
-
     @Override
     @Override
-    protected void processCancelled(FlowableCancelledEvent event) {
-        super.processCancelled(event);
+    protected void processCompleted(FlowableEngineEntityEvent event) {
+        processInstanceService.updateProcessInstanceExtComplete((ProcessInstance)event.getEntity());
     }
     }
 }
 }

+ 5 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java

@@ -39,4 +39,9 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
     protected void taskCreated(FlowableEngineEntityEvent event) {
     protected void taskCreated(FlowableEngineEntityEvent event) {
         taskService.createTaskExt((Task) event.getEntity());
         taskService.createTaskExt((Task) event.getEntity());
     }
     }
+
+    @Override
+    protected void taskCompleted(FlowableEngineEntityEvent event) {
+        super.taskCompleted(event);
+    }
 }
 }

+ 34 - 4
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java

@@ -2,11 +2,9 @@ package cn.iocoder.yudao.module.bpm.service.task;
 
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
 import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
 import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
+import org.flowable.engine.delegate.event.FlowableCancelledEvent;
 import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.runtime.ProcessInstance;
 import org.flowable.engine.runtime.ProcessInstance;
 
 
@@ -22,6 +20,14 @@ import java.util.Set;
  */
  */
 public interface BpmProcessInstanceService {
 public interface BpmProcessInstanceService {
 
 
+    /**
+     * 获得流程实例
+     *
+     * @param id 流程实例的编号
+     * @return 流程实例
+     */
+    ProcessInstance getProcessInstance(String id);
+
     /**
     /**
      * 获得流程实例列表
      * 获得流程实例列表
      *
      *
@@ -67,6 +73,14 @@ public interface BpmProcessInstanceService {
      */
      */
     BpmProcessInstanceRespVO getProcessInstanceVO(String id);
     BpmProcessInstanceRespVO getProcessInstanceVO(String id);
 
 
+    /**
+     * 取消流程实例
+     *
+     * @param userId 用户编号
+     * @param cancelReqVO 取消信息
+     */
+    void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO);
+
     /**
     /**
      * 获得历史的流程实例
      * 获得历史的流程实例
      *
      *
@@ -81,4 +95,20 @@ public interface BpmProcessInstanceService {
      * @param instance 流程任务
      * @param instance 流程任务
      */
      */
     void createProcessInstanceExt(ProcessInstance instance);
     void createProcessInstanceExt(ProcessInstance instance);
+
+    /**
+     * 更新 ProcessInstance 拓展记录为取消
+     *
+     * @param event 流程取消事件
+     */
+    void updateProcessInstanceExtCancel(FlowableCancelledEvent event);
+
+    /**
+     * 更新 ProcessInstance 拓展记录为完成
+     *
+     * @param instance 流程任务
+     */
+    void updateProcessInstanceExtComplete(ProcessInstance instance);
+
+
 }
 }

+ 80 - 11
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java

@@ -4,17 +4,17 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
 import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
 import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;
 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
+import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
@@ -22,6 +22,7 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.flowable.engine.HistoryService;
 import org.flowable.engine.HistoryService;
 import org.flowable.engine.RuntimeService;
 import org.flowable.engine.RuntimeService;
+import org.flowable.engine.delegate.event.FlowableCancelledEvent;
 import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.flowable.engine.runtime.ProcessInstance;
 import org.flowable.engine.runtime.ProcessInstance;
@@ -32,15 +33,12 @@ import org.springframework.validation.annotation.Validated;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 import javax.validation.Valid;
 import javax.validation.Valid;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
 
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
-import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_IS_SUSPENDED;
-import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF;
 
 
 /**
 /**
  * 流程实例 Service 实现类
  * 流程实例 Service 实现类
@@ -74,6 +72,15 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
     private AdminUserApi adminUserApi;
     private AdminUserApi adminUserApi;
     @Resource
     @Resource
     private DeptApi deptApi;
     private DeptApi deptApi;
+    @Resource
+    private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher;
+    @Resource
+    private BpmMessageService messageService;
+    @Override
+    public ProcessInstance getProcessInstance(String id) {
+        return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();
+    }
+
     @Override
     @Override
     public List<ProcessInstance> getProcessInstances(Set<String> ids) {
     public List<ProcessInstance> getProcessInstances(Set<String> ids) {
         return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();
         return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();
@@ -134,6 +141,24 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
                 processDefinition, processDefinitionExt, bpmnXml, startUser, dept);
                 processDefinition, processDefinitionExt, bpmnXml, startUser, dept);
     }
     }
 
 
+    @Override
+    public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) {
+        // 校验流程实例存在
+        ProcessInstance instance = getProcessInstance(cancelReqVO.getId());
+        if (instance == null) {
+            throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
+        }
+        // 只能取消自己的
+        if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) {
+            throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);
+        }
+
+        // 通过删除流程实例,实现流程实例的取消,
+        // 删除流程实例,正则执行任务ACT_RU_TASK. 任务会被删除。通过历史表查询
+        runtimeService.deleteProcessInstance(cancelReqVO.getId(),
+                BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason()));
+    }
+
     /**
     /**
      * 获得历史的流程实例
      * 获得历史的流程实例
      *
      *
@@ -162,6 +187,51 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
         processInstanceExtMapper.insert(instanceExtDO);
         processInstanceExtMapper.insert(instanceExtDO);
     }
     }
 
 
+    @Override
+    public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) {
+        // 判断是否为 Reject 不通过。如果是,则不进行更新
+        if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) {
+            return;
+        }
+
+        // 需要主动查询,因为 instance 只有 id 属性
+        // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance
+        HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId());
+        // 更新拓展表
+        BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()
+                .setProcessInstanceId(event.getProcessInstanceId())
+                .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
+                .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
+                .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());
+
+        processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
+
+        // 发送流程实例的状态事件
+        processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
+                BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
+    }
+
+    @Override
+    public void updateProcessInstanceExtComplete(ProcessInstance instance) {
+        // 需要主动查询,因为 instance 只有 id 属性
+        // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance
+        HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId());
+        // 更新拓展表
+        BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()
+                .setProcessInstanceId(instance.getProcessInstanceId())
+                .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
+                .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
+                .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过
+        processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
+
+        // 发送流程被通过的消息
+        messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance));
+
+        // 发送流程实例的状态事件
+        processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
+                BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
+    }
+
     private String createProcessInstance0(Long userId, ProcessDefinition definition,
     private String createProcessInstance0(Long userId, ProcessDefinition definition,
                                           Map<String, Object> variables, String businessKey) {
                                           Map<String, Object> variables, String businessKey) {
         // 校验流程定义
         // 校验流程定义
@@ -181,7 +251,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
         processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId())
         processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId())
                 .setFormVariables(variables));
                 .setFormVariables(variables));
 
 
-
         return instance.getId();
         return instance.getId();
     }
     }
 }
 }

+ 7 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java

@@ -61,4 +61,11 @@ public interface BpmTaskService {
      */
      */
     void createTaskExt(Task task);
     void createTaskExt(Task task);
 
 
+    /**
+     * 更新 Task 拓展记录为完成
+     *
+     * @param task 任务实体
+     */
+    void updateTaskExtComplete(Task task);
+
 }
 }

+ 10 - 10
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

@@ -27,10 +27,7 @@ import org.flowable.task.api.history.HistoricTaskInstance;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -128,13 +125,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{
 
 
     @Override
     @Override
     public void createTaskExt(Task task) {
     public void createTaskExt(Task task) {
-        BpmTaskExtDO taskExtDO = new BpmTaskExtDO()
-                .setTaskId(task.getId())
-                .setAssigneeUserId(task.getAssignee() == null ? null : Long.valueOf(task.getAssignee()))
-                .setProcessDefinitionId(task.getProcessDefinitionId())
-                .setProcessInstanceId(task.getProcessInstanceId())
-                .setName(task.getName())
+        BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task)
                 .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
                 .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
         taskExtMapper.insert(taskExtDO);
         taskExtMapper.insert(taskExtDO);
     }
     }
+
+    @Override
+    public void updateTaskExtComplete(Task task) {
+        BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task)
+                .setEndTime(new Date()) // 此时不能使用 task 的 completeData,因为还是空的。
+                .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult());
+        taskExtMapper.updateByTaskId(taskExtDO);
+    }
 }
 }