Commit 5c3f30e60f74f5b54326f89f549fb563b1abf2bc

Authored by YunaiV
1 parent 692daf90

flowable 任务被取消(包括主动取消、会签取消)时,统一进行更新 task 状态。

Showing 36 changed files with 187 additions and 386 deletions
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmModelFormTypeEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java
1   -package cn.iocoder.yudao.module.bpm.domain.enums.definition;
  1 +package cn.iocoder.yudao.module.bpm.enums.definition;
2 2  
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Getter;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskAssignRuleTypeEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java
1   -package cn.iocoder.yudao.module.bpm.domain.enums.definition;
  1 +package cn.iocoder.yudao.module.bpm.enums.definition;
2 2  
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Getter;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskRuleScriptEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskRuleScriptEnum.java
1   -package cn.iocoder.yudao.module.bpm.domain.enums.definition;
  1 +package cn.iocoder.yudao.module.bpm.enums.definition;
2 2  
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Getter;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/message/BpmMessageEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/message/BpmMessageEnum.java
1   -package cn.iocoder.yudao.module.bpm.domain.enums.message;
  1 +package cn.iocoder.yudao.module.bpm.enums.message;
2 2  
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Getter;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceDeleteReasonEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java
1   -package cn.iocoder.yudao.module.bpm.domain.enums.task;
  1 +package cn.iocoder.yudao.module.bpm.enums.task;
2 2  
3 3 import cn.hutool.core.util.StrUtil;
4 4 import lombok.AllArgsConstructor;
... ... @@ -14,7 +14,12 @@ import lombok.Getter;
14 14 public enum BpmProcessInstanceDeleteReasonEnum {
15 15  
16 16 REJECT_TASK("不通过任务,原因:{}"), // 修改文案时,需要注意 isRejectReason 方法
17   - CANCEL_TASK("主动取消任务,原因:{}");
  17 + CANCEL_TASK("主动取消任务,原因:{}"),
  18 +
  19 + // ========== 流程任务的独有原因 ==========
  20 + MULTI_TASK_END("系统自动取消,原因:多任务审批已经满足条件,无需审批该任务"), // 多实例满足 condition 而结束时,其它任务实例任务会被取消,对应的删除原因是 MI_END
  21 +
  22 + ;
18 23  
19 24 private final String reason;
20 25  
... ... @@ -34,4 +39,20 @@ public enum BpmProcessInstanceDeleteReasonEnum {
34 39 return StrUtil.startWith(reason, "不通过任务,原因:");
35 40 }
36 41  
  42 + /**
  43 + * 将 Flowable 的删除原因,翻译成对应的中文原因
  44 + *
  45 + * @param reason 原始原因
  46 + * @return 原因
  47 + */
  48 + public static String translateReason(String reason) {
  49 + if (StrUtil.isEmpty(reason)) {
  50 + return reason;
  51 + }
  52 + switch (reason) {
  53 + case "MI_END": return MULTI_TASK_END.getReason();
  54 + default: return reason;
  55 + }
  56 + }
  57 +
37 58 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceResultEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java
1   -package cn.iocoder.yudao.module.bpm.domain.enums.task;
  1 +package cn.iocoder.yudao.module.bpm.enums.task;
2 2  
  3 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
3 4 import lombok.AllArgsConstructor;
4 5 import lombok.Getter;
5 6  
... ... @@ -16,10 +17,15 @@ public enum BpmProcessInstanceResultEnum {
16 17 APPROVE(2, "通过"),
17 18 REJECT(3, "不通过"),
18 19 CANCEL(4, "已取消"),
  20 +
  21 + // ========== 流程任务独有的状态 ==========
  22 +
19 23 BACK(5, "退回/驳回");
20 24  
21 25 /**
22 26 * 结果
  27 + *
  28 + * 如果新增时,注意 {@link #isEndResult(Integer)} 是否需要变更
23 29 */
24 30 private final Integer result;
25 31 /**
... ... @@ -27,4 +33,16 @@ public enum BpmProcessInstanceResultEnum {
27 33 */
28 34 private final String desc;
29 35  
  36 + /**
  37 + * 判断该结果是否已经处于 End 最终结果
  38 + *
  39 + * 主要用于一些结果更新的逻辑,如果已经是最终结果,就不再进行更新
  40 + *
  41 + * @param result 结果
  42 + * @return 是否
  43 + */
  44 + public static boolean isEndResult(Integer result) {
  45 + return ObjectUtils.equalsAny(result, APPROVE.getResult(), REJECT.getResult(), CANCEL.getResult(), BACK.getResult());
  46 + }
  47 +
30 48 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceStatusEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java
1   -package cn.iocoder.yudao.module.bpm.domain.enums.task;
  1 +package cn.iocoder.yudao.module.bpm.enums.task;
2 2  
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Getter;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
... ... @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskDonePage
7 7 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
8 8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;
9 9 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
10   -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum;
  10 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
11 11 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
12 12 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
13 13 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
... ... @@ -192,4 +192,4 @@ public interface BpmTaskConvert {
192 192 tmpMap.forEach((key, var) -> result.add(var));
193 193 return result;
194 194 }
195   -}
196 195 \ No newline at end of file
  196 +}
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java
1 1 package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmModelFormTypeEnum;
  4 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
5 5 import com.baomidou.mybatisplus.annotation.TableField;
6 6 import com.baomidou.mybatisplus.annotation.TableId;
7 7 import com.baomidou.mybatisplus.annotation.TableName;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java
... ... @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
5   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum;
6   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum;
  5 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
  6 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
7 7 import com.baomidou.mybatisplus.annotation.TableField;
8 8 import com.baomidou.mybatisplus.annotation.TableId;
9 9 import com.baomidou.mybatisplus.annotation.TableName;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java
1 1 package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
2 2  
3   -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum;
  3 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
4 4 import lombok.*;
5 5 import java.util.*;
6 6 import com.baomidou.mybatisplus.annotation.*;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java
1 1 package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4   -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum;
5   -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceStatusEnum;
  4 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
  5 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
6 6 import com.baomidou.mybatisplus.annotation.TableField;
7 7 import com.baomidou.mybatisplus.annotation.TableId;
8 8 import com.baomidou.mybatisplus.annotation.TableName;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java
1 1 package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4   -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum;
  4 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
5 5 import com.baomidou.mybatisplus.annotation.TableId;
6 6 import com.baomidou.mybatisplus.annotation.TableName;
7 7 import lombok.Data;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java
... ... @@ -20,18 +20,15 @@ public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> {
20 20 return selectList(BpmTaskExtDO::getTaskId, taskIds);
21 21 }
22 22  
  23 + default BpmTaskExtDO selectByTaskId(String taskId) {
  24 + return selectOne(BpmTaskExtDO::getTaskId, taskId);
  25 + }
  26 +
23 27 default List<BpmTaskExtDO> selectListByProcessInstanceId(String processInstanceId) {
24 28 return selectList(BpmTaskExtDO::getProcessInstanceId, processInstanceId);
25 29 }
26 30  
27 31 /**
28   - * 删除非当前相同taskDefKey非进行中的任务
29   - *
30   - * @param entity 任务信息
31   - */
32   - void delTaskByProcInstIdAndTaskIdAndTaskDefKey(@Param("entity") BpmTaskExtDO entity);
33   -
34   - /**
35 32 * 任务驳回
36 33 *
37 34 * @param taskId 任务列表
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/vo/ApproveProcInstVO.java
... ... @@ -15,6 +15,7 @@ import java.time.LocalDate;
15 15 @Data
16 16 @AllArgsConstructor
17 17 @NoArgsConstructor
  18 +// TODO @ke:这个类是不是没用呀
18 19 public class ApproveProcInstVO {
19 20  
20 21 @ApiModelProperty("任务id")
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java
... ... @@ -57,7 +57,8 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
57 57 Set<Long> candidateUserIds = bpmTaskRuleService.calculateTaskCandidateUsers(execution);
58 58 // 第二步,后随机选择一个任务的处理人
59 59 // 疑问:为什么一定要选择一个任务处理人?
60   - // 解答:项目对 bpm 的任务是责任到人,所以每个任务有且仅有一个处理人。如果希望一个任务可以同时被多个人处理,可以考虑使用 BpmParallelMultiInstanceBehavior 实现的会签 or 或签。
  60 + // 解答:项目对 bpm 的任务是责任到人,所以每个任务有且仅有一个处理人。
  61 + // 如果希望一个任务可以同时被多个人处理,可以考虑使用 BpmParallelMultiInstanceBehavior 实现的会签 or 或签。
61 62 int index = RandomUtil.randomInt(candidateUserIds.size());
62 63 return CollUtil.get(candidateUserIds, index);
63 64 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java
1 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script;
2 2  
3   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum;
  3 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
4 4 import org.flowable.engine.delegate.DelegateExecution;
5 5  
6 6 import java.util.Set;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java
1 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
2 2  
3   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum;
  3 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
4 4 import org.flowable.engine.delegate.DelegateExecution;
5 5 import org.springframework.stereotype.Component;
6 6  
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java
1 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
2 2  
3   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum;
  3 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
4 4 import org.flowable.engine.delegate.DelegateExecution;
5 5 import org.springframework.stereotype.Component;
6 6  
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java
... ... @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl
2 2  
3 3 import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
4 4 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
5   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum;
  5 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
6 6 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
7 7 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
8 8 import org.flowable.engine.delegate.DelegateExecution;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
1 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
2 2  
  3 +import cn.hutool.core.util.StrUtil;
3 4 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
  5 +import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService;
4 6 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
5 7 import com.google.common.collect.ImmutableSet;
  8 +import lombok.extern.slf4j.Slf4j;
6 9 import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
7 10 import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
8 11 import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
  12 +import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent;
  13 +import org.flowable.engine.history.HistoricActivityInstance;
9 14 import org.flowable.task.api.Task;
10 15 import org.springframework.context.annotation.Lazy;
11 16 import org.springframework.stereotype.Component;
... ... @@ -19,16 +24,22 @@ import java.util.Set;
19 24 * @author jason
20 25 */
21 26 @Component
  27 +@Slf4j
22 28 public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
23 29  
24 30 @Resource
25 31 @Lazy // 解决循环依赖
26 32 private BpmTaskService taskService;
27 33  
  34 + @Resource
  35 + @Lazy // 解决循环依赖
  36 + private BpmActivityService activityService;
  37 +
28 38 public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
29 39 .add(FlowableEngineEventType.TASK_CREATED)
30 40 .add(FlowableEngineEventType.TASK_ASSIGNED)
31 41 .add(FlowableEngineEventType.TASK_COMPLETED)
  42 + .add(FlowableEngineEventType.ACTIVITY_CANCELLED)
32 43 .build();
33 44  
34 45 public BpmTaskEventListener(){
... ... @@ -49,4 +60,18 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
49 60 protected void taskAssigned(FlowableEngineEntityEvent event) {
50 61 taskService.updateTaskExtAssign((Task)event.getEntity());
51 62 }
  63 +
  64 + @Override
  65 + protected void activityCancelled(FlowableActivityCancelledEvent event) {
  66 + HistoricActivityInstance activity = activityService.getHistoricActivityByExecutionId(event.getExecutionId());
  67 + if (activity == null) {
  68 + log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]", event.getExecutionId());
  69 + return;
  70 + }
  71 + if (StrUtil.isEmpty(activity.getTaskId())) {
  72 + return;
  73 + }
  74 + taskService.updateTaskExtCancel(activity.getTaskId());
  75 + }
  76 +
52 77 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java
... ... @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.bpm.convert.definition.BpmFormConvert;
9 9 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
10 10 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmFormMapper;
11 11 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
12   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmModelFormTypeEnum;
  12 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
13 13 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmFormFieldRespDTO;
14 14 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
15 15 import cn.iocoder.yudao.framework.common.pojo.PageResult;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
... ... @@ -10,7 +10,7 @@ import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
10 10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
11 11 import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
12 12 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
13   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmModelFormTypeEnum;
  13 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
14 14 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
15 15 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
16 16 import lombok.extern.slf4j.Slf4j;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java
... ... @@ -15,7 +15,7 @@ import cn.iocoder.yudao.module.bpm.convert.definition.BpmTaskAssignRuleConvert;
15 15 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
16 16 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
17 17 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
18   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum;
  18 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
19 19 import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
20 20 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
21 21 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
... ... @@ -274,7 +274,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
274 274  
275 275 // 移除被禁用的用户
276 276 removeDisableUsers(assigneeUserIds);
277   - // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人
  277 + // 如果候选人为空,抛出异常
278 278 if (CollUtil.isEmpty(assigneeUserIds)) {
279 279 log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", execution.getId(),
280 280 execution.getProcessDefinitionId(), execution.getCurrentActivityId(), toJsonString(rule));
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition.dto;
2 2  
3   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmModelFormTypeEnum;
  3 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
4 4 import lombok.Data;
5 5  
6 6 /**
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java
... ... @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.bpm.service.definition.dto;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.StrUtil;
5   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmModelFormTypeEnum;
  5 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
6 6 import lombok.Data;
7 7  
8 8 import javax.validation.constraints.AssertTrue;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java
... ... @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.bpm.service.message;
2 2  
3 3 import cn.iocoder.yudao.framework.web.config.WebProperties;
4 4 import cn.iocoder.yudao.module.bpm.convert.message.BpmMessageConvert;
5   -import cn.iocoder.yudao.module.bpm.domain.enums.message.BpmMessageEnum;
  5 +import cn.iocoder.yudao.module.bpm.enums.message.BpmMessageEnum;
6 6 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
7 7 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
8 8 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java
... ... @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeavePageReqVO;
9 9 import cn.iocoder.yudao.module.bpm.convert.oa.BpmOALeaveConvert;
10 10 import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO;
11 11 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOALeaveMapper;
12   -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum;
  12 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
13 13 import org.springframework.stereotype.Service;
14 14 import org.springframework.transaction.annotation.Transactional;
15 15 import org.springframework.validation.annotation.Validated;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java
1 1 package cn.iocoder.yudao.module.bpm.service.task;
2 2  
3 3 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
  4 +import org.flowable.engine.history.HistoricActivityInstance;
4 5  
5 6 import java.util.List;
6 7  
... ... @@ -19,4 +20,12 @@ public interface BpmActivityService {
19 20 */
20 21 List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId);
21 22  
  23 + /**
  24 + * 获得执行编号对应的活动实例
  25 + *
  26 + * @param executionId 执行编号
  27 + * @return 活动实例
  28 + */
  29 + HistoricActivityInstance getHistoricActivityByExecutionId(String executionId);
  30 +
22 31 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java
... ... @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper;
8 8 import lombok.extern.slf4j.Slf4j;
9 9  
10 10 import org.flowable.engine.HistoryService;
  11 +import org.flowable.engine.history.HistoricActivityInstance;
11 12 import org.springframework.stereotype.Service;
12 13 import org.springframework.validation.annotation.Validated;
13 14  
... ... @@ -38,4 +39,10 @@ public class BpmActivityServiceImpl implements BpmActivityService {
38 39 List<BpmActivityDO> bpmActivityDOList = bpmActivityMapper.listAllByProcInstIdAndDelete(procInstId);
39 40 return BpmActivityConvert.INSTANCE.convertList(bpmActivityDOList);
40 41 }
  42 +
  43 + @Override
  44 + public HistoricActivityInstance getHistoricActivityByExecutionId(String executionId) {
  45 + return historyService.createHistoricActivityInstanceQuery().executionId(executionId).singleResult();
  46 + }
  47 +
41 48 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
1   -package cn.iocoder.yudao.module.bpm.service.task;
2   -
3   -import cn.hutool.core.collection.CollUtil;
4   -import cn.hutool.core.lang.Assert;
5   -import cn.hutool.core.util.StrUtil;
6   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
7   -import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
8   -import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
9   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
10   -import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
11   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
12   -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
13   -import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;
14   -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceDeleteReasonEnum;
15   -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum;
16   -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceStatusEnum;
17   -import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher;
18   -import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
19   -import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
20   -import cn.iocoder.yudao.module.system.api.dept.DeptApi;
21   -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
22   -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
23   -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
24   -import lombok.extern.slf4j.Slf4j;
25   -import org.flowable.engine.HistoryService;
26   -import org.flowable.engine.RuntimeService;
27   -import org.flowable.engine.delegate.event.FlowableCancelledEvent;
28   -import org.flowable.engine.history.HistoricProcessInstance;
29   -import org.flowable.engine.repository.ProcessDefinition;
30   -import org.flowable.engine.runtime.ProcessInstance;
31   -import org.flowable.task.api.Task;
32   -import org.springframework.context.annotation.Lazy;
33   -import org.springframework.scheduling.annotation.Async;
34   -import org.springframework.stereotype.Service;
35   -import org.springframework.transaction.annotation.Transactional;
36   -import org.springframework.validation.annotation.Validated;
37   -
38   -import javax.annotation.Resource;
39   -import javax.validation.Valid;
40   -import java.util.*;
41   -
42   -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
43   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
44   -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
45   -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF;
46   -
47   -/**
48   - * 流程实例 Service 实现类
49   - *
50   - * ProcessDefinition & ProcessInstance & Execution & Task 的关系:
51   - * 1. https://blog.csdn.net/bobozai86/article/details/105210414
52   - *
53   - * HistoricProcessInstance & ProcessInstance 的关系:
54   - * 1.https://my.oschina.net/843294669/blog/719024
55   - * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例
56   - *
57   - * @author 芋道源码
58   - */
59   -@Service
60   -@Validated
61   -@Slf4j
62   -public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService {
63   -
64   - @Resource
65   - private RuntimeService runtimeService;
66   - @Resource
67   - private BpmProcessInstanceExtMapper processInstanceExtMapper;
68   - @Resource
69   - @Lazy // 解决循环依赖
70   - private BpmTaskService taskService;
71   - @Resource
72   - private BpmProcessDefinitionService processDefinitionService;
73   - @Resource
74   - private HistoryService historyService;
75   - @Resource
76   - private AdminUserApi adminUserApi;
77   - @Resource
78   - private DeptApi deptApi;
79   - @Resource
80   - private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher;
81   - @Resource
82   - private BpmMessageService messageService;
83   - @Override
84   - public ProcessInstance getProcessInstance(String id) {
85   - return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();
86   - }
87   -
88   - @Override
89   - public List<ProcessInstance> getProcessInstances(Set<String> ids) {
90   - return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();
91   - }
92   -
93   - @Override
94   - public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
95   - BpmProcessInstanceMyPageReqVO pageReqVO) {
96   - // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页
97   - PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO);
98   - if (CollUtil.isEmpty(pageResult.getList())) {
99   - return new PageResult<>(pageResult.getTotal());
100   - }
101   -
102   - // 获得流程 Task Map
103   - List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId);
104   - Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds);
105   - // 转换返回
106   - return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap);
107   - }
108   -
109   - @Override
110   - @Transactional(rollbackFor = Exception.class)
111   - public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) {
112   - // 获得流程定义
113   - ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId());
114   - // 发起流程
115   - return createProcessInstance0(userId, definition, createReqVO.getVariables(), null);
116   - }
117   -
118   - @Override
119   - public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) {
120   - // 获得流程定义
121   - ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey());
122   - // 发起流程
123   - return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey());
124   - }
125   -
126   - @Override
127   - public BpmProcessInstanceRespVO getProcessInstanceVO(String id) {
128   - // 获得流程实例
129   - HistoricProcessInstance processInstance = getHistoricProcessInstance(id);
130   - if (processInstance == null) {
131   - return null;
132   - }
133   - BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id);
134   - Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id);
135   -
136   - // 获得流程定义
137   - ProcessDefinition processDefinition = processDefinitionService
138   - .getProcessDefinition(processInstance.getProcessDefinitionId());
139   - Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId());
140   - BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt(
141   - processInstance.getProcessDefinitionId());
142   - Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id);
143   - String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId());
144   -
145   - // 获得 User
146   - AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId()));
147   - DeptRespDTO dept = null;
148   - if (startUser != null) {
149   - dept = deptApi.getDept(startUser.getDeptId());
150   - }
151   -
152   - // 拼接结果
153   - return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt,
154   - processDefinition, processDefinitionExt, bpmnXml, startUser, dept);
155   - }
156   -
157   - @Override
158   - public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) {
159   - // 校验流程实例存在
160   - ProcessInstance instance = getProcessInstance(cancelReqVO.getId());
161   - if (instance == null) {
162   - throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
163   - }
164   - // 只能取消自己的
165   - if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) {
166   - throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);
167   - }
168   -
169   - // 通过删除流程实例,实现流程实例的取消,
170   - // 删除流程实例,正则执行任务ACT_RU_TASK. 任务会被删除。通过历史表查询
171   - deleteProcessInstance(cancelReqVO.getId(),
172   - BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason()));
173   - }
174   -
175   - /**
176   - * 获得历史的流程实例
177   - *
178   - * @param id 流程实例的编号
179   - * @return 历史的流程实例
180   - */
181   - @Override
182   - public HistoricProcessInstance getHistoricProcessInstance(String id) {
183   - return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();
184   - }
185   -
186   - @Override
187   - public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) {
188   - return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list();
189   - }
190   -
191   - @Override
192   - public void createProcessInstanceExt(ProcessInstance instance) {
193   - // 获得流程定义
194   - ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId());
195   - // 插入 BpmProcessInstanceExtDO 对象
196   - BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()
197   - .setProcessInstanceId(instance.getId())
198   - .setProcessDefinitionId(definition.getId())
199   - .setName(instance.getProcessDefinitionName())
200   - .setStartUserId(Long.valueOf(instance.getStartUserId()))
201   - .setCategory(definition.getCategory())
202   - .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus())
203   - .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
204   -
205   - processInstanceExtMapper.insert(instanceExtDO);
206   - }
207   -
208   - @Override
209   - public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) {
210   - // 判断是否为 Reject 不通过。如果是,则不进行更新
211   - if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) {
212   - return;
213   - }
214   -
215   - // 需要主动查询,因为 instance 只有 id 属性
216   - // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance
217   - HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId());
218   - // 更新拓展表
219   - BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()
220   - .setProcessInstanceId(event.getProcessInstanceId())
221   - .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
222   - .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
223   - .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());
224   -
225   - processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
226   -
227   - // 发送流程实例的状态事件
228   - processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
229   - BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
230   - }
231   -
232   - @Override
233   - public void updateProcessInstanceExtComplete(ProcessInstance instance) {
234   - // 需要主动查询,因为 instance 只有 id 属性
235   - // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance
236   - HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId());
237   - // 更新拓展表
238   - BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()
239   - .setProcessInstanceId(instance.getProcessInstanceId())
240   - .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
241   - .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
242   - .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过
243   - processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
244   -
245   - // 发送流程被通过的消息
246   - messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance));
247   -
248   - // 发送流程实例的状态事件
249   - processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
250   - BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
251   - }
252   -
253   - @Transactional(rollbackFor = Exception.class)
254   - public void updateProcessInstanceExtReject(String id, String reason) {
255   - // 需要主动查询,因为 instance 只有 id 属性
256   - ProcessInstance processInstance = getProcessInstance(id);
257   - // 删除流程实例,以实现驳回任务时,取消整个审批流程
258   - deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason)));
259   -
260   - // 更新 status + result
261   - // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法,
262   - // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的
263   - BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id)
264   - .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
265   - .setResult(BpmProcessInstanceResultEnum.REJECT.getResult());
266   - processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
267   -
268   - // 发送流程被不通过的消息
269   - messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason));
270   -
271   - // 发送流程实例的状态事件
272   - processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
273   - BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
274   - }
275   -
276   - private void deleteProcessInstance(String id, String reason) {
277   - runtimeService.deleteProcessInstance(id, reason);
278   - }
279   -
280   - private String createProcessInstance0(Long userId, ProcessDefinition definition,
281   - Map<String, Object> variables, String businessKey) {
282   - // 校验流程定义
283   - if (definition == null) {
284   - throw exception(PROCESS_DEFINITION_NOT_EXISTS);
285   - }
286   - if (definition.isSuspended()) {
287   - throw exception(PROCESS_DEFINITION_IS_SUSPENDED);
288   - }
289   -
290   - // 创建流程实例
291   - ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables);
292   - // 设置流程名字
293   - runtimeService.setProcessInstanceName(instance.getId(), definition.getName());
294   -
295   - // 补全流程实例的拓展表
296   - //TODO startProcessInstance流程里面修改了 BpmProcessInstanceExt,没有提交,和下面的更新 锁持有冲突了,异步更新这个表
297   -// processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()).setFormVariables(variables));
298   - BpmProcessInstanceExtDO bpmProcessInstanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()).setFormVariables(variables);
299   - asyncUpdateProcesInstance(bpmProcessInstanceExtDO);
300   - return instance.getId();
301   - }
302   -
303   - @Async
304   - public void asyncUpdateProcesInstance(BpmProcessInstanceExtDO bpmProcessInstanceExtDO){
305   - log.info("asyncUpdateProcesInstance ,cause MySQL Dead Lock");
306   - processInstanceExtMapper.updateByProcessInstanceId(bpmProcessInstanceExtDO);
307   -
308   - }
309   -}
  1 +package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; 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.dal.dataobject.definition.BpmProcessDefinitionExtDO; 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.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; 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.message.BpmMessageService; 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.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; import java.util.*; 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.module.bpm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF; /** * 流程实例 Service 实现类 * * ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. <a href="https://blog.csdn.net/bobozai86/article/details/105210414" /> * * HistoricProcessInstance & ProcessInstance 的关系: * 1. <a href=" https://my.oschina.net/843294669/blog/71902" /> * * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 * * @author 芋道源码 */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private RuntimeService runtimeService; @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private HistoryService historyService; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource private BpmMessageService messageService; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List<ProcessInstance> getProcessInstances(Set<String> ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id); Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id); // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, 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. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); } /** * 获得历史的流程实例 * * @param id 流程实例的编号 * @return 历史的流程实例 */ @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); // 插入 BpmProcessInstanceExtDO 对象 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getId()) .setProcessDefinitionId(definition.getId()) .setName(instance.getProcessDefinitionName()) .setStartUserId(Long.valueOf(instance.getStartUserId())) .setCategory(definition.getCategory()) .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); processInstanceExtMapper.insert(instanceExtDO); } @Override public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { // 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceExtReject 方法,已经进行更新了 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())); } @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceExtReject(String id, String reason) { // 需要主动查询,因为 instance 只有 id 属性 ProcessInstance processInstance = getProcessInstance(id); // 删除流程实例,以实现驳回任务时,取消整个审批流程 deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason))); // 更新 status + result // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法, // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id) .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map<String, Object> variables, String businessKey) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 创建流程实例 ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables); // 设置流程名字 runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); // 补全流程实例的拓展表 //TODO startProcessInstance流程里面修改了 BpmProcessInstanceExt,没有提交,和下面的更新 锁持有冲突了,异步更新这个表 // processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()).setFormVariables(variables)); BpmProcessInstanceExtDO bpmProcessInstanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()).setFormVariables(variables); asyncUpdateProcesInstance(bpmProcessInstanceExtDO); return instance.getId(); } @Async public void asyncUpdateProcesInstance(BpmProcessInstanceExtDO bpmProcessInstanceExtDO){ log.info("asyncUpdateProcesInstance ,cause MySQL Dead Lock"); processInstanceExtMapper.updateByProcessInstanceId(bpmProcessInstanceExtDO); } }
310 2 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
... ... @@ -17,6 +17,7 @@ import java.util.Map;
17 17 * @author 芋道源码
18 18 */
19 19 public interface BpmTaskService {
  20 +
20 21 /**
21 22 * 获得待办的流程任务分页
22 23 *
... ... @@ -121,6 +122,13 @@ public interface BpmTaskService {
121 122 void updateTaskExtComplete(Task task);
122 123  
123 124 /**
  125 + * 更新 Task 拓展记录为已取消
  126 + *
  127 + * @param taskId 任务的编号
  128 + */
  129 + void updateTaskExtCancel(String taskId);
  130 +
  131 + /**
124 132 * 更新 Task 拓展记录,并发送通知
125 133 *
126 134 * @param task 任务实体
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
... ... @@ -15,7 +15,8 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
15 15 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
16 16 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper;
17 17 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper;
18   -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum;
  18 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
  19 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
19 20 import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
20 21 import cn.iocoder.yudao.module.business.hi.task.inst.service.HiTaskInstService;
21 22 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
... ... @@ -214,14 +215,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
214 215 List<BpmTaskAssignRuleDO> bpmTaskAssignRuleList =
215 216 taskAssignRuleMapper.selectListByProcessDefinitionId(task.getProcessDefinitionId(),
216 217 task.getTaskDefinitionKey());
217   - if (CollUtil.isNotEmpty(bpmTaskAssignRuleList) && bpmTaskAssignRuleList.size() > 0) {
218   - // edit by 芋艿 TODO
219   -// if (BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType().equals(bpmTaskAssignRuleList.get(0).getType())) {
220   -// taskExtMapper.delTaskByProcInstIdAndTaskIdAndTaskDefKey(
221   -// new BpmTaskExtDO().setTaskId(task.getId()).setTaskDefKey(task.getTaskDefinitionKey())
222   -// .setProcessInstanceId(task.getProcessInstanceId()));
223   -// }
224   - }
225 218 }
226 219  
227 220 @Override
... ... @@ -292,6 +285,23 @@ public class BpmTaskServiceImpl implements BpmTaskService {
292 285 taskService.setAssignee(id, String.valueOf(userId));
293 286 }
294 287  
  288 + /**
  289 + * 校验任务是否存在, 并且是否是分配给自己的任务
  290 + *
  291 + * @param userId 用户 id
  292 + * @param taskId task id
  293 + */
  294 + private Task checkTask(Long userId, String taskId) {
  295 + Task task = getTask(taskId);
  296 + if (task == null) {
  297 + throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);
  298 + }
  299 + if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) {
  300 + throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
  301 + }
  302 + return task;
  303 + }
  304 +
295 305 @Override
296 306 public void createTaskExt(Task task) {
297 307 BpmTaskExtDO taskExtDO =
... ... @@ -301,11 +311,46 @@ public class BpmTaskServiceImpl implements BpmTaskService {
301 311  
302 312 @Override
303 313 public void updateTaskExtComplete(Task task) {
304   - BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task).setEndTime(new Date());
  314 + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task)
  315 + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()) // 不设置也问题不大,因为 Complete 一般是审核通过,已经设置
  316 + .setEndTime(new Date());
305 317 taskExtMapper.updateByTaskId(taskExtDO);
306 318 }
307 319  
308 320 @Override
  321 + public void updateTaskExtCancel(String taskId) {
  322 + // 需要在事务提交后,才进行查询。不然查询不到历史的原因
  323 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
  324 +
  325 + @Override
  326 + public void afterCommit() {
  327 + // 可能只是活动,不是任务,所以查询不到
  328 + HistoricTaskInstance task = getHistoricTask(taskId);
  329 + if (task == null) {
  330 + return;
  331 + }
  332 +
  333 + // 如果任务拓展表已经是完成的状态,则跳过
  334 + BpmTaskExtDO taskExt = taskExtMapper.selectByTaskId(taskId);
  335 + if (taskExt == null) {
  336 + log.error("[updateTaskExtCancel][taskId({}) 查找不到对应的记录,可能存在问题]", taskId);
  337 + return;
  338 + }
  339 + // 如果已经是最终的结果,则跳过
  340 + if (BpmProcessInstanceResultEnum.isEndResult(taskExt.getResult())) {
  341 + log.error("[updateTaskExtCancel][taskId({}) 处于结果({}),无需进行更新]", taskId, taskExt.getResult());
  342 + return;
  343 + }
  344 +
  345 + // 更新任务
  346 + taskExtMapper.updateById(new BpmTaskExtDO().setId(taskExt.getId()).setResult(BpmProcessInstanceResultEnum.CANCEL.getResult())
  347 + .setEndTime(new Date()).setReason(BpmProcessInstanceDeleteReasonEnum.translateReason(task.getDeleteReason())));
  348 + }
  349 +
  350 + });
  351 + }
  352 +
  353 + @Override
309 354 public void updateTaskExtAssign(Task task) {
310 355 BpmTaskExtDO taskExtDO =
311 356 new BpmTaskExtDO().setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())).setTaskId(task.getId());
... ... @@ -323,24 +368,12 @@ public class BpmTaskServiceImpl implements BpmTaskService {
323 368 });
324 369 }
325 370  
326   - /**
327   - * 校验任务是否存在, 并且是否是分配给自己的任务
328   - *
329   - * @param userId 用户 id
330   - * @param taskId task id
331   - */
332   - private Task checkTask(Long userId, String taskId) {
333   - Task task = getTask(taskId);
334   - if (task == null) {
335   - throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);
336   - }
337   - if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) {
338   - throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
339   - }
340   - return task;
341   - }
342   -
343 371 private Task getTask(String id) {
344 372 return taskService.createTaskQuery().taskId(id).singleResult();
345 373 }
  374 +
  375 + private HistoricTaskInstance getHistoricTask(String id) {
  376 + return historyService.createHistoricTaskInstanceQuery().taskId(id).singleResult();
  377 + }
  378 +
346 379 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/service/HiTaskInstService.java
... ... @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.business.hi.task.inst.service;
3 3 import cn.hutool.core.bean.BeanUtil;
4 4 import cn.hutool.core.collection.CollUtil;
5 5 import cn.hutool.core.util.ObjectUtil;
6   -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
7 6 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
8 7 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
9 8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;
... ... @@ -68,7 +67,6 @@ public class HiTaskInstService {
68 67 * @return 返回流程信息
69 68 */
70 69 @TenantIgnore
71   - @DataPermission(enable = false) // TODO 芋艿:先临时去掉
72 70 public List<BpmTaskRespVO> taskGetComment(List<BpmTaskExtDO> taskList, Object approved) {
73 71 BpmTaskExtDO task = taskList.get(taskList.size() - 1);
74 72 Map<String, BpmTaskExtDO> bpmTaskMap =
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmTaskExtMapper.xml
... ... @@ -2,14 +2,6 @@
2 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 3 <mapper namespace="cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper">
4 4  
5   -
6   - <update id="delTaskByProcInstIdAndTaskIdAndTaskDefKey">
7   - UPDATE bpm_task_ext
8   - SET deleted=1
9   - WHERE process_instance_id = #{entity.processInstanceId}
10   - AND task_def_key = #{entity.taskDefKey}
11   - AND task_id != #{entity.taskId}
12   - </update>
13 5 <update id="backByTaskId">
14 6 UPDATE bpm_task_ext
15 7 SET result=2,
... ... @@ -26,5 +18,4 @@
26 18 </foreach>
27 19 </update>
28 20  
29   -
30 21 </mapper>
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImplTest.java
... ... @@ -6,8 +6,8 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 6 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
7 7 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
8 8 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
9   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum;
10   -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum;
  9 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
  10 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
11 11 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
12 12 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
13 13 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
... ...