diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index 315ec6d71..f5bd01365 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -14,21 +14,21 @@
https://github.com/YunaiV/ruoyi-vue-pro
- 1.6.2-snapshot
+ 1.6.5-snapshot
2.7.6
2021.0.5
2021.0.4.0
3.0.3
- 1.6.7
+ 1.6.8
2.5
- 1.2.14
+ 1.2.15
3.5.2
3.5.2
3.5.2
- 3.17.7
+ 3.18.0
2.7.15
@@ -40,7 +40,7 @@
1.7.1
8.12.0
- 2.6.9
+ 2.7.7
0.33.0
7.2.9.RELEASE
@@ -51,12 +51,12 @@
1.18.24
1.5.3.Final
- 5.8.9
- 3.1.2
+ 5.8.10
+ 3.1.3
2.3
1.0.5
1.2.83
- 30.1.1-jre
+ 31.1-jre
5.1.0
2.14.0
3.8.0
@@ -65,7 +65,9 @@
1.3.0
4.1.82.Final
- 8.2.2
+ 3.0.0
+ 4.10.0
+ 8.4.6
4.6.2
2.2.1
3.1.635
@@ -430,7 +432,7 @@
org.flowable
- flowable-spring-boot-starter-basic
+ flowable-spring-boot-starter-process
${flowable.version}
@@ -563,6 +565,16 @@
+
+ com.squareup.okio
+ okio
+ ${okio.version}
+
+
+ com.squareup.okhttp3
+ okhttp
+ ${okhttp3.version}
+
cn.iocoder.cloud
yudao-spring-boot-starter-file
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
index dbb521fa0..a9b01f28e 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
@@ -63,7 +63,7 @@
com.github.binarywang
weixin-java-pay
- 4.3.8.B
+ 4.4.0
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java
index b3b6ea1bf..1d762c35e 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java
@@ -45,6 +45,7 @@ public class YudaoAuthRequestFactory extends AuthRequestFactory {
* @param source {@link AuthSource}
* @return {@link AuthRequest}
*/
+ @Override
public AuthRequest get(String source) {
// 先尝试获取自定义扩展的
AuthRequest authRequest = getExtendRequest(source);
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-weixin/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-weixin/pom.xml
index 09c414d02..d58e9104d 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-weixin/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-biz-weixin/pom.xml
@@ -35,7 +35,7 @@
com.github.binarywang
wx-java-mp-spring-boot-starter
- 4.3.8.B
+ 4.4.0
diff --git a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/context/EnvContextHolder.java b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/context/EnvContextHolder.java
index a246a781f..a8eafc650 100644
--- a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/context/EnvContextHolder.java
+++ b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/context/EnvContextHolder.java
@@ -18,18 +18,18 @@ public class EnvContextHolder {
*
* 使用 {@link List} 的原因,可能存在多层设置或者清理
*/
- private static final ThreadLocal> tagContext = TransmittableThreadLocal.withInitial(ArrayList::new);
+ private static final ThreadLocal> TAG_CONTEXT = TransmittableThreadLocal.withInitial(ArrayList::new);
public static void setTag(String tag) {
- tagContext.get().add(tag);
+ TAG_CONTEXT.get().add(tag);
}
public static String getTag() {
- return CollUtil.getLast(tagContext.get());
+ return CollUtil.getLast(TAG_CONTEXT.get());
}
public static void removeTag() {
- List tags = tagContext.get();
+ List tags = TAG_CONTEXT.get();
if (CollUtil.isEmpty(tags)) {
return;
}
diff --git a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java
index 5c61f312c..a67e66d70 100644
--- a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java
+++ b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java
@@ -86,7 +86,7 @@ public class SwaggerProvider implements SwaggerResourcesProvider {
*/
private String getRoutePath(RouteDefinition route) {
PredicateDefinition pathDefinition = CollUtil.findOne(route.getPredicates(),
- predicateDefinition -> predicateDefinition.getName().equals("Path"));
+ predicateDefinition -> "Path".equals(predicateDefinition.getName()));
if (pathDefinition == null) {
log.info("[get][Route({}) 没有 Path 条件,忽略接口文档]", route.getId());
return null;
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 a7468ac4f..68075b3d5 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 +1,302 @@
-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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.LocalDateTime;
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.*;
/**
* 流程实例 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())).getCheckedData();
DeptRespDTO dept = null;
if (startUser != null) {
dept = deptApi.getDept(startUser.getDeptId()).getCheckedData();
}
// 拼接结果
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(LocalDateTime.now()) // 由于 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(LocalDateTime.now()) // 由于 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());
// 补全流程实例的拓展表
processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId())
.setFormVariables(variables));
return instance.getId();
}
}
\ No newline at end of file
+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.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.time.LocalDateTime;
+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.*;
+
+/**
+ * 流程实例 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())).getCheckedData();
+ DeptRespDTO dept = null;
+ if (startUser != null) {
+ dept = deptApi.getDept(startUser.getDeptId()).getCheckedData();
+ }
+
+ // 拼接结果
+ 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(LocalDateTime.now()) // 由于 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(LocalDateTime.now()) // 由于 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()));
+ }
+
+ @Override
+ @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());
+
+ // 补全流程实例的拓展表
+ processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId())
+ .setFormVariables(variables));
+ return instance.getId();
+ }
+
+}
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/mq/message/file/FileConfigRefreshMessage.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/mq/message/file/FileConfigRefreshMessage.java
index 9e2336e30..db45856a3 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/mq/message/file/FileConfigRefreshMessage.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/mq/message/file/FileConfigRefreshMessage.java
@@ -13,7 +13,7 @@ public class FileConfigRefreshMessage extends RemoteApplicationEvent {
}
public FileConfigRefreshMessage(Object source, String originService, String destinationService) {
- super(source, originService, destinationService);
+ super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java
index 7ca9c3588..79046e984 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java
@@ -30,6 +30,7 @@ public class CaptchaController extends com.anji.captcha.controller.CaptchaContro
@ApiOperation("获得验证码")
@PermitAll
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
+ @Override
public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) {
return super.get(data, request);
}
@@ -38,6 +39,7 @@ public class CaptchaController extends com.anji.captcha.controller.CaptchaContro
@ApiOperation("校验验证码")
@PermitAll
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
+ @Override
public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) {
return super.check(data, request);
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/auth/OAuth2ClientRefreshMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/auth/OAuth2ClientRefreshMessage.java
index 0285664b1..c0f858d9b 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/auth/OAuth2ClientRefreshMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/auth/OAuth2ClientRefreshMessage.java
@@ -17,7 +17,7 @@ public class OAuth2ClientRefreshMessage extends RemoteApplicationEvent {
}
public OAuth2ClientRefreshMessage(Object source, String originService, String destinationService) {
- super(source, originService, destinationService);
+ super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/dept/DeptRefreshMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/dept/DeptRefreshMessage.java
index b94e6b81f..5c6ab596f 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/dept/DeptRefreshMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/dept/DeptRefreshMessage.java
@@ -17,7 +17,7 @@ public class DeptRefreshMessage extends RemoteApplicationEvent {
}
public DeptRefreshMessage(Object source, String originService, String destinationService) {
- super(source, originService, destinationService);
+ super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/MenuRefreshMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/MenuRefreshMessage.java
index e03e26f08..c569107d9 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/MenuRefreshMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/MenuRefreshMessage.java
@@ -13,7 +13,7 @@ public class MenuRefreshMessage extends RemoteApplicationEvent {
}
public MenuRefreshMessage(Object source, String originService, String destinationService) {
- super(source, originService, destinationService);
+ super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/RoleMenuRefreshMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/RoleMenuRefreshMessage.java
index d2756c2cf..7b073b407 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/RoleMenuRefreshMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/RoleMenuRefreshMessage.java
@@ -15,7 +15,7 @@ public class RoleMenuRefreshMessage extends RemoteApplicationEvent {
}
public RoleMenuRefreshMessage(Object source, String originService, String destinationService) {
- super(source, originService, destinationService);
+ super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/RoleRefreshMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/RoleRefreshMessage.java
index 8078cab47..fee07b6c0 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/RoleRefreshMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/RoleRefreshMessage.java
@@ -15,7 +15,7 @@ public class RoleRefreshMessage extends RemoteApplicationEvent {
}
public RoleRefreshMessage(Object source, String originService, String destinationService) {
- super(source, originService, destinationService);
+ super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/UserRoleRefreshMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/UserRoleRefreshMessage.java
index a675d5187..bb94c8369 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/UserRoleRefreshMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/UserRoleRefreshMessage.java
@@ -15,7 +15,7 @@ public class UserRoleRefreshMessage extends RemoteApplicationEvent {
}
public UserRoleRefreshMessage(Object source, String originService, String destinationService) {
- super(source, originService, destinationService);
+ super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sensitiveword/SensitiveWordRefreshMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sensitiveword/SensitiveWordRefreshMessage.java
index 3dcb3fb7d..d34aac2a8 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sensitiveword/SensitiveWordRefreshMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sensitiveword/SensitiveWordRefreshMessage.java
@@ -15,7 +15,7 @@ public class SensitiveWordRefreshMessage extends RemoteApplicationEvent {
}
public SensitiveWordRefreshMessage(Object source, String originService, String destinationService) {
- super(source, originService, destinationService);
+ super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsChannelRefreshMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsChannelRefreshMessage.java
index 11b18aac5..2dc2983e7 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsChannelRefreshMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsChannelRefreshMessage.java
@@ -17,7 +17,7 @@ public class SmsChannelRefreshMessage extends RemoteApplicationEvent {
}
public SmsChannelRefreshMessage(Object source, String originService, String destinationService) {
- super(source, originService, destinationService);
+ super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsTemplateRefreshMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsTemplateRefreshMessage.java
index edcc44214..b1ae750d9 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsTemplateRefreshMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsTemplateRefreshMessage.java
@@ -17,7 +17,7 @@ public class SmsTemplateRefreshMessage extends RemoteApplicationEvent {
}
public SmsTemplateRefreshMessage(Object source, String originService, String destinationService) {
- super(source, originService, destinationService);
+ super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
}
}