From 5c3f30e60f74f5b54326f89f549fb563b1abf2bc Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 28 May 2022 22:01:17 +0800 Subject: [PATCH] =?UTF-8?q?flowable=20=E4=BB=BB=E5=8A=A1=E8=A2=AB=E5=8F=96?= =?UTF-8?q?=E6=B6=88=EF=BC=88=E5=8C=85=E6=8B=AC=E4=B8=BB=E5=8A=A8=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E3=80=81=E4=BC=9A=E7=AD=BE=E5=8F=96=E6=B6=88=EF=BC=89?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E7=BB=9F=E4=B8=80=E8=BF=9B=E8=A1=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=20task=20=E7=8A=B6=E6=80=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/BpmModelFormTypeEnum.java | 2 +- .../definition/BpmTaskAssignRuleTypeEnum.java | 2 +- .../definition/BpmTaskRuleScriptEnum.java | 2 +- .../bpm}/enums/message/BpmMessageEnum.java | 2 +- .../BpmProcessInstanceDeleteReasonEnum.java | 58 ++++ .../task/BpmProcessInstanceResultEnum.java | 48 +++ .../task/BpmProcessInstanceStatusEnum.java | 2 +- .../bpm/convert/task/BpmTaskConvert.java | 4 +- .../definition/BpmProcessDefinitionExtDO.java | 2 +- .../definition/BpmTaskAssignRuleDO.java | 4 +- .../bpm/dal/dataobject/oa/BpmOALeaveDO.java | 2 +- .../task/BpmProcessInstanceExtDO.java | 4 +- .../bpm/dal/dataobject/task/BpmTaskExtDO.java | 2 +- .../bpm/dal/mysql/task/BpmTaskExtMapper.java | 11 +- .../BpmProcessInstanceDeleteReasonEnum.java | 37 --- .../task/BpmProcessInstanceResultEnum.java | 30 -- .../bpm/domain/vo/ApproveProcInstVO.java | 1 + .../behavior/BpmUserTaskActivityBehavior.java | 3 +- .../behavior/script/BpmTaskAssignScript.java | 2 +- .../impl/BpmTaskAssignLeaderX1Script.java | 2 +- .../impl/BpmTaskAssignLeaderX2Script.java | 2 +- .../impl/BpmTaskAssignStartUserScript.java | 2 +- .../core/listener/BpmTaskEventListener.java | 25 ++ .../definition/BpmFormServiceImpl.java | 2 +- .../definition/BpmModelServiceImpl.java | 2 +- .../BpmTaskAssignRuleServiceImpl.java | 4 +- .../dto/BpmModelMetaInfoRespDTO.java | 2 +- .../dto/BpmProcessDefinitionCreateReqDTO.java | 2 +- .../message/BpmMessageServiceImpl.java | 2 +- .../bpm/service/oa/BpmOALeaveServiceImpl.java | 2 +- .../bpm/service/task/BpmActivityService.java | 9 + .../service/task/BpmActivityServiceImpl.java | 7 + .../task/BpmProcessInstanceServiceImpl.java | 310 +----------------- .../bpm/service/task/BpmTaskService.java | 8 + .../bpm/service/task/BpmTaskServiceImpl.java | 87 +++-- .../task/inst/service/HiTaskInstService.java | 2 - .../resources/mapper/BpmTaskExtMapper.xml | 9 - .../BpmTaskAssignRuleServiceImplTest.java | 4 +- 38 files changed, 251 insertions(+), 450 deletions(-) rename yudao-module-bpm/{yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain => yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm}/enums/definition/BpmModelFormTypeEnum.java (87%) rename yudao-module-bpm/{yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain => yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm}/enums/definition/BpmTaskAssignRuleTypeEnum.java (91%) rename yudao-module-bpm/{yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain => yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm}/enums/definition/BpmTaskRuleScriptEnum.java (90%) rename yudao-module-bpm/{yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain => yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm}/enums/message/BpmMessageEnum.java (91%) create mode 100644 yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java create mode 100644 yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java rename yudao-module-bpm/{yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain => yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm}/enums/task/BpmProcessInstanceStatusEnum.java (87%) delete mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceDeleteReasonEnum.java delete mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceResultEnum.java diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmModelFormTypeEnum.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java similarity index 87% rename from yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmModelFormTypeEnum.java rename to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java index 5b4db860f..c21d6f999 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmModelFormTypeEnum.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.bpm.domain.enums.definition; +package cn.iocoder.yudao.module.bpm.enums.definition; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskAssignRuleTypeEnum.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java similarity index 91% rename from yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskAssignRuleTypeEnum.java rename to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java index bfc25ade2..b7ccc7ae8 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskAssignRuleTypeEnum.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.bpm.domain.enums.definition; +package cn.iocoder.yudao.module.bpm.enums.definition; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskRuleScriptEnum.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskRuleScriptEnum.java similarity index 90% rename from yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskRuleScriptEnum.java rename to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskRuleScriptEnum.java index baac75bed..7fc0e3b8b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskRuleScriptEnum.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskRuleScriptEnum.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.bpm.domain.enums.definition; +package cn.iocoder.yudao.module.bpm.enums.definition; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/message/BpmMessageEnum.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/message/BpmMessageEnum.java similarity index 91% rename from yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/message/BpmMessageEnum.java rename to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/message/BpmMessageEnum.java index e6612c8ea..79001fccd 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/message/BpmMessageEnum.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/message/BpmMessageEnum.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.bpm.domain.enums.message; +package cn.iocoder.yudao.module.bpm.enums.message; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java new file mode 100644 index 000000000..4f99d0a3d --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java @@ -0,0 +1,58 @@ +package cn.iocoder.yudao.module.bpm.enums.task; + +import cn.hutool.core.util.StrUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 流程实例的删除原因 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum BpmProcessInstanceDeleteReasonEnum { + + REJECT_TASK("不通过任务,原因:{}"), // 修改文案时,需要注意 isRejectReason 方法 + CANCEL_TASK("主动取消任务,原因:{}"), + + // ========== 流程任务的独有原因 ========== + MULTI_TASK_END("系统自动取消,原因:多任务审批已经满足条件,无需审批该任务"), // 多实例满足 condition 而结束时,其它任务实例任务会被取消,对应的删除原因是 MI_END + + ; + + private final String reason; + + /** + * 格式化理由 + * + * @param args 参数 + * @return 理由 + */ + public String format(Object... args) { + return StrUtil.format(reason, args); + } + + // ========== 逻辑 ========== + + public static boolean isRejectReason(String reason) { + return StrUtil.startWith(reason, "不通过任务,原因:"); + } + + /** + * 将 Flowable 的删除原因,翻译成对应的中文原因 + * + * @param reason 原始原因 + * @return 原因 + */ + public static String translateReason(String reason) { + if (StrUtil.isEmpty(reason)) { + return reason; + } + switch (reason) { + case "MI_END": return MULTI_TASK_END.getReason(); + default: return reason; + } + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java new file mode 100644 index 000000000..3b57554cf --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.bpm.enums.task; + +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 流程实例的结果 + * + * @author jason + */ +@Getter +@AllArgsConstructor +public enum BpmProcessInstanceResultEnum { + + PROCESS(1, "处理中"), + APPROVE(2, "通过"), + REJECT(3, "不通过"), + CANCEL(4, "已取消"), + + // ========== 流程任务独有的状态 ========== + + BACK(5, "退回/驳回"); + + /** + * 结果 + * + * 如果新增时,注意 {@link #isEndResult(Integer)} 是否需要变更 + */ + private final Integer result; + /** + * 描述 + */ + private final String desc; + + /** + * 判断该结果是否已经处于 End 最终结果 + * + * 主要用于一些结果更新的逻辑,如果已经是最终结果,就不再进行更新 + * + * @param result 结果 + * @return 是否 + */ + public static boolean isEndResult(Integer result) { + return ObjectUtils.equalsAny(result, APPROVE.getResult(), REJECT.getResult(), CANCEL.getResult(), BACK.getResult()); + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceStatusEnum.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java similarity index 87% rename from yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceStatusEnum.java rename to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java index 606a38dce..70a31dd34 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceStatusEnum.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.bpm.domain.enums.task; +package cn.iocoder.yudao.module.bpm.enums.task; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java index 603b58188..007ff2609 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java +++ b/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 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; @@ -192,4 +192,4 @@ public interface BpmTaskConvert { tmpMap.forEach((key, var) -> result.add(var)); return result; } -} \ No newline at end of file +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java index a02042f65..57abc0b99 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmModelFormTypeEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java index 57a7e0c40..e65764f1a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java +++ b/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; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java index 167705bc3..31381a556 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.oa; -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import lombok.*; import java.util.*; import com.baomidou.mybatisplus.annotation.*; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java index ea94d0bf1..b37709962 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.task; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum; -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceStatusEnum; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java index b0f62a095..fe71a1b77 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.task; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java index 0280765f5..cd174d902 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java @@ -20,17 +20,14 @@ public interface BpmTaskExtMapper extends BaseMapperX { return selectList(BpmTaskExtDO::getTaskId, taskIds); } + default BpmTaskExtDO selectByTaskId(String taskId) { + return selectOne(BpmTaskExtDO::getTaskId, taskId); + } + default List selectListByProcessInstanceId(String processInstanceId) { return selectList(BpmTaskExtDO::getProcessInstanceId, processInstanceId); } - /** - * 删除非当前相同taskDefKey非进行中的任务 - * - * @param entity 任务信息 - */ - void delTaskByProcInstIdAndTaskIdAndTaskDefKey(@Param("entity") BpmTaskExtDO entity); - /** * 任务驳回 * diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceDeleteReasonEnum.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceDeleteReasonEnum.java deleted file mode 100644 index 8ee48993c..000000000 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceDeleteReasonEnum.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.bpm.domain.enums.task; - -import cn.hutool.core.util.StrUtil; -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 流程实例的删除原因 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum BpmProcessInstanceDeleteReasonEnum { - - REJECT_TASK("不通过任务,原因:{}"), // 修改文案时,需要注意 isRejectReason 方法 - CANCEL_TASK("主动取消任务,原因:{}"); - - private final String reason; - - /** - * 格式化理由 - * - * @param args 参数 - * @return 理由 - */ - public String format(Object... args) { - return StrUtil.format(reason, args); - } - - // ========== 逻辑 ========== - - public static boolean isRejectReason(String reason) { - return StrUtil.startWith(reason, "不通过任务,原因:"); - } - -} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceResultEnum.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceResultEnum.java deleted file mode 100644 index 3383d7b9b..000000000 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/task/BpmProcessInstanceResultEnum.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.bpm.domain.enums.task; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 流程实例的结果 - * - * @author jason - */ -@Getter -@AllArgsConstructor -public enum BpmProcessInstanceResultEnum { - - PROCESS(1, "处理中"), - APPROVE(2, "通过"), - REJECT(3, "不通过"), - CANCEL(4, "已取消"), - BACK(5, "退回/驳回"); - - /** - * 结果 - */ - private final Integer result; - /** - * 描述 - */ - private final String desc; - -} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/vo/ApproveProcInstVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/vo/ApproveProcInstVO.java index 3e030f263..2fb56a9eb 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/vo/ApproveProcInstVO.java +++ b/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; @Data @AllArgsConstructor @NoArgsConstructor +// TODO @ke:这个类是不是没用呀 public class ApproveProcInstVO { @ApiModelProperty("任务id") diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java index 5ec47d785..aeda4d52c 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java +++ b/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 { Set candidateUserIds = bpmTaskRuleService.calculateTaskCandidateUsers(execution); // 第二步,后随机选择一个任务的处理人 // 疑问:为什么一定要选择一个任务处理人? - // 解答:项目对 bpm 的任务是责任到人,所以每个任务有且仅有一个处理人。如果希望一个任务可以同时被多个人处理,可以考虑使用 BpmParallelMultiInstanceBehavior 实现的会签 or 或签。 + // 解答:项目对 bpm 的任务是责任到人,所以每个任务有且仅有一个处理人。 + // 如果希望一个任务可以同时被多个人处理,可以考虑使用 BpmParallelMultiInstanceBehavior 实现的会签 or 或签。 int index = RandomUtil.randomInt(candidateUserIds.size()); return CollUtil.get(candidateUserIds, index); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java index 8a78e8012..cdbb0861c 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import org.flowable.engine.delegate.DelegateExecution; import java.util.Set; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java index 81fd27cdd..af7d8b5a7 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import org.flowable.engine.delegate.DelegateExecution; import org.springframework.stereotype.Component; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java index ca7faddf0..068ab3d2f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import org.flowable.engine.delegate.DelegateExecution; import org.springframework.stereotype.Component; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java index 4212dac69..1363f3979 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java +++ b/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 import cn.iocoder.yudao.framework.common.util.collection.SetUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import org.flowable.engine.delegate.DelegateExecution; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java index f9c9cb769..332f7fdcc 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java @@ -1,11 +1,16 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; +import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService; import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; import com.google.common.collect.ImmutableSet; +import lombok.extern.slf4j.Slf4j; 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.FlowableActivityCancelledEvent; +import org.flowable.engine.history.HistoricActivityInstance; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @@ -19,16 +24,22 @@ import java.util.Set; * @author jason */ @Component +@Slf4j public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; + @Resource + @Lazy // 解决循环依赖 + private BpmActivityService activityService; + public static final Set TASK_EVENTS = ImmutableSet.builder() .add(FlowableEngineEventType.TASK_CREATED) .add(FlowableEngineEventType.TASK_ASSIGNED) .add(FlowableEngineEventType.TASK_COMPLETED) + .add(FlowableEngineEventType.ACTIVITY_CANCELLED) .build(); public BpmTaskEventListener(){ @@ -49,4 +60,18 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { protected void taskAssigned(FlowableEngineEntityEvent event) { taskService.updateTaskExtAssign((Task)event.getEntity()); } + + @Override + protected void activityCancelled(FlowableActivityCancelledEvent event) { + HistoricActivityInstance activity = activityService.getHistoricActivityByExecutionId(event.getExecutionId()); + if (activity == null) { + log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]", event.getExecutionId()); + return; + } + if (StrUtil.isEmpty(activity.getTaskId())) { + return; + } + taskService.updateTaskExtCancel(activity.getTaskId()); + } + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java index 85f53960d..d64684b82 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java +++ b/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; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmFormMapper; import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmModelFormTypeEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmFormFieldRespDTO; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java index 5a1b435c9..dcb0b9e47 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java +++ b/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; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmModelFormTypeEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import lombok.extern.slf4j.Slf4j; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index 83087212c..49bfdac4e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/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; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -274,7 +274,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { // 移除被禁用的用户 removeDisableUsers(assigneeUserIds); - // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人 + // 如果候选人为空,抛出异常 if (CollUtil.isEmpty(assigneeUserIds)) { log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", execution.getId(), execution.getProcessDefinitionId(), execution.getCurrentActivityId(), toJsonString(rule)); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java index 73ba89d12..3a36b0eeb 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.bpm.service.definition.dto; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmModelFormTypeEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; import lombok.Data; /** diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java index 507ec3fb5..8b2d22ad5 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java +++ b/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; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmModelFormTypeEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; import lombok.Data; import javax.validation.constraints.AssertTrue; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java index 17b0d7414..89dfd1227 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java +++ b/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; import cn.iocoder.yudao.framework.web.config.WebProperties; import cn.iocoder.yudao.module.bpm.convert.message.BpmMessageConvert; -import cn.iocoder.yudao.module.bpm.domain.enums.message.BpmMessageEnum; +import cn.iocoder.yudao.module.bpm.enums.message.BpmMessageEnum; import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO; import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO; import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java index c782bbc07..d0aadd95e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java +++ b/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; import cn.iocoder.yudao.module.bpm.convert.oa.BpmOALeaveConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO; import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOALeaveMapper; -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java index 20d71ec24..716271526 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.bpm.service.task; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; +import org.flowable.engine.history.HistoricActivityInstance; import java.util.List; @@ -19,4 +20,12 @@ public interface BpmActivityService { */ List getActivityListByProcessInstanceId(String processInstanceId); + /** + * 获得执行编号对应的活动实例 + * + * @param executionId 执行编号 + * @return 活动实例 + */ + HistoricActivityInstance getHistoricActivityByExecutionId(String executionId); + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java index bb9f0abb8..9c5f86982 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java +++ b/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; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; +import org.flowable.engine.history.HistoricActivityInstance; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -38,4 +39,10 @@ public class BpmActivityServiceImpl implements BpmActivityService { List bpmActivityDOList = bpmActivityMapper.listAllByProcInstIdAndDelete(procInstId); return BpmActivityConvert.INSTANCE.convertList(bpmActivityDOList); } + + @Override + public HistoricActivityInstance getHistoricActivityByExecutionId(String executionId) { + return historyService.createHistoricActivityInstanceQuery().executionId(executionId).singleResult(); + } + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index d1fe10e9e..f5738ed7d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -1,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.domain.enums.task.BpmProcessInstanceDeleteReasonEnum; -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum; -import cn.iocoder.yudao.module.bpm.domain.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. https://blog.csdn.net/bobozai86/article/details/105210414 - * - * HistoricProcessInstance & ProcessInstance 的关系: - * 1.https://my.oschina.net/843294669/blog/719024 - * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 - * - * @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 getProcessInstances(Set ids) { - return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); - } - - @Override - public PageResult getMyProcessInstancePage(Long userId, - BpmProcessInstanceMyPageReqVO pageReqVO) { - // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 - PageResult pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); - if (CollUtil.isEmpty(pageResult.getList())) { - return new PageResult<>(pageResult.getTotal()); - } - - // 获得流程 Task Map - List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); - Map> 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 getHistoricProcessInstances(Set 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 不通过。如果是,则不进行更新 - 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 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); - - } -} +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. * * HistoricProcessInstance & ProcessInstance 的关系: * 1. * * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 * * @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 getProcessInstances(Set ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> 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 getHistoricProcessInstances(Set 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 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); } } \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index a3dbbd9ea..6c9048e6f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/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; * @author 芋道源码 */ public interface BpmTaskService { + /** * 获得待办的流程任务分页 * @@ -120,6 +121,13 @@ public interface BpmTaskService { */ void updateTaskExtComplete(Task task); + /** + * 更新 Task 拓展记录为已取消 + * + * @param taskId 任务的编号 + */ + void updateTaskExtCancel(String taskId); + /** * 更新 Task 拓展记录,并发送通知 * diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index d9a48a39a..ef94eac90 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/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; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; -import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.business.hi.task.inst.service.HiTaskInstService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -214,14 +215,6 @@ public class BpmTaskServiceImpl implements BpmTaskService { List bpmTaskAssignRuleList = taskAssignRuleMapper.selectListByProcessDefinitionId(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); - if (CollUtil.isNotEmpty(bpmTaskAssignRuleList) && bpmTaskAssignRuleList.size() > 0) { - // edit by 芋艿 TODO -// if (BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType().equals(bpmTaskAssignRuleList.get(0).getType())) { -// taskExtMapper.delTaskByProcInstIdAndTaskIdAndTaskDefKey( -// new BpmTaskExtDO().setTaskId(task.getId()).setTaskDefKey(task.getTaskDefinitionKey()) -// .setProcessInstanceId(task.getProcessInstanceId())); -// } - } } @Override @@ -292,6 +285,23 @@ public class BpmTaskServiceImpl implements BpmTaskService { taskService.setAssignee(id, String.valueOf(userId)); } + /** + * 校验任务是否存在, 并且是否是分配给自己的任务 + * + * @param userId 用户 id + * @param taskId task id + */ + private Task checkTask(Long userId, String taskId) { + Task task = getTask(taskId); + if (task == null) { + throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS); + } + if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) { + throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF); + } + return task; + } + @Override public void createTaskExt(Task task) { BpmTaskExtDO taskExtDO = @@ -301,10 +311,45 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override public void updateTaskExtComplete(Task task) { - BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task).setEndTime(new Date()); + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task) + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()) // 不设置也问题不大,因为 Complete 一般是审核通过,已经设置 + .setEndTime(new Date()); taskExtMapper.updateByTaskId(taskExtDO); } + @Override + public void updateTaskExtCancel(String taskId) { + // 需要在事务提交后,才进行查询。不然查询不到历史的原因 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + + @Override + public void afterCommit() { + // 可能只是活动,不是任务,所以查询不到 + HistoricTaskInstance task = getHistoricTask(taskId); + if (task == null) { + return; + } + + // 如果任务拓展表已经是完成的状态,则跳过 + BpmTaskExtDO taskExt = taskExtMapper.selectByTaskId(taskId); + if (taskExt == null) { + log.error("[updateTaskExtCancel][taskId({}) 查找不到对应的记录,可能存在问题]", taskId); + return; + } + // 如果已经是最终的结果,则跳过 + if (BpmProcessInstanceResultEnum.isEndResult(taskExt.getResult())) { + log.error("[updateTaskExtCancel][taskId({}) 处于结果({}),无需进行更新]", taskId, taskExt.getResult()); + return; + } + + // 更新任务 + taskExtMapper.updateById(new BpmTaskExtDO().setId(taskExt.getId()).setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()) + .setEndTime(new Date()).setReason(BpmProcessInstanceDeleteReasonEnum.translateReason(task.getDeleteReason()))); + } + + }); + } + @Override public void updateTaskExtAssign(Task task) { BpmTaskExtDO taskExtDO = @@ -323,24 +368,12 @@ public class BpmTaskServiceImpl implements BpmTaskService { }); } - /** - * 校验任务是否存在, 并且是否是分配给自己的任务 - * - * @param userId 用户 id - * @param taskId task id - */ - private Task checkTask(Long userId, String taskId) { - Task task = getTask(taskId); - if (task == null) { - throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS); - } - if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) { - throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF); - } - return task; - } - private Task getTask(String id) { return taskService.createTaskQuery().taskId(id).singleResult(); } + + private HistoricTaskInstance getHistoricTask(String id) { + return historyService.createHistoricTaskInstanceQuery().taskId(id).singleResult(); + } + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/service/HiTaskInstService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/service/HiTaskInstService.java index 974b19f31..5e24819c7 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/service/HiTaskInstService.java +++ b/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; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO; @@ -68,7 +67,6 @@ public class HiTaskInstService { * @return 返回流程信息 */ @TenantIgnore - @DataPermission(enable = false) // TODO 芋艿:先临时去掉 public List taskGetComment(List taskList, Object approved) { BpmTaskExtDO task = taskList.get(taskList.size() - 1); Map bpmTaskMap = diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmTaskExtMapper.xml b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmTaskExtMapper.xml index 3bb6b0cad..934a358f5 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmTaskExtMapper.xml +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmTaskExtMapper.xml @@ -2,14 +2,6 @@ - - - UPDATE bpm_task_ext - SET deleted=1 - WHERE process_instance_id = #{entity.processInstanceId} - AND task_def_key = #{entity.taskDefKey} - AND task_id != #{entity.taskId} - UPDATE bpm_task_ext SET result=2, @@ -26,5 +18,4 @@ - diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImplTest.java b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImplTest.java index 8b644bffe..2edec75d7 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImplTest.java +++ b/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; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskRuleScriptEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;