From 9c452ee612d5e276c3e76d33b03a716297599a23 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Tue, 8 Feb 2022 22:30:25 +0800 Subject: [PATCH 01/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E6=A8=A1=E5=9E=8B=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/BpmModelCommonService.java | 22 +++++ .../service/definition/BpmModelService.java | 10 +-- .../yudao-module-bpm-impl-flowable/pom.xml | 5 ++ .../yudao/module/bpm/api/package-info.java | 4 + .../task/FlowableProcessInstanceApiImpl.java | 24 ++++++ .../definition/FlowableModelController.java | 33 +++++++ .../bpm/controller/app/package-info.java | 4 + .../module/bpm/controller/package-info.java | 6 ++ .../bpm/convert/definition/ModelConvert.java | 85 +++++++++++++++++++ .../module/bpm/convert/package-info.java | 6 ++ ...道 Spring Boot 对象转换 MapStruct 入门》.md | 1 + .../yudao/module/bpm/package-info.java | 12 +++ .../definition/FlowableModelService.java | 10 +++ .../definition/FlowableModelServiceImpl.java | 83 ++++++++++++++++++ .../FlowableProcessDefinitionService.java | 52 ++++++++++++ .../FlowableProcessDefinitionServiceImpl.java | 62 ++++++++++++++ .../definition/dto/ModelMetaInfoRespDTO.java | 39 +++++++++ 17 files changed, 449 insertions(+), 9 deletions(-) create mode 100644 yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/FlowableProcessInstanceApiImpl.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/ModelMetaInfoRespDTO.java diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java new file mode 100644 index 000000000..f0e77d5c2 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageReqVO; + +/** + * 流程模型通用接口 + * Activiti 和 flowable 通用的流程模型接口 + * + * @author yunlongn + * @author jason + */ +public interface BpmModelCommonService { + /** + * 获得流程模型分页 + * + * @param pageVO 分页查询 + * @return 流程模型分页 + */ + PageResult getModelPage(BpmModelPageReqVO pageVO); +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java index ec2d6a0c9..11204819b 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java @@ -11,15 +11,7 @@ import javax.validation.Valid; * * @author yunlongn */ -public interface BpmModelService { - - /** - * 获得流程模型分页 - * - * @param pageVO 分页查询 - * @return 流程模型分页 - */ - PageResult getModelPage(BpmModelPageReqVO pageVO); +public interface BpmModelService extends BpmModelCommonService { /** * 获得流程模块 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml b/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml index ec16d5275..09822771d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml @@ -16,6 +16,11 @@ + + cn.iocoder.boot + yudao-module-bpm-base + ${revision} + org.flowable diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java new file mode 100644 index 000000000..2137e2203 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java @@ -0,0 +1,4 @@ +/** + * bpm API 实现类,定义暴露给其它模块的 API + */ +package cn.iocoder.yudao.module.bpm.api; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/FlowableProcessInstanceApiImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/FlowableProcessInstanceApiImpl.java new file mode 100644 index 000000000..0f455ed99 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/FlowableProcessInstanceApiImpl.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.bpm.api.task; + +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import javax.validation.Valid; +/** + * Flowable 流程实例 Api 实现类 + * + * @author 芋道源码 + * @author jason + */ +@Service +@Validated +public class FlowableProcessInstanceApiImpl implements BpmProcessInstanceApi { + + @Override + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO reqDTO) { + //TODO + return null; + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java new file mode 100644 index 000000000..9d2f911bd --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.definition; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageReqVO; +import cn.iocoder.yudao.module.bpm.service.definition.FlowableModelService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Api(tags = "管理后台 - 流程模型") +@RestController +@RequestMapping("/bpm/model") +@Validated +public class FlowableModelController { + + @Resource + private FlowableModelService modelService; + + @GetMapping("/page") + @ApiOperation(value = "获得模型分页") + public CommonResult> getModelPage(BpmModelPageReqVO pageVO) { + return success(modelService.getModelPage(pageVO)); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java new file mode 100644 index 000000000..e8d285e35 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位 + */ +package cn.iocoder.yudao.module.bpm.controller.app; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java new file mode 100644 index 000000000..d1930bd6a --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java @@ -0,0 +1,6 @@ +/** + * 提供 RESTful API 给前端: + * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目 + * 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分 + */ +package cn.iocoder.yudao.module.bpm.controller; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java new file mode 100644 index 000000000..56587c046 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java @@ -0,0 +1,85 @@ +package cn.iocoder.yudao.module.bpm.convert.definition; + +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelBaseVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelRespVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; +import cn.iocoder.yudao.module.bpm.service.definition.dto.ModelMetaInfoRespDTO; +import org.flowable.common.engine.impl.db.SuspensionState; +import org.flowable.engine.repository.Deployment; +import org.flowable.engine.repository.Model; +import org.flowable.engine.repository.ProcessDefinition; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +import java.util.List; +import java.util.Map; + +/** + * 流程模型 Convert + * + * @author yunlongn + */ +@Mapper +public interface ModelConvert { + + ModelConvert INSTANCE = Mappers.getMapper(ModelConvert.class); + + default List convertList(List list, Map formMap, + Map deploymentMap, + Map processDefinitionMap) { + return CollectionUtils.convertList(list, model -> { + ModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), ModelMetaInfoRespDTO.class); + BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null; + Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null; + ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null; + return convert(model, form, deployment, processDefinition); + }); + } + + default BpmModelPageItemRespVO convert(Model model, BpmFormDO form, Deployment deployment, ProcessDefinition processDefinition) { + BpmModelPageItemRespVO modelRespVO = new BpmModelPageItemRespVO(); + modelRespVO.setId(model.getId()); + modelRespVO.setCreateTime(model.getCreateTime()); + // 通用 copy + copyTo(model, modelRespVO); + // Form + if (form != null) { + modelRespVO.setFormId(form.getId()); + modelRespVO.setFormName(form.getName()); + } + // ProcessDefinition + modelRespVO.setProcessDefinition(this.convert(processDefinition)); + if (modelRespVO.getProcessDefinition() != null) { + modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ? + SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode()); + modelRespVO.getProcessDefinition().setDeploymentTime(deployment.getDeploymentTime()); + } + return modelRespVO; + } + + default BpmModelRespVO convert(Model model) { + BpmModelRespVO modelRespVO = new BpmModelRespVO(); + modelRespVO.setId(model.getId()); + modelRespVO.setCreateTime(model.getCreateTime()); + // 通用 copy + copyTo(model, modelRespVO); + return modelRespVO; + } + + default void copyTo(Model model, BpmModelBaseVO to) { + to.setName(model.getName()); + to.setKey(model.getKey()); + to.setCategory(model.getCategory()); + // metaInfo + ModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), ModelMetaInfoRespDTO.class); + copyTo(metaInfo, to); + } + + void copyTo(ModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to); + + BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean); +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java new file mode 100644 index 000000000..6db6ebc46 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java @@ -0,0 +1,6 @@ +/** + * 提供 POJO 类的实体转换 + * + * 目前使用 MapStruct 框架 + */ +package cn.iocoder.yudao.module.bpm.convert; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md new file mode 100644 index 000000000..8153487b7 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md @@ -0,0 +1 @@ + diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java new file mode 100644 index 000000000..5713e495c --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java @@ -0,0 +1,12 @@ +/** + * bpm 包下,业务流程管理(Business Process Management),我们放工作流的功能,基于 activiti 7 版本实现。 + * 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等 + * + * bpm 解释:https://baike.baidu.com/item/BPM/1933 + * + * 1. Controller URL:以 /bpm/ 开头,避免和其它 Module 冲突 + * 2. DataObject 表名:以 bpm_ 开头,方便在数据库中区分 + * + * 注意,由于 Bpm 模块下,容易和其它模块重名,所以类名都加载 Pay 的前缀~ + */ +package cn.iocoder.yudao.module.bpm; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelService.java new file mode 100644 index 000000000..bbc304d33 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelService.java @@ -0,0 +1,10 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +/** + * Flowable流程模型接口 + * + * @author yunlongn + */ +public interface FlowableModelService extends BpmModelCommonService { + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java new file mode 100644 index 000000000..db7f3d54e --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java @@ -0,0 +1,83 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.common.util.object.PageUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageReqVO; +import cn.iocoder.yudao.module.bpm.convert.definition.ModelConvert; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; +import cn.iocoder.yudao.module.bpm.service.definition.dto.ModelMetaInfoRespDTO; +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.repository.Deployment; +import org.flowable.engine.repository.Model; +import org.flowable.engine.repository.ModelQuery; +import org.flowable.engine.repository.ProcessDefinition; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +/** + * Flowable流程模型实现 + * 主要进行 Flowable {@link Model} 的维护 + * + * @author yunlongn + * @author 芋道源码 + */ +@Service +@Validated +@Slf4j +public class FlowableModelServiceImpl implements FlowableModelService { + + @Resource + private RepositoryService repositoryService; + @Resource + private BpmFormService bpmFormService; + @Resource + private FlowableProcessDefinitionService processDefinitionService; + + @Override + public PageResult getModelPage(BpmModelPageReqVO pageVO) { + ModelQuery modelQuery = repositoryService.createModelQuery(); + if (StrUtil.isNotBlank(pageVO.getKey())) { + modelQuery.modelKey(pageVO.getKey()); + } + if (StrUtil.isNotBlank(pageVO.getName())) { + modelQuery.modelNameLike("%" + pageVO.getName() + "%"); // 模糊匹配 + } + if (StrUtil.isNotBlank(pageVO.getCategory())) { + modelQuery.modelCategory(pageVO.getCategory()); + } + // 执行查询 + List models = modelQuery.orderByCreateTime().desc() + .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); + + // 获得 Form Map + Set formIds = CollectionUtils.convertSet(models, model -> { + ModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), ModelMetaInfoRespDTO.class); + return metaInfo != null ? metaInfo.getFormId() : null; + }); + Map formMap = bpmFormService.getFormMap(formIds); + + // 获得 Deployment Map + Set deploymentIds = new HashSet<>(); + models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId())); + Map deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds); + // 获得 ProcessDefinition Map + List processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds); + Map processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId); + + // 拼接结果 + long modelCount = modelQuery.count(); + return new PageResult<>(ModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java new file mode 100644 index 000000000..c6693f364 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import org.flowable.engine.repository.Deployment; +import org.flowable.engine.repository.ProcessDefinition; + +import java.util.List; +import java.util.Map; +import java.util.Set; +/** + * Flowable流程定义接口 + * + * @author yunlong.li + * @author ZJQ + * @author 芋道源码 + */ +public interface FlowableProcessDefinitionService { + + /** + * 获得 deploymentIds 对应的 ProcessDefinition 数组 + * + * @param deploymentIds 部署编号的数组 + * @return 流程定义的数组 + */ + List getProcessDefinitionListByDeploymentIds(Set deploymentIds); + + /** + * 获得 ids 对应的 Deployment Map + * + * @param ids 部署编号的数组 + * @return 流程部署 Map + */ + default Map getDeploymentMap(Set ids) { + return CollectionUtils.convertMap(getDeployments(ids), Deployment::getId); + } + + /** + * 获得 ids 对应的 Deployment 数组 + * + * @param ids 部署编号的数组 + * @return 流程部署的数组 + */ + List getDeployments(Set ids); + + /** + * 获得 id 对应的 Deployment + * + * @param id 部署编号 + * @return 流程部署 + */ + Deployment getDeployment(String id); +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java new file mode 100644 index 000000000..7bcf72327 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.repository.Deployment; +import org.flowable.engine.repository.ProcessDefinition; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.addIfNotNull; +import static java.util.Collections.emptyList; + +/** + * 流程定义实现 + * 主要进行 Flowable {@link ProcessDefinition} 和 {@link Deployment} 的维护 + * + * @author yunlongn + * @author ZJQ + * @author 芋道源码 + */ +@Service +@Validated +@Slf4j +public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefinitionService { + @Resource + private RepositoryService repositoryService; + + @Override + public List getProcessDefinitionListByDeploymentIds(Set deploymentIds) { + if (CollUtil.isEmpty(deploymentIds)) { + return emptyList(); + } + return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list(); + } + + @Override + public List getDeployments(Set ids) { + if (CollUtil.isEmpty(ids)) { + return emptyList(); + } + List list = new ArrayList<>(ids.size()); + for (String id : ids) { + addIfNotNull(list, getDeployment(id)); + } + return list; + } + + @Override + public Deployment getDeployment(String id) { + if (StrUtil.isEmpty(id)) { + return null; + } + return repositoryService.createDeploymentQuery().deploymentId(id).singleResult(); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/ModelMetaInfoRespDTO.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/ModelMetaInfoRespDTO.java new file mode 100644 index 000000000..ee725054c --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/ModelMetaInfoRespDTO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.bpm.service.definition.dto; + +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; +import lombok.Data; + +/** + * BPM 流程 MetaInfo Response DTO + * 主要用于 {@link org.flowable.engine.repository.Model#setMetaInfo(String)} 的存储 + * + * @author 芋道源码 + */ +@Data +public class ModelMetaInfoRespDTO { + + /** + * 流程描述 + */ + private String description; + /** + * 表单类型 + */ + private Integer formType; + /** + * 表单编号 + * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 + */ + private Long formId; + /** + * 自定义表单的提交路径,使用 Vue 的路由地址 + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 + */ + private String formCustomCreatePath; + /** + * 自定义表单的查看路径,使用 Vue 的路由地址 + * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 + */ + private String formCustomViewPath; + +} From a207412e8cdabe8a04eb517896f484d12d07adef Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Tue, 8 Feb 2022 23:42:03 +0800 Subject: [PATCH 02/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E6=A8=A1=E5=9E=8B=E6=8E=A5=E5=8F=A3=20?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/BpmModelCommonService.java | 29 ++++++- .../service/definition/BpmModelService.java | 23 ------ .../definition/FlowableModelController.java | 47 ++++++++++-- .../bpm/convert/definition/ModelConvert.java | 40 +++++++++- .../definition/FlowableModelServiceImpl.java | 76 ++++++++++++++++++- 5 files changed, 180 insertions(+), 35 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java index f0e77d5c2..5ffe3ce0b 100644 --- a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java @@ -1,8 +1,9 @@ package cn.iocoder.yudao.module.bpm.service.definition; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageItemRespVO; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; + +import javax.validation.Valid; /** * 流程模型通用接口 @@ -19,4 +20,28 @@ public interface BpmModelCommonService { * @return 流程模型分页 */ PageResult getModelPage(BpmModelPageReqVO pageVO); + + /** + * 创建流程模型 + * + * @param modelVO 创建信息 + * @param bpmnXml BPMN XML + * @return 创建的流程模型的编号 + */ + String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml); + + /** + * 获得流程模块 + * + * @param id 编号 + * @return 流程模型 + */ + BpmModelRespVO getModel(String id); + + /** + * 修改流程模型 + * + * @param updateReqVO 更新信息 + */ + void updateModel(@Valid BpmModelUpdateReqVO updateReqVO); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java index 11204819b..05a8c03f9 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java @@ -13,29 +13,6 @@ import javax.validation.Valid; */ public interface BpmModelService extends BpmModelCommonService { - /** - * 获得流程模块 - * - * @param id 编号 - * @return 流程模型 - */ - BpmModelRespVO getModel(String id); - - /** - * 创建流程模型 - * - * @param modelVO 创建信息 - * @param bpmnXml BPMN XML - * @return 创建的流程模型的编号 - */ - String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml); - - /** - * 修改流程模型 - * - * @param updateReqVO 更新信息 - */ - void updateModel(@Valid BpmModelUpdateReqVO updateReqVO); /** * 将流程模型,部署成一个流程定义 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java index 9d2f911bd..ff2bfa2da 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java @@ -2,17 +2,21 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageItemRespVO; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageReqVO; +import cn.iocoder.yudao.framework.common.util.io.IoUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; +import cn.iocoder.yudao.module.bpm.convert.definition.ModelConvert; import cn.iocoder.yudao.module.bpm.service.definition.FlowableModelService; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.validation.Valid; + +import java.io.IOException; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -30,4 +34,37 @@ public class FlowableModelController { public CommonResult> getModelPage(BpmModelPageReqVO pageVO) { return success(modelService.getModelPage(pageVO)); } + + @GetMapping("/get") + @ApiOperation("获得模型") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) + @PreAuthorize("@ss.hasPermission('bpm:model:query')") + public CommonResult getModel(@RequestParam("id") String id) { + BpmModelRespVO model = modelService.getModel(id); + return success(model); + } + + @PostMapping("/create") + @ApiOperation(value = "新建模型") + @PreAuthorize("@ss.hasPermission('bpm:model:create')") + public CommonResult createModel(@Valid @RequestBody BpmModelCreateReqVO createRetVO) { + return success(modelService.createModel(createRetVO, null)); + } + + @PutMapping("/update") + @ApiOperation(value = "修改模型") + @PreAuthorize("@ss.hasPermission('bpm:model:update')") + public CommonResult updateModel(@Valid @RequestBody BpmModelUpdateReqVO modelVO) { + modelService.updateModel(modelVO); + return success(true); + } + + @PostMapping("/import") + @ApiOperation(value = "导入模型") + public CommonResult importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException { + BpmModelCreateReqVO createReqVO = ModelConvert.INSTANCE.convert(importReqVO); + // 读取文件 + String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false); + return success(modelService.createModel(createReqVO, bpmnXml)); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java index 56587c046..c49cc9c23 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java @@ -1,10 +1,9 @@ package cn.iocoder.yudao.module.bpm.convert.definition; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelBaseVO; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageItemRespVO; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; import cn.iocoder.yudao.module.bpm.service.definition.dto.ModelMetaInfoRespDTO; import org.flowable.common.engine.impl.db.SuspensionState; @@ -17,6 +16,7 @@ import org.mapstruct.factory.Mappers; import java.util.List; import java.util.Map; +import java.util.Objects; /** * 流程模型 Convert @@ -78,8 +78,42 @@ public interface ModelConvert { ModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), ModelMetaInfoRespDTO.class); copyTo(metaInfo, to); } + BpmModelCreateReqVO convert(BpmModeImportReqVO bean); void copyTo(ModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to); BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean); + + default void copy(Model model, BpmModelCreateReqVO bean) { + model.setName(bean.getName()); + model.setKey(bean.getKey()); + model.setMetaInfo(buildMetaInfoStr(null, bean.getDescription(), null, null, + null, null)); + } + + default void copy(Model model, BpmModelUpdateReqVO bean) { + model.setName(bean.getName()); + model.setCategory(bean.getCategory()); + model.setMetaInfo(buildMetaInfoStr(JsonUtils.parseObject(model.getMetaInfo(), ModelMetaInfoRespDTO.class), + bean.getDescription(), bean.getFormType(), bean.getFormId(), + bean.getFormCustomCreatePath(), bean.getFormCustomViewPath())); + } + + default String buildMetaInfoStr(ModelMetaInfoRespDTO metaInfo, String description, Integer formType, + Long formId, String formCustomCreatePath, String formCustomViewPath) { + if (metaInfo == null) { + metaInfo = new ModelMetaInfoRespDTO(); + } + // 只有非空,才进行设置,避免更新时的覆盖 + if (StrUtil.isNotEmpty(description)) { + metaInfo.setDescription(description); + } + if (Objects.nonNull(formType)) { + metaInfo.setFormType(formType); + metaInfo.setFormId(formId); + metaInfo.setFormCustomCreatePath(formCustomCreatePath); + metaInfo.setFormCustomViewPath(formCustomViewPath); + } + return JsonUtils.toJsonString(metaInfo); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java index db7f3d54e..c0d361f0d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java @@ -5,8 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageItemRespVO; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageReqVO; +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.ModelConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; import cn.iocoder.yudao.module.bpm.service.definition.dto.ModelMetaInfoRespDTO; @@ -17,21 +17,27 @@ import org.flowable.engine.repository.Model; import org.flowable.engine.repository.ModelQuery; import org.flowable.engine.repository.ProcessDefinition; 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.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; + /** * Flowable流程模型实现 * 主要进行 Flowable {@link Model} 的维护 * * @author yunlongn * @author 芋道源码 + * @author jason */ @Service @Validated @@ -80,4 +86,70 @@ public class FlowableModelServiceImpl implements FlowableModelService { long modelCount = modelQuery.count(); return new PageResult<>(ModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount); } + + @Override + @Transactional(rollbackFor = Exception.class) + public String createModel(@Valid BpmModelCreateReqVO createReqVO, String bpmnXml) { + checkKeyNCName(createReqVO.getKey()); + // 校验流程标识已经存在 + Model keyModel = this.getModelByKey(createReqVO.getKey()); + if (keyModel != null) { + throw exception(MODEL_KEY_EXISTS, createReqVO.getKey()); + } + + // 创建流程定义 + Model model = repositoryService.newModel(); + ModelConvert.INSTANCE.copy(model, createReqVO); + // 保存流程定义 + repositoryService.saveModel(model); + // 保存 BPMN XML + saveModelBpmnXml(model, bpmnXml); + return model.getId(); + } + + @Override + public BpmModelRespVO getModel(String id) { + Model model = repositoryService.getModel(id); + if (model == null) { + return null; + } + BpmModelRespVO modelRespVO = ModelConvert.INSTANCE.convert(model); + // 拼接 bpmn XML + byte[] bpmnBytes = repositoryService.getModelEditorSource(id); + modelRespVO.setBpmnXml(StrUtil.utf8Str(bpmnBytes)); + return modelRespVO; + } + + @Override + public void updateModel(@Valid BpmModelUpdateReqVO updateReqVO) { + // 校验流程模型存在 + Model model = repositoryService.getModel(updateReqVO.getId()); + if (model == null) { + throw exception(MODEL_NOT_EXISTS); + } + + // 修改流程定义 + ModelConvert.INSTANCE.copy(model, updateReqVO); + // 更新模型 + repositoryService.saveModel(model); + // 更新 BPMN XML + saveModelBpmnXml(model, updateReqVO.getBpmnXml()); + } + + private Model getModelByKey(String key) { + return repositoryService.createModelQuery().modelKey(key).singleResult(); + } + + private void checkKeyNCName(String key) { + if (!ValidationUtils.isXmlNCName(key)) { + throw exception(MODEL_KEY_VALID); + } + } + + private void saveModelBpmnXml(Model model, String bpmnXml) { + if (StrUtil.isEmpty(bpmnXml)) { + return; + } + repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml)); + } } From d6a6a01252d868bb8902587af96403a8e84e3ed4 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Thu, 10 Feb 2022 00:16:43 +0800 Subject: [PATCH 03/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E6=B5=81=E7=A8=8B=E7=9A=84=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/BpmAbstractModelService.java | 56 ++++++++++++ .../definition/BpmModelCommonService.java | 22 +++++ .../dto/BpmModelMetaInfoRespDTO.java | 2 +- .../dto/BpmProcessDefinitionCreateReqDTO.java | 0 .../convert/definition/BpmModelConvert.java | 4 +- .../BpmProcessDefinitionConvert.java | 2 +- .../service/definition/BpmModelService.java | 23 ----- .../definition/BpmModelServiceImpl.java | 44 ++------- .../BpmProcessDefinitionService.java | 2 +- .../BpmProcessDefinitionServiceImpl.java | 2 +- .../definition/FlowableModelController.java | 9 ++ .../BpmProcessDefinitionConvert.java | 18 ++++ .../bpm/convert/definition/ModelConvert.java | 35 ++++++-- .../definition/FlowableModelServiceImpl.java | 90 +++++++++++++++---- .../FlowableProcessDefinitionService.java | 34 +++++++ .../FlowableProcessDefinitionServiceImpl.java | 74 +++++++++++++++ .../definition/dto/ModelMetaInfoRespDTO.java | 39 -------- 17 files changed, 331 insertions(+), 125 deletions(-) create mode 100644 yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java rename yudao-module-bpm/{yudao-module-bpm-impl-activiti => yudao-module-bpm-base}/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java (90%) rename yudao-module-bpm/{yudao-module-bpm-impl-activiti => yudao-module-bpm-base}/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java (100%) create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java delete mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/ModelMetaInfoRespDTO.java diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java new file mode 100644 index 000000000..d790189d5 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; + +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; +/** + * 流程模型通用抽象类 + * Activiti 和 flowable 通用的流程模型抽象类, Activiti 和 flowable 两边通用的方法 + * + * @author yunlongn + * @author jason + */ +public abstract class BpmAbstractModelService { + + protected final BpmFormService bpmFormService; + + public BpmAbstractModelService(BpmFormService bpmFormService) { + this.bpmFormService = bpmFormService; + } + + /** + * 校验流程表单已配置 + * + * @param metaInfoStr 流程模型 metaInfo 字段 + * @return 流程表单 + */ + protected BpmFormDO checkFormConfig(String metaInfoStr) { + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(metaInfoStr, BpmModelMetaInfoRespDTO.class); + if (metaInfo == null || metaInfo.getFormType() == null) { + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG); + } + // 校验表单存在 + if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) { + BpmFormDO form = bpmFormService.getForm(metaInfo.getFormId()); + if (form == null) { + throw exception(FORM_NOT_EXISTS); + } + return form; + } + return null; + } + + + protected void checkKeyNCName(String key) { + if (!ValidationUtils.isXmlNCName(key)) { + throw exception(MODEL_KEY_VALID); + } + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java index 5ffe3ce0b..a634a02d7 100644 --- a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java @@ -44,4 +44,26 @@ public interface BpmModelCommonService { * @param updateReqVO 更新信息 */ void updateModel(@Valid BpmModelUpdateReqVO updateReqVO); + + /** + * 将流程模型,部署成一个流程定义 + * + * @param id 编号 + */ + void deployModel(String id); + + /** + * 删除模型 + * + * @param id 编号 + */ + void deleteModel(String id); + + /** + * 修改模型的状态,实际更新的部署的流程定义的状态 + * + * @param id 编号 + * @param state 状态 + */ + void updateModelState(String id, Integer state); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java similarity index 90% rename from yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java rename to yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java index e50dae3c3..3a36b0eeb 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java @@ -5,7 +5,7 @@ import lombok.Data; /** * BPM 流程 MetaInfo Response DTO - * 主要用于 {@link org.activiti.engine.repository.Model#setMetaInfo(String)} 的存储 + * 主要用于 { Model#setMetaInfo(String)} 的存储 * * @author 芋道源码 */ diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java similarity index 100% rename from yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java rename to yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java index 445911c8c..171bbbb53 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.bpm.convert.definition; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import org.activiti.engine.impl.persistence.entity.SuspensionState; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.Model; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java index 17a4fb144..b789bc000 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java @@ -1,11 +1,11 @@ package cn.iocoder.yudao.module.bpm.convert.definition; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import org.activiti.engine.impl.persistence.entity.SuspensionState; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java index 05a8c03f9..1203f060a 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java @@ -13,29 +13,6 @@ import javax.validation.Valid; */ public interface BpmModelService extends BpmModelCommonService { - - /** - * 将流程模型,部署成一个流程定义 - * - * @param id 编号 - */ - void deployModel(String id); - - /** - * 删除模型 - * - * @param id 编号 - */ - void deleteModel(String id); - - /** - * 修改模型的状态,实际更新的部署的流程定义的状态 - * - * @param id 编号 - * @param state 状态 {@link org.activiti.engine.impl.persistence.entity.SuspensionState} - */ - void updateModelState(String id, Integer state); - /** * 获得流程模型编号对应的 BPMN Model * diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java index 3626bd58c..abda72ea3 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java @@ -6,16 +6,14 @@ import cn.hutool.core.util.StrUtil; 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.service.definition.dto.BpmModelMetaInfoRespDTO; -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; -import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; -import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import lombok.extern.slf4j.Slf4j; import org.activiti.bpmn.model.BpmnModel; import org.activiti.engine.RepositoryService; @@ -47,18 +45,22 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; @Service @Validated @Slf4j -public class BpmModelServiceImpl implements BpmModelService { +public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmModelService { @Resource private RepositoryService repositoryService; - @Resource - private BpmFormService bpmFormService; + @Resource private BpmProcessDefinitionService processDefinitionService; @Resource @Lazy // 解决循环依赖 private BpmTaskAssignRuleService taskAssignRuleService; + + public BpmModelServiceImpl(BpmFormService bpmFormService) { + super(bpmFormService); + } + @Override public PageResult getModelPage(BpmModelPageReqVO pageVO) { ModelQuery modelQuery = repositoryService.createModelQuery(); @@ -167,7 +169,7 @@ public class BpmModelServiceImpl implements BpmModelService { } // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素; // 校验表单已配 - BpmFormDO form = checkFormConfig(model); + BpmFormDO form = checkFormConfig(model.getMetaInfo()); // 校验任务分配规则已配置 checkTaskAssignRuleAllConfig(id); @@ -214,28 +216,6 @@ public class BpmModelServiceImpl implements BpmModelService { }); } - /** - * 校验流程表单已配置 - * - * @param model 流程模型 - * @return 流程表单 - */ - private BpmFormDO checkFormConfig(Model model) { - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); - if (metaInfo == null || metaInfo.getFormType() == null) { - throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG); - } - // 校验表单存在 - if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) { - BpmFormDO form = bpmFormService.getForm(metaInfo.getFormId()); - if (form == null) { - throw exception(FORM_NOT_EXISTS); - } - return form; - } - return null; - } - @Override @Transactional(rollbackFor = Exception.class) public void deleteModel(String id) { @@ -291,10 +271,4 @@ public class BpmModelServiceImpl implements BpmModelService { return repositoryService.createModelQuery().modelKey(key).singleResult(); } - private void checkKeyNCName(String key) { - if (!ValidationUtils.isXmlNCName(key)) { - throw exception(MODEL_KEY_VALID); - } - } - } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java index 7fe2a28de..afa1e9d03 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java @@ -5,9 +5,9 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmPro import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import org.activiti.bpmn.model.BpmnModel; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java index 538e2a05c..5d41da654 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert; -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.PageUtils; @@ -15,6 +14,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmPro import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import lombok.extern.slf4j.Slf4j; import org.activiti.bpmn.model.BpmnModel; import org.activiti.engine.RepositoryService; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java index ff2bfa2da..2a51688d6 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java @@ -67,4 +67,13 @@ public class FlowableModelController { String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false); return success(modelService.createModel(createReqVO, bpmnXml)); } + + @PostMapping("/deploy") + @ApiOperation(value = "部署模型") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) + @PreAuthorize("@ss.hasPermission('bpm:model:deploy')") + public CommonResult deployModel(@RequestParam("id") String id) { + modelService.deployModel(id); + return success(true); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java new file mode 100644 index 000000000..4b15ffb00 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.bpm.convert.definition; + +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * Bpm 流程定义的 Convert + * + * @author yunlong.li + */ +@Mapper +public interface BpmProcessDefinitionConvert { + BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class); + + BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean); +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java index c49cc9c23..4c7cd01ba 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java @@ -5,7 +5,8 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; -import cn.iocoder.yudao.module.bpm.service.definition.dto.ModelMetaInfoRespDTO; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import org.flowable.common.engine.impl.db.SuspensionState; import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.Model; @@ -32,7 +33,7 @@ public interface ModelConvert { Map deploymentMap, Map processDefinitionMap) { return CollectionUtils.convertList(list, model -> { - ModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), ModelMetaInfoRespDTO.class); + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null; Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null; ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null; @@ -75,12 +76,32 @@ public interface ModelConvert { to.setKey(model.getKey()); to.setCategory(model.getCategory()); // metaInfo - ModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), ModelMetaInfoRespDTO.class); + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); copyTo(metaInfo, to); } + BpmModelCreateReqVO convert(BpmModeImportReqVO bean); - void copyTo(ModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to); + default BpmProcessDefinitionCreateReqDTO convert2(Model model, BpmFormDO form) { + BpmProcessDefinitionCreateReqDTO createReqDTO = new BpmProcessDefinitionCreateReqDTO(); + createReqDTO.setModelId(model.getId()); + createReqDTO.setName(model.getName()); + createReqDTO.setKey(model.getKey()); + createReqDTO.setCategory(model.getCategory()); + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); + // metaInfo + copyTo(metaInfo, createReqDTO); + // form + if (form != null) { + createReqDTO.setFormConf(form.getConf()); + createReqDTO.setFormFields(form.getFields()); + } + return createReqDTO; + } + + void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmProcessDefinitionCreateReqDTO to); + + void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to); BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean); @@ -94,15 +115,15 @@ public interface ModelConvert { default void copy(Model model, BpmModelUpdateReqVO bean) { model.setName(bean.getName()); model.setCategory(bean.getCategory()); - model.setMetaInfo(buildMetaInfoStr(JsonUtils.parseObject(model.getMetaInfo(), ModelMetaInfoRespDTO.class), + model.setMetaInfo(buildMetaInfoStr(JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class), bean.getDescription(), bean.getFormType(), bean.getFormId(), bean.getFormCustomCreatePath(), bean.getFormCustomViewPath())); } - default String buildMetaInfoStr(ModelMetaInfoRespDTO metaInfo, String description, Integer formType, + default String buildMetaInfoStr(BpmModelMetaInfoRespDTO metaInfo, String description, Integer formType, Long formId, String formCustomCreatePath, String formCustomViewPath) { if (metaInfo == null) { - metaInfo = new ModelMetaInfoRespDTO(); + metaInfo = new BpmModelMetaInfoRespDTO(); } // 只有非空,才进行设置,避免更新时的覆盖 if (StrUtil.isNotEmpty(description)) { diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java index c0d361f0d..12354db9a 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java @@ -5,12 +5,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; -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.ModelConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; -import cn.iocoder.yudao.module.bpm.service.definition.dto.ModelMetaInfoRespDTO; +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; +import org.flowable.common.engine.impl.db.SuspensionState; import org.flowable.engine.RepositoryService; import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.Model; @@ -18,14 +19,12 @@ import org.flowable.engine.repository.ModelQuery; import org.flowable.engine.repository.ProcessDefinition; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ObjectUtils; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; @@ -42,15 +41,17 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; @Service @Validated @Slf4j -public class FlowableModelServiceImpl implements FlowableModelService { +public class FlowableModelServiceImpl extends BpmAbstractModelService implements FlowableModelService { @Resource private RepositoryService repositoryService; @Resource - private BpmFormService bpmFormService; - @Resource private FlowableProcessDefinitionService processDefinitionService; + public FlowableModelServiceImpl(BpmFormService bpmFormService){ + super(bpmFormService); + } + @Override public PageResult getModelPage(BpmModelPageReqVO pageVO) { ModelQuery modelQuery = repositoryService.createModelQuery(); @@ -69,7 +70,7 @@ public class FlowableModelServiceImpl implements FlowableModelService { // 获得 Form Map Set formIds = CollectionUtils.convertSet(models, model -> { - ModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), ModelMetaInfoRespDTO.class); + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class); return metaInfo != null ? metaInfo.getFormId() : null; }); Map formMap = bpmFormService.getFormMap(formIds); @@ -136,15 +137,63 @@ public class FlowableModelServiceImpl implements FlowableModelService { saveModelBpmnXml(model, updateReqVO.getBpmnXml()); } + @Override + public void deployModel(String id) { + // 校验流程模型存在 + Model model = repositoryService.getModel(id); + if (ObjectUtils.isEmpty(model)) { + throw exception(MODEL_NOT_EXISTS); + } + // 校验流程图 + byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId()); + if (bpmnBytes == null) { + throw exception(MODEL_NOT_EXISTS); + } + // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素; + // 校验表单已配 + BpmFormDO form = checkFormConfig(model.getMetaInfo()); + //TODO 校验任务分配规则已配置 + //checkTaskAssignRuleAllConfig(id); + + BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = ModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes); + // TODO 校验模型是否发生修改。如果未修改,则不允许创建 +// if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等 +// ProcessDefinition oldProcessInstance = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId()); +// if (oldProcessInstance != null && taskAssignRuleService.isTaskAssignRulesEquals(model.getId(), oldProcessInstance.getId())) { +// throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS); +// } +// } + // 创建流程定义 + String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO); + + // 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。 + updateProcessDefinitionSuspended(model.getDeploymentId()); + + // 更新 model 的 deploymentId,进行关联 + ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId); + model.setDeploymentId(definition.getDeploymentId()); + repositoryService.saveModel(model); + + //TODO 复制任务分配规则 + //taskAssignRuleService.copyTaskAssignRules(id, definition.getId()); + } + + @Override + public void deleteModel(String id) { + + } + + @Override + public void updateModelState(String id, Integer state) { + + } + + + private Model getModelByKey(String key) { return repositoryService.createModelQuery().modelKey(key).singleResult(); } - private void checkKeyNCName(String key) { - if (!ValidationUtils.isXmlNCName(key)) { - throw exception(MODEL_KEY_VALID); - } - } private void saveModelBpmnXml(Model model, String bpmnXml) { if (StrUtil.isEmpty(bpmnXml)) { @@ -152,4 +201,15 @@ public class FlowableModelServiceImpl implements FlowableModelService { } repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml)); } + + private void updateProcessDefinitionSuspended(String deploymentId) { + if (StrUtil.isEmpty(deploymentId)) { + return; + } + ProcessDefinition oldDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(deploymentId); + if (oldDefinition == null) { + return; + } + processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode()); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java index c6693f364..c7643c148 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java @@ -1,9 +1,11 @@ package cn.iocoder.yudao.module.bpm.service.definition; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.ProcessDefinition; +import javax.validation.Valid; import java.util.List; import java.util.Map; import java.util.Set; @@ -16,6 +18,22 @@ import java.util.Set; */ public interface FlowableProcessDefinitionService { + /** + * 获得编号对应的 ProcessDefinition + * + * @param id 编号 + * @return 流程定义 + */ + ProcessDefinition getProcessDefinition(String id); + + /** + * 获得 deploymentId 对应的 ProcessDefinition + * + * @param deploymentId 部署编号 + * @return 流程定义 + */ + ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId); + /** * 获得 deploymentIds 对应的 ProcessDefinition 数组 * @@ -49,4 +67,20 @@ public interface FlowableProcessDefinitionService { * @return 流程部署 */ Deployment getDeployment(String id); + + /** + * 创建流程定义 + * + * @param createReqDTO 创建信息 + * @return 流程编号 + */ + String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); + + /** + * 更新流程定义状态 + * + * @param id 流程定义的编号 + * @param state 状态 + */ + void updateProcessDefinitionState(String id, Integer state); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java index 7bcf72327..f205d3249 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java @@ -2,7 +2,12 @@ package cn.iocoder.yudao.module.bpm.service.definition; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import lombok.extern.slf4j.Slf4j; +import org.flowable.common.engine.impl.db.SuspensionState; import org.flowable.engine.RepositoryService; import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.ProcessDefinition; @@ -10,11 +15,16 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import javax.validation.Valid; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Set; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.addIfNotNull; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH; import static java.util.Collections.emptyList; /** @@ -29,9 +39,28 @@ import static java.util.Collections.emptyList; @Validated @Slf4j public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefinitionService { + + private static final String BPMN_FILE_SUFFIX = ".bpmn"; + @Resource private RepositoryService repositoryService; + @Resource + private BpmProcessDefinitionExtMapper processDefinitionMapper; + + @Override + public ProcessDefinition getProcessDefinition(String id) { + return repositoryService.getProcessDefinition(id); + } + + @Override + public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) { + if (StrUtil.isEmpty(deploymentId)) { + return null; + } + return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult(); + } + @Override public List getProcessDefinitionListByDeploymentIds(Set deploymentIds) { if (CollUtil.isEmpty(deploymentIds)) { @@ -59,4 +88,49 @@ public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefi } return repositoryService.createDeploymentQuery().deploymentId(id).singleResult(); } + + @Override + public String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) { + // 创建 Deployment 部署 + Deployment deploy = repositoryService.createDeployment() + .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory()) + .addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes()) + .deploy(); + + // 设置 ProcessDefinition 的 category 分类 + ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult(); + repositoryService.setProcessDefinitionCategory(definition.getId(), createReqDTO.getCategory()); + // 注意 1,ProcessDefinition 的 key 和 name 是通过 BPMN 中的 的 id 和 name 决定 + // 注意 2,目前该项目的设计上,需要保证 Model、Deployment、ProcessDefinition 使用相同的 key,保证关联性。 + // 否则,会导致 ProcessDefinition 的分页无法查询到。 + if (!Objects.equals(definition.getKey(), createReqDTO.getKey())) { + throw exception(PROCESS_DEFINITION_KEY_NOT_MATCH, createReqDTO.getKey(), definition.getKey()); + } + if (!Objects.equals(definition.getName(), createReqDTO.getName())) { + throw exception(PROCESS_DEFINITION_NAME_NOT_MATCH, createReqDTO.getName(), definition.getName()); + } + + // 插入拓展表 + BpmProcessDefinitionExtDO definitionDO = BpmProcessDefinitionConvert.INSTANCE.convert2(createReqDTO) + .setProcessDefinitionId(definition.getId()); + processDefinitionMapper.insert(definitionDO); + return definition.getId(); + } + + @Override + public void updateProcessDefinitionState(String id, Integer state) { + // 激活 + if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) { + repositoryService.activateProcessDefinitionById(id, false, null); + return; + } + // 挂起 + if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) { + // suspendProcessInstances = false,进行中的任务,不进行挂起。 + // 原因:只要新的流程不允许发起即可,老流程继续可以执行。 + repositoryService.suspendProcessDefinitionById(id, false, null); + return; + } + log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/ModelMetaInfoRespDTO.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/ModelMetaInfoRespDTO.java deleted file mode 100644 index ee725054c..000000000 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/ModelMetaInfoRespDTO.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.bpm.service.definition.dto; - -import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; -import lombok.Data; - -/** - * BPM 流程 MetaInfo Response DTO - * 主要用于 {@link org.flowable.engine.repository.Model#setMetaInfo(String)} 的存储 - * - * @author 芋道源码 - */ -@Data -public class ModelMetaInfoRespDTO { - - /** - * 流程描述 - */ - private String description; - /** - * 表单类型 - */ - private Integer formType; - /** - * 表单编号 - * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时 - */ - private Long formId; - /** - * 自定义表单的提交路径,使用 Vue 的路由地址 - * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 - */ - private String formCustomCreatePath; - /** - * 自定义表单的查看路径,使用 Vue 的路由地址 - * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时 - */ - private String formCustomViewPath; - -} From b1d6baaad8a92c6de7364c2dffbe29ccd5392031 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Fri, 11 Feb 2022 00:01:46 +0800 Subject: [PATCH 04/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E6=B5=81=E7=A8=8B,=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=20=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/BpmAbstractModelService.java | 28 +- .../BpmProcessDefinitionCommonService.java | 69 +++++ .../definition/BpmTaskAssignRuleService.java | 0 .../definition/BpmModelServiceImpl.java | 28 +- .../BpmProcessDefinitionService.java | 50 +--- ...ontroller.java => BpmModelController.java} | 27 +- .../BpmProcessDefinitionController.java | 47 ++++ ...ModelConvert.java => BpmModelConvert.java} | 4 +- .../BpmProcessDefinitionConvert.java | 43 +++ .../definition/BpmTaskAssignRuleConvert.java | 32 +++ .../service/definition/BpmModelService.java | 20 ++ ...viceImpl.java => BpmModelServiceImpl.java} | 93 ++++-- ....java => BpmProcessDefinitionService.java} | 29 +- .../BpmProcessDefinitionServiceImpl.java | 265 ++++++++++++++++++ .../BpmTaskAssignRuleServiceImpl.java | 141 ++++++++++ .../definition/FlowableModelService.java | 10 - .../FlowableProcessDefinitionServiceImpl.java | 136 --------- 17 files changed, 750 insertions(+), 272 deletions(-) create mode 100644 yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionCommonService.java rename yudao-module-bpm/{yudao-module-bpm-impl-activiti => yudao-module-bpm-base}/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java (100%) rename yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/{FlowableModelController.java => BpmModelController.java} (72%) create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java rename yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/{ModelConvert.java => BpmModelConvert.java} (98%) create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java rename yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/{FlowableModelServiceImpl.java => BpmModelServiceImpl.java} (70%) rename yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/{FlowableProcessDefinitionService.java => BpmProcessDefinitionService.java} (77%) create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java delete mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelService.java delete mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java index d790189d5..caa8e1399 100644 --- a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java @@ -1,11 +1,14 @@ package cn.iocoder.yudao.module.bpm.service.definition; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; +import java.util.List; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -21,8 +24,11 @@ public abstract class BpmAbstractModelService { protected final BpmFormService bpmFormService; - public BpmAbstractModelService(BpmFormService bpmFormService) { + protected final BpmTaskAssignRuleService taskAssignRuleService; + + public BpmAbstractModelService(BpmFormService bpmFormService,BpmTaskAssignRuleService taskAssignRuleService) { this.bpmFormService = bpmFormService; + this.taskAssignRuleService = taskAssignRuleService; } /** @@ -47,6 +53,26 @@ public abstract class BpmAbstractModelService { return null; } + /** + * 校验流程模型的任务分配规则全部都配置了 + * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去! + * + * @param id 流程模型编号 + */ + protected void checkTaskAssignRuleAllConfig(String id) { + // 一个用户任务都没配置,所以无需配置规则 + List taskAssignRules = taskAssignRuleService.getTaskAssignRuleList(id, null); + if (CollUtil.isEmpty(taskAssignRules)) { + return; + } + // 校验未配置规则的任务 + taskAssignRules.forEach(rule -> { + if (CollUtil.isEmpty(rule.getOptions())) { + throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName()); + } + }); + } + protected void checkKeyNCName(String key) { if (!ValidationUtils.isXmlNCName(key)) { diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionCommonService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionCommonService.java new file mode 100644 index 000000000..51a2ee424 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionCommonService.java @@ -0,0 +1,69 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; + +import javax.validation.Valid; + +/** + * 流程定义通用接口 + * Activiti 和 flowable 通用的流程定义接口 + * + * @author yunlong.li + * @author ZJQ + * @author 芋道源码 + * @author jason + */ +public interface BpmProcessDefinitionCommonService { + + /** + * 获得流程定义分页 + * + * @param pageReqVO 分页入参 + * @return 流程定义 Page + */ + PageResult getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO); + + /** + * 创建流程定义 + * + * @param createReqDTO 创建信息 + * @return 流程编号 + */ + String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); + + /** + * 更新流程定义状态 + * + * @param id 流程定义的编号 + * @param state 状态 + */ + void updateProcessDefinitionState(String id, Integer state); + + /** + * 获得流程定义对应的 BPMN XML + * + * @param id 流程定义编号 + * @return BPMN XML + */ + String getProcessDefinitionBpmnXML(String id); + + /** + * 获得需要创建的流程定义,是否和当前激活的流程定义相等 + * + * @param createReqDTO 创建信息 + * @return 是否相等 + */ + boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); + + /** + * 获得编号对应的 BpmProcessDefinitionExtDO + * + * @param id 编号 + * @return 流程定义拓展 + */ + BpmProcessDefinitionExtDO getProcessDefinitionExt(String id); +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java similarity index 100% rename from yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java rename to yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java index abda72ea3..4387199d4 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java @@ -52,13 +52,9 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM @Resource private BpmProcessDefinitionService processDefinitionService; - @Resource - @Lazy // 解决循环依赖 - private BpmTaskAssignRuleService taskAssignRuleService; - - public BpmModelServiceImpl(BpmFormService bpmFormService) { - super(bpmFormService); + public BpmModelServiceImpl(BpmFormService bpmFormService,BpmTaskAssignRuleService taskAssignRuleService) { + super(bpmFormService, taskAssignRuleService); } @Override @@ -196,26 +192,6 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM taskAssignRuleService.copyTaskAssignRules(id, definition.getId()); } - /** - * 校验流程模型的任务分配规则全部都配置了 - * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去! - * - * @param id 流程模型编号 - */ - private void checkTaskAssignRuleAllConfig(String id) { - // 一个用户任务都没配置,所以无需配置规则 - List taskAssignRules = taskAssignRuleService.getTaskAssignRuleList(id, null); - if (CollUtil.isEmpty(taskAssignRules)) { - return; - } - // 校验未配置规则的任务 - taskAssignRules.forEach(rule -> { - if (CollUtil.isEmpty(rule.getOptions())) { - throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName()); - } - }); - } - @Override @Transactional(rollbackFor = Exception.class) public void deleteModel(String id) { diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java index afa1e9d03..58bba1f6c 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java @@ -24,15 +24,7 @@ import java.util.Set; * @author ZJQ * @author 芋道源码 */ -public interface BpmProcessDefinitionService { - - /** - * 获得流程定义分页 - * - * @param pageReqVO 分页入参 - * @return 流程定义 Page - */ - PageResult getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO); +public interface BpmProcessDefinitionService extends BpmProcessDefinitionCommonService { /** * 获得流程定义列表 @@ -42,14 +34,6 @@ public interface BpmProcessDefinitionService { */ List getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO); - /** - * 获得流程定义对应的 BPMN XML - * - * @param id 流程定义编号 - * @return BPMN XML - */ - String getProcessDefinitionBpmnXML(String id); - /** * 获得 Bpmn 模型 * @@ -84,14 +68,6 @@ public interface BpmProcessDefinitionService { */ ProcessDefinition getActiveProcessDefinition(String key); - /** - * 获得编号对应的 BpmProcessDefinitionExtDO - * - * @param id 编号 - * @return 流程定义拓展 - */ - BpmProcessDefinitionExtDO getProcessDefinitionExt(String id); - /** * 获得 id 对应的 Deployment * @@ -134,28 +110,4 @@ public interface BpmProcessDefinitionService { */ List getProcessDefinitionListByDeploymentIds(Set deploymentIds); - /** - * 获得需要创建的流程定义,是否和当前激活的流程定义相等 - * - * @param createReqDTO 创建信息 - * @return 是否相等 - */ - boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); - - /** - * 创建流程定义 - * - * @param createReqDTO 创建信息 - * @return 流程编号 - */ - String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); - - /** - * 更新流程定义的挂起状态 - * - * @param id 流程定义的编号 - * @param state 挂起状态 {@link org.activiti.engine.impl.persistence.entity.SuspensionState} - */ - void updateProcessDefinitionState(String id, Integer state); - } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java similarity index 72% rename from yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java rename to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java index 2a51688d6..1bac1888e 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/FlowableModelController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.io.IoUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; -import cn.iocoder.yudao.module.bpm.convert.definition.ModelConvert; -import cn.iocoder.yudao.module.bpm.service.definition.FlowableModelService; +import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert; +import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; @@ -24,10 +24,10 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @RestController @RequestMapping("/bpm/model") @Validated -public class FlowableModelController { +public class BpmModelController { @Resource - private FlowableModelService modelService; + private BpmModelService modelService; @GetMapping("/page") @ApiOperation(value = "获得模型分页") @@ -62,7 +62,7 @@ public class FlowableModelController { @PostMapping("/import") @ApiOperation(value = "导入模型") public CommonResult importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException { - BpmModelCreateReqVO createReqVO = ModelConvert.INSTANCE.convert(importReqVO); + BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO); // 读取文件 String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false); return success(modelService.createModel(createReqVO, bpmnXml)); @@ -76,4 +76,21 @@ public class FlowableModelController { modelService.deployModel(id); return success(true); } + + @PutMapping("/update-state") + @ApiOperation(value = "修改模型的状态", notes = "实际更新的部署的流程定义的状态") + @PreAuthorize("@ss.hasPermission('bpm:model:update')") + public CommonResult updateModelState(@Valid @RequestBody BpmModelUpdateStateReqVO reqVO) { + modelService.updateModelState(reqVO.getId(), reqVO.getState()); + return success(true); + } + + @DeleteMapping("/delete") + @ApiOperation("删除模型") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) + @PreAuthorize("@ss.hasPermission('bpm:model:delete')") + public CommonResult deleteModel(@RequestParam("id") String id) { + modelService.deleteModel(id); + return success(true); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java new file mode 100644 index 000000000..2d6ddc0b0 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.definition; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Api(tags = "管理后台 - 流程定义") +@RestController +@RequestMapping("/bpm/process-definition") +@Validated +public class BpmProcessDefinitionController { + + @Resource + private BpmProcessDefinitionService bpmDefinitionService; + + @GetMapping("/page") + @ApiOperation(value = "获得流程定义分页") + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')") + public CommonResult> getProcessDefinitionPage( + BpmProcessDefinitionPageReqVO pageReqVO) { + return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO)); + } + + @GetMapping ("/get-bpmn-xml") + @ApiOperation(value = "获得流程定义的 BPMN XML") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')") + public CommonResult getProcessDefinitionBpmnXML(@RequestParam("id") String id) { + String bpmnXML = bpmDefinitionService.getProcessDefinitionBpmnXML(id); + return success(bpmnXML); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java similarity index 98% rename from yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java rename to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java index 4c7cd01ba..4d1b2a003 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/ModelConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java @@ -25,9 +25,9 @@ import java.util.Objects; * @author yunlongn */ @Mapper -public interface ModelConvert { +public interface BpmModelConvert { - ModelConvert INSTANCE = Mappers.getMapper(ModelConvert.class); + BpmModelConvert INSTANCE = Mappers.getMapper(BpmModelConvert.class); default List convertList(List list, Map formMap, Map deploymentMap, diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java index 4b15ffb00..5e8168369 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java @@ -1,10 +1,22 @@ package cn.iocoder.yudao.module.bpm.convert.definition; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; +import org.flowable.common.engine.impl.db.SuspensionState; +import org.flowable.engine.repository.Deployment; +import org.flowable.engine.repository.ProcessDefinition; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; import org.mapstruct.factory.Mappers; +import java.util.List; +import java.util.Map; + /** * Bpm 流程定义的 Convert * @@ -12,7 +24,38 @@ import org.mapstruct.factory.Mappers; */ @Mapper public interface BpmProcessDefinitionConvert { + BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class); + BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean); + BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean); + + default List convertList(List list, Map deploymentMap, + Map processDefinitionDOMap, Map formMap) { + return CollectionUtils.convertList(list, definition -> { + Deployment deployment = definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId()) : null; + BpmProcessDefinitionExtDO definitionDO = processDefinitionDOMap.get(definition.getId()); + BpmFormDO form = definitionDO != null ? formMap.get(definitionDO.getFormId()) : null; + return convert(definition, deployment, definitionDO, form); + }); + } + + default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment, + BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) { + BpmProcessDefinitionPageItemRespVO respVO = convert(bean); + respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode()); + if (deployment != null) { + respVO.setDeploymentTime(deployment.getDeploymentTime()); + } + if (form != null) { + respVO.setFormName(form.getName()); + } + // 复制通用属性 + copyTo(processDefinitionExtDO, respVO); + return respVO; + } + + @Mapping(source = "from.id", target = "to.id", ignore = true) + void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessDefinitionRespVO to); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java new file mode 100644 index 000000000..992fa0b86 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.bpm.convert.definition; + +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; +import org.flowable.bpmn.model.UserTask; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface BpmTaskAssignRuleConvert { + BpmTaskAssignRuleConvert INSTANCE = Mappers.getMapper(BpmTaskAssignRuleConvert.class); + + default List convertList(List tasks, List rules) { + Map ruleMap = CollectionUtils.convertMap(rules, BpmTaskAssignRuleDO::getTaskDefinitionKey); + // 以 UserTask 为主维度,原因是:流程图编辑后,一些规则实际就没用了。 + return CollectionUtils.convertList(tasks, task -> { + BpmTaskAssignRuleRespVO respVO = convert(ruleMap.get(task.getId())); + if (respVO == null) { + respVO = new BpmTaskAssignRuleRespVO(); + respVO.setTaskDefinitionKey(task.getId()); + } + respVO.setTaskDefinitionName(task.getName()); + return respVO; + }); + } + + BpmTaskAssignRuleRespVO convert(BpmTaskAssignRuleDO bean); +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java new file mode 100644 index 000000000..9bd455191 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +import org.flowable.bpmn.model.BpmnModel; + +/** + * Flowable流程模型接口 + * + * @author yunlongn + */ +public interface BpmModelService extends BpmModelCommonService { + + /** + * 获得流程模型编号对应的 BPMN Model + * + * @param id 流程模型编号 + * @return BPMN Model + */ + BpmnModel getBpmnModel(String id); + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java similarity index 70% rename from yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java rename to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java index 12354db9a..a1558d681 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java @@ -1,17 +1,21 @@ package cn.iocoder.yudao.module.bpm.service.definition; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; -import cn.iocoder.yudao.module.bpm.convert.definition.ModelConvert; +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.service.definition.dto.BpmModelMetaInfoRespDTO; import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.converter.BpmnXMLConverter; +import org.flowable.bpmn.model.BpmnModel; import org.flowable.common.engine.impl.db.SuspensionState; +import org.flowable.common.engine.impl.util.io.BytesStreamSource; import org.flowable.engine.RepositoryService; import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.Model; @@ -41,15 +45,15 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; @Service @Validated @Slf4j -public class FlowableModelServiceImpl extends BpmAbstractModelService implements FlowableModelService { +public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmModelService { @Resource private RepositoryService repositoryService; @Resource - private FlowableProcessDefinitionService processDefinitionService; + private BpmProcessDefinitionService processDefinitionService; - public FlowableModelServiceImpl(BpmFormService bpmFormService){ - super(bpmFormService); + public BpmModelServiceImpl(BpmFormService bpmFormService, BpmTaskAssignRuleService taskAssignRuleService){ + super(bpmFormService, taskAssignRuleService); } @Override @@ -85,7 +89,7 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements // 拼接结果 long modelCount = modelQuery.count(); - return new PageResult<>(ModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount); + return new PageResult<>(BpmModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount); } @Override @@ -100,7 +104,7 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements // 创建流程定义 Model model = repositoryService.newModel(); - ModelConvert.INSTANCE.copy(model, createReqVO); + BpmModelConvert.INSTANCE.copy(model, createReqVO); // 保存流程定义 repositoryService.saveModel(model); // 保存 BPMN XML @@ -108,13 +112,17 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements return model.getId(); } + private Model getModelByKey(String key) { + return repositoryService.createModelQuery().modelKey(key).singleResult(); + } + @Override public BpmModelRespVO getModel(String id) { Model model = repositoryService.getModel(id); if (model == null) { return null; } - BpmModelRespVO modelRespVO = ModelConvert.INSTANCE.convert(model); + BpmModelRespVO modelRespVO = BpmModelConvert.INSTANCE.convert(model); // 拼接 bpmn XML byte[] bpmnBytes = repositoryService.getModelEditorSource(id); modelRespVO.setBpmnXml(StrUtil.utf8Str(bpmnBytes)); @@ -130,7 +138,7 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements } // 修改流程定义 - ModelConvert.INSTANCE.copy(model, updateReqVO); + BpmModelConvert.INSTANCE.copy(model, updateReqVO); // 更新模型 repositoryService.saveModel(model); // 更新 BPMN XML @@ -152,17 +160,17 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素; // 校验表单已配 BpmFormDO form = checkFormConfig(model.getMetaInfo()); - //TODO 校验任务分配规则已配置 - //checkTaskAssignRuleAllConfig(id); + //校验任务分配规则已配置 + checkTaskAssignRuleAllConfig(id); - BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = ModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes); - // TODO 校验模型是否发生修改。如果未修改,则不允许创建 -// if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等 -// ProcessDefinition oldProcessInstance = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId()); -// if (oldProcessInstance != null && taskAssignRuleService.isTaskAssignRulesEquals(model.getId(), oldProcessInstance.getId())) { -// throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS); -// } -// } + BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes); + //校验模型是否发生修改。如果未修改,则不允许创建 + if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等 + ProcessDefinition oldProcessInstance = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId()); + if (oldProcessInstance != null && taskAssignRuleService.isTaskAssignRulesEquals(model.getId(), oldProcessInstance.getId())) { + throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS); + } + } // 创建流程定义 String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO); @@ -178,23 +186,38 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements //taskAssignRuleService.copyTaskAssignRules(id, definition.getId()); } - @Override - public void deleteModel(String id) { + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteModel(String id) { + // 校验流程模型存在 + Model model = repositoryService.getModel(id); + if (model == null) { + throw exception(MODEL_NOT_EXISTS); + } + // 执行删除 + repositoryService.deleteModel(id); + // 禁用流程实例 + updateProcessDefinitionSuspended(model.getDeploymentId()); } @Override public void updateModelState(String id, Integer state) { + // 校验流程模型存在 + Model model = repositoryService.getModel(id); + if (model == null) { + throw exception(MODEL_NOT_EXISTS); + } + // 校验流程定义存在 + ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId()); + if (definition == null) { + throw exception(PROCESS_DEFINITION_NOT_EXISTS); + } + // 更新状态 + processDefinitionService.updateProcessDefinitionState(definition.getId(), state); } - - - private Model getModelByKey(String key) { - return repositoryService.createModelQuery().modelKey(key).singleResult(); - } - - private void saveModelBpmnXml(Model model, String bpmnXml) { if (StrUtil.isEmpty(bpmnXml)) { return; @@ -202,6 +225,10 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml)); } + /** + * 挂起 deploymentId 对应的流程定义。 这里一个deploymentId 只关联一个流程定义 + * @param deploymentId 流程发布Id. + */ private void updateProcessDefinitionSuspended(String deploymentId) { if (StrUtil.isEmpty(deploymentId)) { return; @@ -212,4 +239,14 @@ public class FlowableModelServiceImpl extends BpmAbstractModelService implements } processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode()); } + + @Override + public BpmnModel getBpmnModel(String id) { + byte[] bpmnBytes = repositoryService.getModelEditorSource(id); + if (ArrayUtil.isEmpty(bpmnBytes)) { + return null; + } + BpmnXMLConverter converter = new BpmnXMLConverter(); + return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java similarity index 77% rename from yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java rename to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java index c7643c148..121bdc220 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java @@ -1,11 +1,10 @@ package cn.iocoder.yudao.module.bpm.service.definition; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; +import org.flowable.bpmn.model.BpmnModel; import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.ProcessDefinition; -import javax.validation.Valid; import java.util.List; import java.util.Map; import java.util.Set; @@ -16,7 +15,7 @@ import java.util.Set; * @author ZJQ * @author 芋道源码 */ -public interface FlowableProcessDefinitionService { +public interface BpmProcessDefinitionService extends BpmProcessDefinitionCommonService { /** * 获得编号对应的 ProcessDefinition @@ -42,6 +41,14 @@ public interface FlowableProcessDefinitionService { */ List getProcessDefinitionListByDeploymentIds(Set deploymentIds); + /** + * 获得流程定义标识对应的激活的流程定义 + * + * @param key 流程定义的标识 + * @return 流程定义 + */ + ProcessDefinition getActiveProcessDefinition(String key); + /** * 获得 ids 对应的 Deployment Map * @@ -69,18 +76,10 @@ public interface FlowableProcessDefinitionService { Deployment getDeployment(String id); /** - * 创建流程定义 + * 获得 Bpmn 模型 * - * @param createReqDTO 创建信息 - * @return 流程编号 + * @param processDefinitionId 流程定义的编号 + * @return Bpmn 模型 */ - String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); - - /** - * 更新流程定义状态 - * - * @param id 流程定义的编号 - * @param state 状态 - */ - void updateProcessDefinitionState(String id, Integer state); + BpmnModel getBpmnModel(String processDefinitionId); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java new file mode 100644 index 000000000..cb3419483 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java @@ -0,0 +1,265 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.PageUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; +import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; +import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.converter.BpmnXMLConverter; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.common.engine.impl.db.SuspensionState; +import org.flowable.common.engine.impl.util.io.BytesStreamSource; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.repository.Deployment; +import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.engine.repository.ProcessDefinitionQuery; +import org.springframework.stereotype.Service; +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.*; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH; +import static java.util.Collections.emptyList; + +/** + * 流程定义实现 + * 主要进行 Flowable {@link ProcessDefinition} 和 {@link Deployment} 的维护 + * + * @author yunlongn + * @author ZJQ + * @author 芋道源码 + */ +@Service +@Validated +@Slf4j +public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService { + + private static final String BPMN_FILE_SUFFIX = ".bpmn"; + + @Resource + private RepositoryService repositoryService; + + @Resource + private BpmProcessDefinitionExtMapper processDefinitionMapper; + + @Resource + private BpmFormService formService; + + @Override + public ProcessDefinition getProcessDefinition(String id) { + return repositoryService.getProcessDefinition(id); + } + + @Override + public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) { + if (StrUtil.isEmpty(deploymentId)) { + return null; + } + return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult(); + } + + @Override + public List getProcessDefinitionListByDeploymentIds(Set deploymentIds) { + if (CollUtil.isEmpty(deploymentIds)) { + return emptyList(); + } + return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list(); + } + + @Override + public ProcessDefinition getActiveProcessDefinition(String key) { + return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active().singleResult(); + } + + @Override + public List getDeployments(Set ids) { + if (CollUtil.isEmpty(ids)) { + return emptyList(); + } + List list = new ArrayList<>(ids.size()); + for (String id : ids) { + addIfNotNull(list, getDeployment(id)); + } + return list; + } + + @Override + public Deployment getDeployment(String id) { + if (StrUtil.isEmpty(id)) { + return null; + } + return repositoryService.createDeploymentQuery().deploymentId(id).singleResult(); + } + + @Override + public BpmnModel getBpmnModel(String processDefinitionId) { + return repositoryService.getBpmnModel(processDefinitionId); + } + + @Override + public String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) { + // 创建 Deployment 部署 + Deployment deploy = repositoryService.createDeployment() + .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory()) + .addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes()) + .deploy(); + + // 设置 ProcessDefinition 的 category 分类 + ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult(); + repositoryService.setProcessDefinitionCategory(definition.getId(), createReqDTO.getCategory()); + // 注意 1,ProcessDefinition 的 key 和 name 是通过 BPMN 中的 的 id 和 name 决定 + // 注意 2,目前该项目的设计上,需要保证 Model、Deployment、ProcessDefinition 使用相同的 key,保证关联性。 + // 否则,会导致 ProcessDefinition 的分页无法查询到。 + if (!Objects.equals(definition.getKey(), createReqDTO.getKey())) { + throw exception(PROCESS_DEFINITION_KEY_NOT_MATCH, createReqDTO.getKey(), definition.getKey()); + } + if (!Objects.equals(definition.getName(), createReqDTO.getName())) { + throw exception(PROCESS_DEFINITION_NAME_NOT_MATCH, createReqDTO.getName(), definition.getName()); + } + + // 插入拓展表 + BpmProcessDefinitionExtDO definitionDO = BpmProcessDefinitionConvert.INSTANCE.convert2(createReqDTO) + .setProcessDefinitionId(definition.getId()); + processDefinitionMapper.insert(definitionDO); + return definition.getId(); + } + + @Override + public void updateProcessDefinitionState(String id, Integer state) { + // 激活 + if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) { + repositoryService.activateProcessDefinitionById(id, false, null); + return; + } + // 挂起 + if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) { + // suspendProcessInstances = false,进行中的任务,不进行挂起。 + // 原因:只要新的流程不允许发起即可,老流程继续可以执行。 + repositoryService.suspendProcessDefinitionById(id, false, null); + return; + } + log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state); + } + + @Override + public String getProcessDefinitionBpmnXML(String id) { + BpmnModel bpmnModel = repositoryService.getBpmnModel(id); + if (bpmnModel == null) { + return null; + } + BpmnXMLConverter converter = new BpmnXMLConverter(); + return StrUtil.utf8Str(converter.convertToXML(bpmnModel)); + } + + @Override + public boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) { + // 校验 name、description 是否更新 + ProcessDefinition oldProcessDefinition = getActiveProcessDefinition(createReqDTO.getKey()); + if (oldProcessDefinition == null) { + return false; + } + BpmProcessDefinitionExtDO oldProcessDefinitionExt = getProcessDefinitionExt(oldProcessDefinition.getId()); + if (!StrUtil.equals(createReqDTO.getName(), oldProcessDefinition.getName()) + || !StrUtil.equals(createReqDTO.getDescription(), oldProcessDefinitionExt.getDescription()) + || !StrUtil.equals(createReqDTO.getCategory(), oldProcessDefinition.getCategory())) { + return false; + } + // 校验 form 信息是否更新 + if (!ObjectUtil.equal(createReqDTO.getFormType(), oldProcessDefinitionExt.getFormType()) + || !ObjectUtil.equal(createReqDTO.getFormId(), oldProcessDefinitionExt.getFormId()) + || !ObjectUtil.equal(createReqDTO.getFormConf(), oldProcessDefinitionExt.getFormConf()) + || !ObjectUtil.equal(createReqDTO.getFormFields(), oldProcessDefinitionExt.getFormFields()) + || !ObjectUtil.equal(createReqDTO.getFormCustomCreatePath(), oldProcessDefinitionExt.getFormCustomCreatePath()) + || !ObjectUtil.equal(createReqDTO.getFormCustomViewPath(), oldProcessDefinitionExt.getFormCustomViewPath())) { + return false; + } + // 校验 BPMN XML 信息 + BpmnModel newModel = buildBpmnModel(createReqDTO.getBpmnBytes()); + BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId()); + //TODO 貌似 flowable 不修改这个也不同。需要看看。 sourceSystemId 不同 + if (equals(oldModel, newModel)) { + return false; + } + // 最终发现都一致,则返回 true + return true; + } + + /** + * 构建对应的 BPMN Model + * + * @param bpmnBytes 原始的 BPMN XML 字节数组 + * @return BPMN Model + */ + private BpmnModel buildBpmnModel(byte[] bpmnBytes) { + // 转换成 BpmnModel 对象 + BpmnXMLConverter converter = new BpmnXMLConverter(); + return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true); + } + //TODO 移出去 + public boolean equals(BpmnModel oldModel, BpmnModel newModel) { + // 由于 BpmnModel 未提供 equals 方法,所以只能转成字节数组,进行比较 + return Arrays.equals(getBpmnBytes(oldModel), getBpmnBytes(newModel)); + } + //TODO 移出去 + public byte[] getBpmnBytes(BpmnModel model) { + if (model == null) { + return new byte[0]; + } + BpmnXMLConverter converter = new BpmnXMLConverter(); + return converter.convertToXML(model); + } + + @Override + public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) { + return processDefinitionMapper.selectByProcessDefinitionId(id); + } + + @Override + public PageResult getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) { + ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery(); + if (StrUtil.isNotBlank(pageVO.getKey())) { + definitionQuery.processDefinitionKey(pageVO.getKey()); + } + + // 执行查询 + List processDefinitions = definitionQuery.orderByProcessDefinitionVersion().desc() + .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); + + if (CollUtil.isEmpty(processDefinitions)) { + return new PageResult<>(emptyList(), definitionQuery.count()); + } + // 获得 Deployment Map + Set deploymentIds = new HashSet<>(); + processDefinitions.forEach(definition -> addIfNotNull(deploymentIds, definition.getDeploymentId())); + Map deploymentMap = getDeploymentMap(deploymentIds); + + // 获得 BpmProcessDefinitionDO Map + List processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds( + convertList(processDefinitions, ProcessDefinition::getId)); + Map processDefinitionDOMap = convertMap(processDefinitionDOs, + BpmProcessDefinitionExtDO::getProcessDefinitionId); + + // 获得 Form Map + Set formIds = convertSet(processDefinitionDOs, BpmProcessDefinitionExtDO::getFormId); + Map formMap = formService.getFormMap(formIds); + + // 拼接结果 + long definitionCount = definitionQuery.count(); + return new PageResult<>(BpmProcessDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap, + processDefinitionDOMap, formMap), definitionCount); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java new file mode 100644 index 000000000..26cf938e7 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -0,0 +1,141 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; +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.mysql.definition.BpmTaskAssignRuleMapper; +import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.UserTask; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * BPM 任务分配规则 Service 实现类 + */ +@Service +@Validated +@Slf4j +public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ + + @Resource + private BpmTaskAssignRuleMapper taskRuleMapper; + + @Resource + @Lazy // 解决循环依赖 + private BpmModelService modelService; + + @Resource + private BpmProcessDefinitionService processDefinitionService; + + @Override + public List getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId, String taskDefinitionKey) { + return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey); + } + + @Override + public List getTaskAssignRuleListByModelId(String modelId) { + return taskRuleMapper.selectListByModelId(modelId); + } + + @Override + public List getTaskAssignRuleList(String modelId, String processDefinitionId) { + // 获得规则 + List rules = Collections.emptyList(); + BpmnModel model = null; + if (StrUtil.isNotEmpty(modelId)) { + rules = getTaskAssignRuleListByModelId(modelId); + model = modelService.getBpmnModel(modelId); + } else if (StrUtil.isNotEmpty(processDefinitionId)) { + rules = getTaskAssignRuleListByProcessDefinitionId(processDefinitionId, null); + model = processDefinitionService.getBpmnModel(processDefinitionId); + } + if (model == null) { + return Collections.emptyList(); + } + + // 获得用户任务,只有用户任务才可以设置分配规则 + List userTasks = getBpmnModelElements(model, UserTask.class); + if (CollUtil.isEmpty(userTasks)) { + return Collections.emptyList(); + } + + // 转换数据 + return BpmTaskAssignRuleConvert.INSTANCE.convertList(userTasks, rules); + } + + /** + * TODO 需要移出去 + * 获得 BPMN 流程中,指定的元素们 + * + * @param model + * @param clazz 指定元素。例如说,{@link org.flowable.bpmn.model.UserTask}、{@link org.flowable.bpmn.model.Gateway} 等等 + * @return 元素们 + */ + public static List getBpmnModelElements(BpmnModel model, Class clazz) { + List result = new ArrayList<>(); + model.getProcesses().forEach(process -> { + process.getFlowElements().forEach(flowElement -> { + if (flowElement.getClass().isAssignableFrom(clazz)) { + result.add((T) flowElement); + } + }); + }); + return result; + } + + @Override + public Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO) { + return null; + } + + @Override + public void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO) { + + } + + @Override + public boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId) { + // 调用 VO 接口的原因是,过滤掉流程模型不需要的规则,保持和 copyTaskAssignRules 方法的一致性 + List modelRules = getTaskAssignRuleList(modelId, null); + List processInstanceRules = getTaskAssignRuleList(null, processDefinitionId); + if (modelRules.size() != processInstanceRules.size()) { + return false; + } + + // 遍历,匹配对应的规则 + Map processInstanceRuleMap = CollectionUtils.convertMap(processInstanceRules, + BpmTaskAssignRuleRespVO::getTaskDefinitionKey); + for (BpmTaskAssignRuleRespVO modelRule : modelRules) { + BpmTaskAssignRuleRespVO processInstanceRule = processInstanceRuleMap.get(modelRule.getTaskDefinitionKey()); + if (processInstanceRule == null) { + return false; + } + if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType()) + || !ObjectUtil.equal(modelRule.getOptions(), processInstanceRule.getOptions())) { + return false; + } + } + return true; + } + + @Override + public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) { + + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelService.java deleted file mode 100644 index bbc304d33..000000000 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableModelService.java +++ /dev/null @@ -1,10 +0,0 @@ -package cn.iocoder.yudao.module.bpm.service.definition; - -/** - * Flowable流程模型接口 - * - * @author yunlongn - */ -public interface FlowableModelService extends BpmModelCommonService { - -} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java deleted file mode 100644 index f205d3249..000000000 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/FlowableProcessDefinitionServiceImpl.java +++ /dev/null @@ -1,136 +0,0 @@ -package cn.iocoder.yudao.module.bpm.service.definition; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert; -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; -import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper; -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; -import lombok.extern.slf4j.Slf4j; -import org.flowable.common.engine.impl.db.SuspensionState; -import org.flowable.engine.RepositoryService; -import org.flowable.engine.repository.Deployment; -import org.flowable.engine.repository.ProcessDefinition; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.addIfNotNull; -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH; -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH; -import static java.util.Collections.emptyList; - -/** - * 流程定义实现 - * 主要进行 Flowable {@link ProcessDefinition} 和 {@link Deployment} 的维护 - * - * @author yunlongn - * @author ZJQ - * @author 芋道源码 - */ -@Service -@Validated -@Slf4j -public class FlowableProcessDefinitionServiceImpl implements FlowableProcessDefinitionService { - - private static final String BPMN_FILE_SUFFIX = ".bpmn"; - - @Resource - private RepositoryService repositoryService; - - @Resource - private BpmProcessDefinitionExtMapper processDefinitionMapper; - - @Override - public ProcessDefinition getProcessDefinition(String id) { - return repositoryService.getProcessDefinition(id); - } - - @Override - public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) { - if (StrUtil.isEmpty(deploymentId)) { - return null; - } - return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult(); - } - - @Override - public List getProcessDefinitionListByDeploymentIds(Set deploymentIds) { - if (CollUtil.isEmpty(deploymentIds)) { - return emptyList(); - } - return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list(); - } - - @Override - public List getDeployments(Set ids) { - if (CollUtil.isEmpty(ids)) { - return emptyList(); - } - List list = new ArrayList<>(ids.size()); - for (String id : ids) { - addIfNotNull(list, getDeployment(id)); - } - return list; - } - - @Override - public Deployment getDeployment(String id) { - if (StrUtil.isEmpty(id)) { - return null; - } - return repositoryService.createDeploymentQuery().deploymentId(id).singleResult(); - } - - @Override - public String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) { - // 创建 Deployment 部署 - Deployment deploy = repositoryService.createDeployment() - .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory()) - .addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes()) - .deploy(); - - // 设置 ProcessDefinition 的 category 分类 - ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult(); - repositoryService.setProcessDefinitionCategory(definition.getId(), createReqDTO.getCategory()); - // 注意 1,ProcessDefinition 的 key 和 name 是通过 BPMN 中的 的 id 和 name 决定 - // 注意 2,目前该项目的设计上,需要保证 Model、Deployment、ProcessDefinition 使用相同的 key,保证关联性。 - // 否则,会导致 ProcessDefinition 的分页无法查询到。 - if (!Objects.equals(definition.getKey(), createReqDTO.getKey())) { - throw exception(PROCESS_DEFINITION_KEY_NOT_MATCH, createReqDTO.getKey(), definition.getKey()); - } - if (!Objects.equals(definition.getName(), createReqDTO.getName())) { - throw exception(PROCESS_DEFINITION_NAME_NOT_MATCH, createReqDTO.getName(), definition.getName()); - } - - // 插入拓展表 - BpmProcessDefinitionExtDO definitionDO = BpmProcessDefinitionConvert.INSTANCE.convert2(createReqDTO) - .setProcessDefinitionId(definition.getId()); - processDefinitionMapper.insert(definitionDO); - return definition.getId(); - } - - @Override - public void updateProcessDefinitionState(String id, Integer state) { - // 激活 - if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) { - repositoryService.activateProcessDefinitionById(id, false, null); - return; - } - // 挂起 - if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) { - // suspendProcessInstances = false,进行中的任务,不进行挂起。 - // 原因:只要新的流程不允许发起即可,老流程继续可以执行。 - repositoryService.suspendProcessDefinitionById(id, false, null); - return; - } - log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state); - } -} From d64555697f867a89c88365bc80c3b75c310a47ba Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Fri, 11 Feb 2022 11:32:46 +0800 Subject: [PATCH 05/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E6=A8=A1=E5=9E=8B=EF=BC=8C=20=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E5=AE=9A=E4=B9=89=20=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BpmTaskAssignRuleController.http | 0 .../BpmTaskAssignRuleController.java | 4 +- .../definition/BpmAbstractModelService.java | 82 -------------- .../service/definition/BpmFormService.java | 8 ++ .../definition/BpmFormServiceImpl.java | 34 +++++- .../definition/BpmModelCommonService.java | 69 ------------ .../BpmProcessDefinitionCommonService.java | 69 ------------ .../definition/BpmTaskAssignRuleService.java | 8 ++ .../service/definition/BpmModelService.java | 55 +++++++++- .../definition/BpmModelServiceImpl.java | 43 ++++++-- .../BpmProcessDefinitionService.java | 50 ++++++++- .../BpmTaskAssignRuleServiceImpl.java | 15 +++ .../definition/BpmTaskAssignRuleConvert.java | 8 ++ .../service/definition/BpmModelService.java | 59 +++++++++- .../definition/BpmModelServiceImpl.java | 66 +++++++++--- .../BpmProcessDefinitionService.java | 56 +++++++++- .../BpmTaskAssignRuleServiceImpl.java | 101 ++++++++++++++++-- 17 files changed, 466 insertions(+), 261 deletions(-) rename yudao-module-bpm/{yudao-module-bpm-impl-activiti => yudao-module-bpm-base}/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http (100%) rename yudao-module-bpm/{yudao-module-bpm-impl-activiti => yudao-module-bpm-base}/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java (97%) delete mode 100644 yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java delete mode 100644 yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java delete mode 100644 yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionCommonService.java diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http similarity index 100% rename from yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http rename to yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java similarity index 97% rename from yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java rename to yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java index 1be0b7487..b51a4661b 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -32,7 +32,7 @@ public class BpmTaskAssignRuleController { @ApiOperation(value = "获得任务分配规则列表") @ApiImplicitParams({ @ApiImplicitParam(name = "modelId", value = "模型编号", example = "1024", dataTypeClass = String.class), - @ApiImplicitParam(name = "processDefinitionId", value = "刘晨定义的编号", example = "2048", dataTypeClass = String.class) + @ApiImplicitParam(name = "processDefinitionId", value = "流程定义的编号", example = "2048", dataTypeClass = String.class) }) @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')") public CommonResult> getTaskAssignRuleList( diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java deleted file mode 100644 index caa8e1399..000000000 --- a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmAbstractModelService.java +++ /dev/null @@ -1,82 +0,0 @@ -package cn.iocoder.yudao.module.bpm.service.definition; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; -import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; - -import java.util.List; -import java.util.Objects; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; -/** - * 流程模型通用抽象类 - * Activiti 和 flowable 通用的流程模型抽象类, Activiti 和 flowable 两边通用的方法 - * - * @author yunlongn - * @author jason - */ -public abstract class BpmAbstractModelService { - - protected final BpmFormService bpmFormService; - - protected final BpmTaskAssignRuleService taskAssignRuleService; - - public BpmAbstractModelService(BpmFormService bpmFormService,BpmTaskAssignRuleService taskAssignRuleService) { - this.bpmFormService = bpmFormService; - this.taskAssignRuleService = taskAssignRuleService; - } - - /** - * 校验流程表单已配置 - * - * @param metaInfoStr 流程模型 metaInfo 字段 - * @return 流程表单 - */ - protected BpmFormDO checkFormConfig(String metaInfoStr) { - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(metaInfoStr, BpmModelMetaInfoRespDTO.class); - if (metaInfo == null || metaInfo.getFormType() == null) { - throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG); - } - // 校验表单存在 - if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) { - BpmFormDO form = bpmFormService.getForm(metaInfo.getFormId()); - if (form == null) { - throw exception(FORM_NOT_EXISTS); - } - return form; - } - return null; - } - - /** - * 校验流程模型的任务分配规则全部都配置了 - * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去! - * - * @param id 流程模型编号 - */ - protected void checkTaskAssignRuleAllConfig(String id) { - // 一个用户任务都没配置,所以无需配置规则 - List taskAssignRules = taskAssignRuleService.getTaskAssignRuleList(id, null); - if (CollUtil.isEmpty(taskAssignRules)) { - return; - } - // 校验未配置规则的任务 - taskAssignRules.forEach(rule -> { - if (CollUtil.isEmpty(rule.getOptions())) { - throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName()); - } - }); - } - - - protected void checkKeyNCName(String key) { - if (!ValidationUtils.isXmlNCName(key)) { - throw exception(MODEL_KEY_VALID); - } - } -} diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java index a90fc9760..80355ef5e 100644 --- a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java @@ -88,4 +88,12 @@ public interface BpmFormService { */ PageResult getFormPage(BpmFormPageReqVO pageReqVO); + /** + * 校验流程表单已配置 + * + * @param configStr configStr 字段 + * @return 流程表单 + */ + BpmFormDO checkFormConfig(String configStr); + } diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java index 42f1b145c..d64684b82 100644 --- a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.bpm.service.definition; import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO; @@ -8,18 +9,20 @@ 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.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; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 动态表单 Service 实现类 @@ -87,6 +90,29 @@ public class BpmFormServiceImpl implements BpmFormService { return formMapper.selectPage(pageReqVO); } + + @Override + public BpmFormDO checkFormConfig(String configStr) { + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(configStr, BpmModelMetaInfoRespDTO.class); + if (metaInfo == null || metaInfo.getFormType() == null) { + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG); + } + // 校验表单存在 + if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) { + BpmFormDO form = getForm(metaInfo.getFormId()); + if (form == null) { + throw exception(FORM_NOT_EXISTS); + } + return form; + } + return null; + } + + private void checkKeyNCName(String key) { + if (!ValidationUtils.isXmlNCName(key)) { + throw exception(MODEL_KEY_VALID); + } + } /** * 校验 Field,避免 field 重复 * diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java deleted file mode 100644 index a634a02d7..000000000 --- a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelCommonService.java +++ /dev/null @@ -1,69 +0,0 @@ -package cn.iocoder.yudao.module.bpm.service.definition; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; - -import javax.validation.Valid; - -/** - * 流程模型通用接口 - * Activiti 和 flowable 通用的流程模型接口 - * - * @author yunlongn - * @author jason - */ -public interface BpmModelCommonService { - /** - * 获得流程模型分页 - * - * @param pageVO 分页查询 - * @return 流程模型分页 - */ - PageResult getModelPage(BpmModelPageReqVO pageVO); - - /** - * 创建流程模型 - * - * @param modelVO 创建信息 - * @param bpmnXml BPMN XML - * @return 创建的流程模型的编号 - */ - String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml); - - /** - * 获得流程模块 - * - * @param id 编号 - * @return 流程模型 - */ - BpmModelRespVO getModel(String id); - - /** - * 修改流程模型 - * - * @param updateReqVO 更新信息 - */ - void updateModel(@Valid BpmModelUpdateReqVO updateReqVO); - - /** - * 将流程模型,部署成一个流程定义 - * - * @param id 编号 - */ - void deployModel(String id); - - /** - * 删除模型 - * - * @param id 编号 - */ - void deleteModel(String id); - - /** - * 修改模型的状态,实际更新的部署的流程定义的状态 - * - * @param id 编号 - * @param state 状态 - */ - void updateModelState(String id, Integer state); -} diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionCommonService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionCommonService.java deleted file mode 100644 index 51a2ee424..000000000 --- a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionCommonService.java +++ /dev/null @@ -1,69 +0,0 @@ -package cn.iocoder.yudao.module.bpm.service.definition; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; - -import javax.validation.Valid; - -/** - * 流程定义通用接口 - * Activiti 和 flowable 通用的流程定义接口 - * - * @author yunlong.li - * @author ZJQ - * @author 芋道源码 - * @author jason - */ -public interface BpmProcessDefinitionCommonService { - - /** - * 获得流程定义分页 - * - * @param pageReqVO 分页入参 - * @return 流程定义 Page - */ - PageResult getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO); - - /** - * 创建流程定义 - * - * @param createReqDTO 创建信息 - * @return 流程编号 - */ - String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); - - /** - * 更新流程定义状态 - * - * @param id 流程定义的编号 - * @param state 状态 - */ - void updateProcessDefinitionState(String id, Integer state); - - /** - * 获得流程定义对应的 BPMN XML - * - * @param id 流程定义编号 - * @return BPMN XML - */ - String getProcessDefinitionBpmnXML(String id); - - /** - * 获得需要创建的流程定义,是否和当前激活的流程定义相等 - * - * @param createReqDTO 创建信息 - * @return 是否相等 - */ - boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); - - /** - * 获得编号对应的 BpmProcessDefinitionExtDO - * - * @param id 编号 - * @return 流程定义拓展 - */ - BpmProcessDefinitionExtDO getProcessDefinitionExt(String id); -} diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java index 19e7f9684..079451597 100644 --- a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java +++ b/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java @@ -76,4 +76,12 @@ public interface BpmTaskAssignRuleService { */ void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId); + /** + * 校验流程模型的任务分配规则全部都配置了 + * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去! + * + * @param id 流程模型编号 + */ + void checkTaskAssignRuleAllConfig(String id); + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java index 1203f060a..fea5398a7 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java @@ -11,7 +11,60 @@ import javax.validation.Valid; * * @author yunlongn */ -public interface BpmModelService extends BpmModelCommonService { +public interface BpmModelService { + /** + * 获得流程模型分页 + * + * @param pageVO 分页查询 + * @return 流程模型分页 + */ + PageResult getModelPage(BpmModelPageReqVO pageVO); + + /** + * 创建流程模型 + * + * @param modelVO 创建信息 + * @param bpmnXml BPMN XML + * @return 创建的流程模型的编号 + */ + String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml); + + /** + * 获得流程模块 + * + * @param id 编号 + * @return 流程模型 + */ + BpmModelRespVO getModel(String id); + + /** + * 修改流程模型 + * + * @param updateReqVO 更新信息 + */ + void updateModel(@Valid BpmModelUpdateReqVO updateReqVO); + + /** + * 将流程模型,部署成一个流程定义 + * + * @param id 编号 + */ + void deployModel(String id); + + /** + * 删除模型 + * + * @param id 编号 + */ + void deleteModel(String id); + + /** + * 修改模型的状态,实际更新的部署的流程定义的状态 + * + * @param id 编号 + * @param state 状态 + */ + void updateModelState(String id, Integer state); /** * 获得流程模型编号对应的 BPMN Model diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java index 4387199d4..319f732d7 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java @@ -3,8 +3,10 @@ package cn.iocoder.yudao.module.bpm.service.definition; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; +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.enums.definition.BpmModelFormTypeEnum; import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -45,17 +47,16 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; @Service @Validated @Slf4j -public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmModelService { +public class BpmModelServiceImpl implements BpmModelService { @Resource private RepositoryService repositoryService; - @Resource private BpmProcessDefinitionService processDefinitionService; - - public BpmModelServiceImpl(BpmFormService bpmFormService,BpmTaskAssignRuleService taskAssignRuleService) { - super(bpmFormService, taskAssignRuleService); - } + @Resource + private BpmFormService bpmFormService; + @Resource + private BpmTaskAssignRuleService taskAssignRuleService; @Override public PageResult getModelPage(BpmModelPageReqVO pageVO) { @@ -167,7 +168,7 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM // 校验表单已配 BpmFormDO form = checkFormConfig(model.getMetaInfo()); // 校验任务分配规则已配置 - checkTaskAssignRuleAllConfig(id); + taskAssignRuleService.checkTaskAssignRuleAllConfig(id); // 校验模型是否发生修改。如果未修改,则不允许创建 BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes); @@ -247,4 +248,32 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM return repositoryService.createModelQuery().modelKey(key).singleResult(); } + private void checkKeyNCName(String key) { + if (!ValidationUtils.isXmlNCName(key)) { + throw exception(MODEL_KEY_VALID); + } + } + + /** + * 校验流程表单已配置 + * + * @param metaInfoStr 流程模型 metaInfo 字段 + * @return 流程表单 + */ + private BpmFormDO checkFormConfig(String metaInfoStr) { + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(metaInfoStr, BpmModelMetaInfoRespDTO.class); + if (metaInfo == null || metaInfo.getFormType() == null) { + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG); + } + // 校验表单存在 + if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) { + BpmFormDO form = bpmFormService.getForm(metaInfo.getFormId()); + if (form == null) { + throw exception(FORM_NOT_EXISTS); + } + return form; + } + return null; + } + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java index 58bba1f6c..46be4b64f 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java @@ -24,7 +24,55 @@ import java.util.Set; * @author ZJQ * @author 芋道源码 */ -public interface BpmProcessDefinitionService extends BpmProcessDefinitionCommonService { +public interface BpmProcessDefinitionService { + + /** + * 获得流程定义分页 + * + * @param pageReqVO 分页入参 + * @return 流程定义 Page + */ + PageResult getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO); + + /** + * 创建流程定义 + * + * @param createReqDTO 创建信息 + * @return 流程编号 + */ + String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); + + /** + * 更新流程定义状态 + * + * @param id 流程定义的编号 + * @param state 状态 + */ + void updateProcessDefinitionState(String id, Integer state); + + /** + * 获得流程定义对应的 BPMN XML + * + * @param id 流程定义编号 + * @return BPMN XML + */ + String getProcessDefinitionBpmnXML(String id); + + /** + * 获得需要创建的流程定义,是否和当前激活的流程定义相等 + * + * @param createReqDTO 创建信息 + * @return 是否相等 + */ + boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); + + /** + * 获得编号对应的 BpmProcessDefinitionExtDO + * + * @param id 编号 + * @return 流程定义拓展 + */ + BpmProcessDefinitionExtDO getProcessDefinitionExt(String id); /** * 获得流程定义列表 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index 2f4eaa310..93eedb514 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -173,6 +173,21 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { taskRuleMapper.insertBatch(newRules); } + @Override + public void checkTaskAssignRuleAllConfig(String id) { + // 一个用户任务都没配置,所以无需配置规则 + List taskAssignRules = getTaskAssignRuleList(id, null); + if (CollUtil.isEmpty(taskAssignRules)) { + return; + } + // 校验未配置规则的任务 + taskAssignRules.forEach(rule -> { + if (CollUtil.isEmpty(rule.getOptions())) { + throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName()); + } + }); + } + private void validTaskAssignRuleOptions(Integer type, Set options) { if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) { roleApi.validRoles(options); diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java index 992fa0b86..c616e90b0 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.bpm.convert.definition; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; import org.flowable.bpmn.model.UserTask; import org.mapstruct.Mapper; @@ -29,4 +31,10 @@ public interface BpmTaskAssignRuleConvert { } BpmTaskAssignRuleRespVO convert(BpmTaskAssignRuleDO bean); + + BpmTaskAssignRuleDO convert(BpmTaskAssignRuleCreateReqVO bean); + + BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean); + + List convertList2(List list); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java index 9bd455191..a4e4f83d1 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java @@ -1,13 +1,70 @@ package cn.iocoder.yudao.module.bpm.service.definition; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; import org.flowable.bpmn.model.BpmnModel; +import javax.validation.Valid; + /** * Flowable流程模型接口 * * @author yunlongn */ -public interface BpmModelService extends BpmModelCommonService { +public interface BpmModelService { + /** + * 获得流程模型分页 + * + * @param pageVO 分页查询 + * @return 流程模型分页 + */ + PageResult getModelPage(BpmModelPageReqVO pageVO); + + /** + * 创建流程模型 + * + * @param modelVO 创建信息 + * @param bpmnXml BPMN XML + * @return 创建的流程模型的编号 + */ + String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml); + + /** + * 获得流程模块 + * + * @param id 编号 + * @return 流程模型 + */ + BpmModelRespVO getModel(String id); + + /** + * 修改流程模型 + * + * @param updateReqVO 更新信息 + */ + void updateModel(@Valid BpmModelUpdateReqVO updateReqVO); + + /** + * 将流程模型,部署成一个流程定义 + * + * @param id 编号 + */ + void deployModel(String id); + + /** + * 删除模型 + * + * @param id 编号 + */ + void deleteModel(String id); + + /** + * 修改模型的状态,实际更新的部署的流程定义的状态 + * + * @param id 编号 + * @param state 状态 + */ + void updateModelState(String id, Integer state); /** * 获得流程模型编号对应的 BPMN Model diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java index a1558d681..7c4e0b208 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java @@ -6,9 +6,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; +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.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; @@ -45,16 +47,16 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; @Service @Validated @Slf4j -public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmModelService { +public class BpmModelServiceImpl implements BpmModelService { @Resource private RepositoryService repositoryService; @Resource private BpmProcessDefinitionService processDefinitionService; - - public BpmModelServiceImpl(BpmFormService bpmFormService, BpmTaskAssignRuleService taskAssignRuleService){ - super(bpmFormService, taskAssignRuleService); - } + @Resource + private BpmFormService bpmFormService; + @Resource + private BpmTaskAssignRuleService taskAssignRuleService; @Override public PageResult getModelPage(BpmModelPageReqVO pageVO) { @@ -161,7 +163,7 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM // 校验表单已配 BpmFormDO form = checkFormConfig(model.getMetaInfo()); //校验任务分配规则已配置 - checkTaskAssignRuleAllConfig(id); + taskAssignRuleService.checkTaskAssignRuleAllConfig(id); BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes); //校验模型是否发生修改。如果未修改,则不允许创建 @@ -182,8 +184,8 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM model.setDeploymentId(definition.getDeploymentId()); repositoryService.saveModel(model); - //TODO 复制任务分配规则 - //taskAssignRuleService.copyTaskAssignRules(id, definition.getId()); + //复制任务分配规则 + taskAssignRuleService.copyTaskAssignRules(id, definition.getId()); } @@ -218,6 +220,44 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM processDefinitionService.updateProcessDefinitionState(definition.getId(), state); } + @Override + public BpmnModel getBpmnModel(String id) { + byte[] bpmnBytes = repositoryService.getModelEditorSource(id); + if (ArrayUtil.isEmpty(bpmnBytes)) { + return null; + } + BpmnXMLConverter converter = new BpmnXMLConverter(); + return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true); + } + + private void checkKeyNCName(String key) { + if (!ValidationUtils.isXmlNCName(key)) { + throw exception(MODEL_KEY_VALID); + } + } + + /** + * 校验流程表单已配置 + * + * @param metaInfoStr 流程模型 metaInfo 字段 + * @return 流程表单 + */ + private BpmFormDO checkFormConfig(String metaInfoStr) { + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(metaInfoStr, BpmModelMetaInfoRespDTO.class); + if (metaInfo == null || metaInfo.getFormType() == null) { + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG); + } + // 校验表单存在 + if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) { + BpmFormDO form = bpmFormService.getForm(metaInfo.getFormId()); + if (form == null) { + throw exception(FORM_NOT_EXISTS); + } + return form; + } + return null; + } + private void saveModelBpmnXml(Model model, String bpmnXml) { if (StrUtil.isEmpty(bpmnXml)) { return; @@ -240,13 +280,5 @@ public class BpmModelServiceImpl extends BpmAbstractModelService implements BpmM processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode()); } - @Override - public BpmnModel getBpmnModel(String id) { - byte[] bpmnBytes = repositoryService.getModelEditorSource(id); - if (ArrayUtil.isEmpty(bpmnBytes)) { - return null; - } - BpmnXMLConverter converter = new BpmnXMLConverter(); - return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true); - } + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java index 121bdc220..51bc807fb 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java @@ -1,10 +1,16 @@ package cn.iocoder.yudao.module.bpm.service.definition; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import org.flowable.bpmn.model.BpmnModel; import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.ProcessDefinition; +import javax.validation.Valid; import java.util.List; import java.util.Map; import java.util.Set; @@ -15,7 +21,55 @@ import java.util.Set; * @author ZJQ * @author 芋道源码 */ -public interface BpmProcessDefinitionService extends BpmProcessDefinitionCommonService { +public interface BpmProcessDefinitionService { + + /** + * 获得流程定义分页 + * + * @param pageReqVO 分页入参 + * @return 流程定义 Page + */ + PageResult getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO); + + /** + * 创建流程定义 + * + * @param createReqDTO 创建信息 + * @return 流程编号 + */ + String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); + + /** + * 更新流程定义状态 + * + * @param id 流程定义的编号 + * @param state 状态 + */ + void updateProcessDefinitionState(String id, Integer state); + + /** + * 获得流程定义对应的 BPMN XML + * + * @param id 流程定义编号 + * @return BPMN XML + */ + String getProcessDefinitionBpmnXML(String id); + + /** + * 获得需要创建的流程定义,是否和当前激活的流程定义相等 + * + * @param createReqDTO 创建信息 + * @return 是否相等 + */ + boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); + + /** + * 获得编号对应的 BpmProcessDefinitionExtDO + * + * @param id 编号 + * @return 流程定义拓展 + */ + BpmProcessDefinitionExtDO getProcessDefinitionExt(String id); /** * 获得编号对应的 ProcessDefinition diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index 26cf938e7..7b375e36a 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -4,12 +4,20 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; 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.mysql.definition.BpmTaskAssignRuleMapper; +import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.system.api.dept.DeptApi; +import cn.iocoder.yudao.module.system.api.dept.PostApi; +import cn.iocoder.yudao.module.system.api.dict.DictDataApi; +import cn.iocoder.yudao.module.system.api.permission.RoleApi; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.model.BpmnModel; import org.flowable.bpmn.model.FlowElement; @@ -20,10 +28,10 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * BPM 任务分配规则 Service 实现类 @@ -35,13 +43,23 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ @Resource private BpmTaskAssignRuleMapper taskRuleMapper; - @Resource @Lazy // 解决循环依赖 private BpmModelService modelService; - @Resource private BpmProcessDefinitionService processDefinitionService; + @Resource + private BpmUserGroupService userGroupService; + @Resource + private RoleApi roleApi; + @Resource + private DeptApi deptApi; + @Resource + private PostApi postApi; + @Resource + private AdminUserApi adminUserApi; + @Resource + private DictDataApi dictDataApi; @Override public List getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId, String taskDefinitionKey) { @@ -101,12 +119,38 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ @Override public Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO) { - return null; + // 校验参数 + validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions()); + // 校验是否已经配置 + BpmTaskAssignRuleDO existRule = taskRuleMapper.selectListByModelIdAndTaskDefinitionKey( + reqVO.getModelId(), reqVO.getTaskDefinitionKey()); + if (existRule != null) { + throw exception(TASK_ASSIGN_RULE_EXISTS, reqVO.getModelId(), reqVO.getTaskDefinitionKey()); + } + + // 存储 + BpmTaskAssignRuleDO rule = BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO) + .setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建 + taskRuleMapper.insert(rule); + return rule.getId(); } @Override public void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO) { + // 校验参数 + validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions()); + // 校验是否存在 + BpmTaskAssignRuleDO existRule = taskRuleMapper.selectById(reqVO.getId()); + if (existRule == null) { + throw exception(TASK_ASSIGN_RULE_NOT_EXISTS); + } + // 只允许修改流程模型的规则 + if (!Objects.equals(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL, existRule.getProcessDefinitionId())) { + throw exception(TASK_UPDATE_FAIL_NOT_MODEL); + } + // 执行更新 + taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO)); } @Override @@ -136,6 +180,49 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ @Override public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) { + List rules = getTaskAssignRuleList(fromModelId, null); + if (CollUtil.isEmpty(rules)) { + return; + } + // 开始复制 + List newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules); + newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null) + .setCreateTime(null).setUpdateTime(null)); + taskRuleMapper.insertBatch(newRules); + } + @Override + public void checkTaskAssignRuleAllConfig(String id) { + // 一个用户任务都没配置,所以无需配置规则 + List taskAssignRules = getTaskAssignRuleList(id, null); + if (CollUtil.isEmpty(taskAssignRules)) { + return; + } + // 校验未配置规则的任务 + taskAssignRules.forEach(rule -> { + if (CollUtil.isEmpty(rule.getOptions())) { + throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName()); + } + }); + } + + private void validTaskAssignRuleOptions(Integer type, Set options) { + if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) { + roleApi.validRoles(options); + } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), + BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) { + deptApi.validDepts(options); + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) { + postApi.validPosts(options); + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER.getType())) { + adminUserApi.validUsers(options); + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_GROUP.getType())) { + userGroupService.validUserGroups(options); + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) { + dictDataApi.validDictDatas(DictTypeConstants.TASK_ASSIGN_SCRIPT, + CollectionUtils.convertSet(options, String::valueOf)); + } else { + throw new IllegalArgumentException(StrUtil.format("未知的规则类型({})", type)); + } } } From c761f5258a2a4bbc5dadb871de8d7ad216e1fa56 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Fri, 11 Feb 2022 21:54:39 +0800 Subject: [PATCH 06/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E5=AE=9E=E4=BE=8B=20=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BpmTaskAssignRuleController.http | 0 .../BpmTaskAssignRuleController.java | 0 .../definition/BpmTaskAssignRuleService.java | 0 .../BpmProcessDefinitionController.java | 12 ++ .../BpmTaskAssignRuleController.java | 59 +++++++ .../task/BpmProcessInstanceController.java | 53 ++++++ .../admin/task/BpmTaskController.java | 39 ++++ .../BpmProcessDefinitionConvert.java | 21 +++ .../task/BpmProcessInstanceConvert.java | 76 ++++++++ .../bpm/convert/task/BpmTaskConvert.java | 68 +++++++ .../BpmProcessDefinitionService.java | 10 ++ .../BpmProcessDefinitionServiceImpl.java | 25 +++ .../definition/BpmTaskAssignRuleService.java | 87 +++++++++ .../task/BpmProcessInstanceService.java | 76 ++++++++ .../task/BpmProcessInstanceServiceImpl.java | 167 ++++++++++++++++++ .../bpm/service/task/BpmTaskService.java | 47 +++++ .../bpm/service/task/BpmTaskServiceImpl.java | 82 +++++++++ 17 files changed, 822 insertions(+) rename yudao-module-bpm/{yudao-module-bpm-base => yudao-module-bpm-impl-activiti}/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http (100%) rename yudao-module-bpm/{yudao-module-bpm-base => yudao-module-bpm-impl-activiti}/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java (100%) rename yudao-module-bpm/{yudao-module-bpm-base => yudao-module-bpm-impl-activiti}/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java (100%) create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http similarity index 100% rename from yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http rename to yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java similarity index 100% rename from yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java rename to yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java diff --git a/yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java similarity index 100% rename from yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java rename to yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java index 2d6ddc0b0..ebcaad05b 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java @@ -2,8 +2,10 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; @@ -17,6 +19,8 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.util.List; + import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @Api(tags = "管理后台 - 流程定义") @@ -36,6 +40,14 @@ public class BpmProcessDefinitionController { return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO)); } + @GetMapping ("/list") + @ApiOperation(value = "获得流程定义列表") + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')") + public CommonResult> getProcessDefinitionList( + BpmProcessDefinitionListReqVO listReqVO) { + return success(bpmDefinitionService.getProcessDefinitionList(listReqVO)); + } + @GetMapping ("/get-bpmn-xml") @ApiOperation(value = "获得流程定义的 BPMN XML") @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java new file mode 100644 index 000000000..b51a4661b --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java @@ -0,0 +1,59 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.definition; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Api(tags = "管理后台 - 任务分配规则") +@RestController +@RequestMapping("/bpm/task-assign-rule") +@Validated +public class BpmTaskAssignRuleController { + + @Resource + private BpmTaskAssignRuleService taskAssignRuleService; + + @GetMapping("/list") + @ApiOperation(value = "获得任务分配规则列表") + @ApiImplicitParams({ + @ApiImplicitParam(name = "modelId", value = "模型编号", example = "1024", dataTypeClass = String.class), + @ApiImplicitParam(name = "processDefinitionId", value = "流程定义的编号", example = "2048", dataTypeClass = String.class) + }) + @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')") + public CommonResult> getTaskAssignRuleList( + @RequestParam(value = "modelId", required = false) String modelId, + @RequestParam(value = "processDefinitionId", required = false) String processDefinitionId) { + return success(taskAssignRuleService.getTaskAssignRuleList(modelId, processDefinitionId)); + } + + @PostMapping("/create") + @ApiOperation(value = "创建任务分配规则") + @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:create')") + public CommonResult createTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleCreateReqVO reqVO) { + return success(taskAssignRuleService.createTaskAssignRule(reqVO)); + } + + @PutMapping("/update") + @ApiOperation(value = "更新任务分配规则") + @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:update')") + public CommonResult updateTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleUpdateReqVO reqVO) { + taskAssignRuleService.updateTaskAssignRule(reqVO); + return success(true); + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java new file mode 100644 index 000000000..93e1f2fb6 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.task; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Api(tags = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请” +@RestController +@RequestMapping("/bpm/process-instance") +@Validated +public class BpmProcessInstanceController { + @Resource + private BpmProcessInstanceService processInstanceService; + + @GetMapping("/my-page") + @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用") + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") + public CommonResult> getMyProcessInstancePage( + @Valid BpmProcessInstanceMyPageReqVO pageReqVO) { + return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO)); + } + + @PostMapping("/create") + @ApiOperation("新建流程实例") + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") + public CommonResult createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) { + return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO)); + } + + @GetMapping("/get") + @ApiOperation(value = "获得指定流程实例", notes = "在【流程详细】界面中,进行调用") + @ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class) + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") + public CommonResult getProcessInstance(@RequestParam("id") String id) { + return success(processInstanceService.getProcessInstanceVO(id)); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java new file mode 100644 index 000000000..05c2fe958 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.task; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageReqVO; +import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.engine.TaskService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; + +@Api(tags = "管理后台 - 流程任务实例") +@RestController +@RequestMapping("/bpm/task") +@Validated +public class BpmTaskController { + + @Resource + private BpmTaskService taskService; + + @GetMapping("todo-page") + @ApiOperation("获取 Todo 待办任务分页") + @PreAuthorize("@ss.hasPermission('bpm:task:query')") + public CommonResult> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) { + return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO)); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java index 5e8168369..8f5bfcd26 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java @@ -12,6 +12,7 @@ import org.flowable.engine.repository.ProcessDefinition; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; +import org.mapstruct.Named; import org.mapstruct.factory.Mappers; import java.util.List; @@ -41,6 +42,26 @@ public interface BpmProcessDefinitionConvert { }); } + default List convertList3(List list, + Map processDefinitionDOMap) { + return CollectionUtils.convertList(list, processDefinition -> { + BpmProcessDefinitionRespVO respVO = convert3(processDefinition); + BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId()); + // 复制通用属性 + copyTo(processDefinitionExtDO, respVO); + return respVO; + }); + } + + @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState") + BpmProcessDefinitionRespVO convert3(ProcessDefinition bean); + + @Named("convertSuspendedToSuspensionState") + default Integer convertSuspendedToSuspensionState(boolean suspended) { + return suspended ? SuspensionState.SUSPENDED.getStateCode() : + SuspensionState.ACTIVE.getStateCode(); + } + default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment, BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) { BpmProcessDefinitionPageItemRespVO respVO = convert(bean); diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java new file mode 100644 index 000000000..4f0e71f9e --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.bpm.convert.task; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import org.flowable.engine.history.HistoricProcessInstance; +import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.task.api.Task; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +import java.util.List; +import java.util.Map; + +/** + * 流程实例 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface BpmProcessInstanceConvert { + + BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class); + + default PageResult convertPage(PageResult page, + Map> taskMap) { + List list = convertList(page.getList()); + list.forEach(respVO -> respVO.setTasks(convertList2(taskMap.get(respVO.getId())))); + return new PageResult<>(list, page.getTotal()); + } + + List convertList(List list); + + List convertList2(List tasks); + + default BpmProcessInstanceRespVO convert2(HistoricProcessInstance processInstance, BpmProcessInstanceExtDO processInstanceExt, + ProcessDefinition processDefinition, BpmProcessDefinitionExtDO processDefinitionExt, + String bpmnXml, AdminUserRespDTO startUser, DeptRespDTO dept) { + BpmProcessInstanceRespVO respVO = convert2(processInstance); + copyTo(processInstanceExt, respVO); + // definition + respVO.setProcessDefinition(convert2(processDefinition)); + copyTo(processDefinitionExt, respVO.getProcessDefinition()); + respVO.getProcessDefinition().setBpmnXml(bpmnXml); + // user + if (startUser != null) { + respVO.setStartUser(convert2(startUser)); + if (dept != null) { + respVO.getStartUser().setDeptName(dept.getName()); + } + } + return respVO; + } + + BpmProcessInstanceRespVO convert2(HistoricProcessInstance bean); + + @Mapping(source = "from.id", target = "to.id", ignore = true) + void copyTo(BpmProcessInstanceExtDO from, @MappingTarget BpmProcessInstanceRespVO to); + + BpmProcessInstanceRespVO.ProcessDefinition convert2(ProcessDefinition bean); + + @Mapping(source = "from.id", target = "to.id", ignore = true) + void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to); + + BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean); + + + + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java new file mode 100644 index 000000000..330d59d0e --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java @@ -0,0 +1,68 @@ +package cn.iocoder.yudao.module.bpm.convert.task; + +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskDonePageItemRespVO; +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.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO; +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; + +import org.flowable.common.engine.impl.db.SuspensionState; +import org.flowable.engine.history.HistoricProcessInstance; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.task.api.Task; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.mapstruct.*; +import org.mapstruct.factory.Mappers; + +import java.util.List; +import java.util.Map; + +/** + * Bpm 任务 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface BpmTaskConvert { + + BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class); + + default List convertList1(List tasks, Map processInstanceMap, + Map userMap) { + return CollectionUtils.convertList(tasks, task -> { + BpmTaskTodoPageItemRespVO respVO = convert1(task); + ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId()); + if (processInstance != null) { + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId())); + respVO.setProcessInstance(convert(processInstance, startUser)); + } + return respVO; + }); + } + + @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState") + BpmTaskTodoPageItemRespVO convert1(Task bean); + + @Named("convertSuspendedToSuspensionState") + default Integer convertSuspendedToSuspensionState(boolean suspended) { + return suspended ? SuspensionState.SUSPENDED.getStateCode() : + SuspensionState.ACTIVE.getStateCode(); + } + + @Mappings({ + @Mapping(source = "processInstance.id", target = "id"), + @Mapping(source = "processInstance.name", target = "name"), + @Mapping(source = "processInstance.startUserId", target = "startUserId"), + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"), + @Mapping(source = "startUser.nickname", target = "startUserNickname") + }) + BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, AdminUserRespDTO startUser); + + +} + + diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java index 51bc807fb..96a0bc1a7 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java @@ -2,8 +2,10 @@ package cn.iocoder.yudao.module.bpm.service.definition; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import org.flowable.bpmn.model.BpmnModel; @@ -31,6 +33,14 @@ public interface BpmProcessDefinitionService { */ PageResult getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO); + /** + * 获得流程定义列表 + * + * @param listReqVO 列表入参 + * @return 流程定义列表 + */ + List getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO); + /** * 创建流程定义 * diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java index cb3419483..f56a18fff 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java @@ -5,8 +5,10 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.PageUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; @@ -228,6 +230,27 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ return processDefinitionMapper.selectByProcessDefinitionId(id); } + @Override + public List getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO) { + // 拼接查询条件 + ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery(); + if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), listReqVO.getSuspensionState())) { + definitionQuery.suspended(); + } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), listReqVO.getSuspensionState())) { + definitionQuery.active(); + } + // 执行查询 + List processDefinitions = definitionQuery.list(); + + // 获得 BpmProcessDefinitionDO Map + List processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds( + convertList(processDefinitions, ProcessDefinition::getId)); + Map processDefinitionDOMap = convertMap(processDefinitionDOs, + BpmProcessDefinitionExtDO::getProcessDefinitionId); + // 执行查询,并返回 + return BpmProcessDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap); + } + @Override public PageResult getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) { ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery(); @@ -262,4 +285,6 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ return new PageResult<>(BpmProcessDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap, processDefinitionDOMap, formMap), definitionCount); } + + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java new file mode 100644 index 000000000..079451597 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java @@ -0,0 +1,87 @@ +package cn.iocoder.yudao.module.bpm.service.definition; + +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; +import org.springframework.lang.Nullable; + +import javax.validation.Valid; +import java.util.List; + +/** + * BPM 任务分配规则 Service 接口 + * + * @author 芋道源码 + */ +public interface BpmTaskAssignRuleService { + + /** + * 获得流程定义的任务分配规则数组 + * + * @param processDefinitionId 流程定义的编号 + * @param taskDefinitionKey 流程任务定义的 Key。允许空 + * @return 任务规则数组 + */ + List getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId, + @Nullable String taskDefinitionKey); + + /** + * 获得流程模型的任务规则数组 + * + * @param modelId 流程模型的编号 + * @return 任务规则数组 + */ + List getTaskAssignRuleListByModelId(String modelId); + + /** + * 获得流程定义的任务分配规则数组 + * + * @param modelId 流程模型的编号 + * @param processDefinitionId 流程定义的编号 + * @return 任务规则数组 + */ + List getTaskAssignRuleList(String modelId, String processDefinitionId); + + /** + * 创建任务分配规则 + * + * @param reqVO 创建信息 + * @return 规则编号 + */ + Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO); + + /** + * 更新任务分配规则 + * + * @param reqVO 创建信息 + */ + void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO); + + /** + * 判断指定流程模型和流程定义的分配规则是否相等 + * + * @param modelId 流程模型编号 + * @param processDefinitionId 流程定义编号 + * @return 是否相等 + */ + boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId); + + /** + * 将流程流程模型的任务分配规则,复制一份给流程定义 + * 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义 + * + * @param fromModelId 流程模型编号 + * @param toProcessDefinitionId 流程定义编号 + */ + void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId); + + /** + * 校验流程模型的任务分配规则全部都配置了 + * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去! + * + * @param id 流程模型编号 + */ + void checkTaskAssignRuleAllConfig(String id); + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java new file mode 100644 index 000000000..f1d25f1e2 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.bpm.service.task; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; +import org.flowable.engine.history.HistoricProcessInstance; +import org.flowable.engine.runtime.ProcessInstance; + +import javax.validation.Valid; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 流程实例 Service 接口 + * + * @author 芋道源码 + */ +public interface BpmProcessInstanceService { + + /** + * 获得流程实例列表 + * + * @param ids 流程实例的编号集合 + * @return 流程实例列表 + */ + List getProcessInstances(Set ids); + + /** + * 获得流程实例 Map + * + * @param ids 流程实例的编号集合 + * @return 流程实例列表 Map + */ + default Map getProcessInstanceMap(Set ids) { + return CollectionUtils.convertMap(getProcessInstances(ids), ProcessInstance::getProcessInstanceId); + } + + /** + * 获得流程实例的分页 + * + * @param userId 用户编号 + * @param pageReqVO 分页请求 + * @return 流程实例的分页 + */ + PageResult getMyProcessInstancePage(Long userId, + @Valid BpmProcessInstanceMyPageReqVO pageReqVO); + + /** + * 创建流程实例(提供给前端) + * + * @param userId 用户编号 + * @param createReqVO 创建信息 + * @return 实例的编号 + */ + String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO); + + /** + * 获得流程实例 VO 信息 + * + * @param id 流程实例的编号 + * @return 流程实例 + */ + BpmProcessInstanceRespVO getProcessInstanceVO(String id); + + /** + * 获得历史的流程实例 + * + * @param id 流程实例的编号 + * @return 历史的流程实例 + */ + HistoricProcessInstance getHistoricProcessInstance(String id); +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java new file mode 100644 index 000000000..77f14f3d1 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -0,0 +1,167 @@ +package cn.iocoder.yudao.module.bpm.service.task; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; +import cn.iocoder.yudao.module.bpm.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.service.definition.BpmProcessDefinitionService; +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.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.validation.annotation.Validated; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; +import java.util.Map; +import java.util.Set; + +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.PROCESS_DEFINITION_IS_SUSPENDED; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS; + +/** + * 流程实例 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; + @Override + public List getProcessInstances(Set ids) { + return runtimeService.createProcessInstanceQuery().processDefinitionIds(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 + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { + // 获得流程定义 + ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); + // 发起流程 + return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); + } + + @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); + } + + /** + * 获得历史的流程实例 + * + * @param id 流程实例的编号 + * @return 历史的流程实例 + */ + @Override + public HistoricProcessInstance getHistoricProcessInstance(String id) { + return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); + } + + 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-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java new file mode 100644 index 000000000..de4ea3b95 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.bpm.service.task; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageReqVO; +import org.flowable.task.api.Task; + + +import java.util.List; +import java.util.Map; + +/** + * 流程任务实例 Service 接口 + * + * @author jason + * @author 芋道源码 + */ +public interface BpmTaskService { + /** + * 获得待办的流程任务分页 + * + * @param userId 用户编号 + * @param pageReqVO 分页请求 + * @return 流程任务分页 + */ + PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO); + + /** + * 获得流程任务 Map + * + * @param processInstanceIds 流程实例的编号数组 + * @return 流程任务 Map + */ + default Map> getTaskMapByProcessInstanceIds(List processInstanceIds) { + return CollectionUtils.convertMultiMap(getTasksByProcessInstanceIds(processInstanceIds), + Task::getProcessInstanceId); + } + + /** + * 获得流程任务列表 + * + * @param processInstanceIds 流程实例的编号数组 + * @return 流程任务列表 + */ + List getTasksByProcessInstanceIds(List processInstanceIds); +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java new file mode 100644 index 000000000..857012a45 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.bpm.service.task; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.PageUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageReqVO; +import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; +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.TaskService; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.task.api.Task; +import org.flowable.task.api.TaskQuery; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +/** + * 流程任务实例 Service 实现类 + * + * @author jason + * @author 芋道源码 + */ +@Slf4j +@Service +public class BpmTaskServiceImpl implements BpmTaskService{ + + @Resource + private TaskService taskService; + @Resource + private AdminUserApi adminUserApi; + @Resource + private BpmProcessInstanceService processInstanceService; + + @Override + public PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) { + // 查询待办任务 + TaskQuery taskQuery = taskService.createTaskQuery() + .taskAssignee(String.valueOf(userId)) // 分配给自己 + .orderByTaskCreateTime().desc(); // 创建时间倒序 + if (StrUtil.isNotBlank(pageVO.getName())) { + taskQuery.taskNameLike("%" + pageVO.getName() + "%"); + } + if (pageVO.getBeginCreateTime() != null) { + taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime()); + } + if (pageVO.getEndCreateTime() != null) { + taskQuery.taskCreatedBefore(pageVO.getEndCreateTime()); + } + // 执行查询 + List tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); + if (CollUtil.isEmpty(tasks)) { + return PageResult.empty(taskQuery.count()); + } + + // 获得 ProcessInstance Map + Map processInstanceMap = processInstanceService.getProcessInstanceMap( + convertSet(tasks, Task::getProcessInstanceId)); + // 获得 User Map + Map userMap = adminUserApi.getUserMap( + convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()))); + // 拼接结果 + return new PageResult<>(BpmTaskConvert.INSTANCE.convertList1(tasks, processInstanceMap, userMap), + taskQuery.count()); + } + + @Override + public List getTasksByProcessInstanceIds(List processInstanceIds) { + if (CollUtil.isEmpty(processInstanceIds)) { + return Collections.emptyList(); + } + return taskService.createTaskQuery().processInstanceIdIn(processInstanceIds).list(); + } +} From 073d860a78d6d6b565060de717d600f6a27dc7df Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sat, 12 Feb 2022 23:31:55 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E5=8F=91=E8=B5=B7=E6=B5=81=E7=A8=8B=20=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-dependencies/pom.xml | 5 ++ yudao-framework/pom.xml | 1 + .../common/enums/WebFilterOrderEnum.java | 2 + .../pom.xml | 31 +++++++++++ .../config/YudaoFlowableConfiguration.java | 22 ++++++++ .../framework/flowable/core/package-info.java | 1 + .../flowable/core/util/FlowableUtils.java | 14 +++++ .../flowable/core/web/FlowableWebFilter.java | 35 ++++++++++++ .../framework/flowable/package-info.java | 1 + .../main/resources/META-INF/spring.factories | 2 + .../yudao-module-bpm-impl-flowable/pom.xml | 4 +- .../config/BpmFlowableConfiguration.java | 33 ++++++++++++ .../BpmProcessInstanceEventListener.java | 54 +++++++++++++++++++ .../BpmProcessDefinitionService.java | 10 ++++ .../BpmProcessDefinitionServiceImpl.java | 5 ++ .../task/BpmProcessInstanceService.java | 8 +++ .../task/BpmProcessInstanceServiceImpl.java | 20 +++++++ 17 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-flowable/pom.xml create mode 100644 yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java create mode 100644 yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/package-info.java create mode 100644 yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java create mode 100644 yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/web/FlowableWebFilter.java create mode 100644 yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/package-info.java create mode 100644 yudao-framework/yudao-spring-boot-starter-flowable/src/main/resources/META-INF/spring.factories create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 9f555b02a..0e92b32d0 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -399,6 +399,11 @@ ${revision} + + cn.iocoder.boot + yudao-spring-boot-starter-flowable + ${revision} + org.flowable flowable-spring-boot-starter-basic diff --git a/yudao-framework/pom.xml b/yudao-framework/pom.xml index 85533c9a2..21452b4d1 100644 --- a/yudao-framework/pom.xml +++ b/yudao-framework/pom.xml @@ -35,6 +35,7 @@ yudao-spring-boot-starter-biz-social yudao-spring-boot-starter-biz-tenant yudao-spring-boot-starter-biz-data-permission + yudao-spring-boot-starter-flowable yudao-framework diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java index 6cfbba177..93bd20fa4 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java @@ -29,6 +29,8 @@ public interface WebFilterOrderEnum { int ACTIVITI_FILTER = -98; // 需要保证在 Spring Security 过滤后面 + int FLOWABLE_FILTER = -98; // 需要保证在 Spring Security 过滤后面 + int DEMO_FILTER = Integer.MAX_VALUE; } diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/pom.xml b/yudao-framework/yudao-spring-boot-starter-flowable/pom.xml new file mode 100644 index 000000000..f778e2a54 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-flowable/pom.xml @@ -0,0 +1,31 @@ + + + + yudao-framework + cn.iocoder.boot + ${revision} + + 4.0.0 + + yudao-spring-boot-starter-flowable + + + + cn.iocoder.boot + yudao-common + + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + org.flowable + flowable-spring-boot-starter-basic + + + + \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java new file mode 100644 index 000000000..4061339d6 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.framework.flowable.config; + +import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; +import cn.iocoder.yudao.framework.flowable.core.web.FlowableWebFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class YudaoFlowableConfiguration { + + /** + * 配置 flowable Web 过滤器 + */ + @Bean + public FilterRegistrationBean flowableWebFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new FlowableWebFilter()); + registrationBean.setOrder(WebFilterOrderEnum.FLOWABLE_FILTER); + return registrationBean; + } +} diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/package-info.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/package-info.java new file mode 100644 index 000000000..de8d6279d --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.framework.flowable.core; diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java new file mode 100644 index 000000000..641c699c9 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.framework.flowable.core.util; + +import org.flowable.common.engine.impl.identity.Authentication; + +public class FlowableUtils { + + public static void setAuthenticatedUserId(Long userId) { + Authentication.setAuthenticatedUserId(String.valueOf(userId)); + } + + public static void clearAuthenticatedUserId() { + Authentication.setAuthenticatedUserId(null); + } +} diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/web/FlowableWebFilter.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/web/FlowableWebFilter.java new file mode 100644 index 000000000..d9845a394 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/web/FlowableWebFilter.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.framework.flowable.core.web; + +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +/** + * flowable Web 过滤器,将 userId 设置到 {@link org.flowable.common.engine.impl.identity.Authentication} 中 + * + * @author jason + */ +public class FlowableWebFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException { + try { + // 设置工作流的用户 + Long userId = SecurityFrameworkUtils.getLoginUserId(); + if (userId != null) { + FlowableUtils.setAuthenticatedUserId(userId); + } + // 过滤 + chain.doFilter(request, response); + } finally { + // 清理 + FlowableUtils.clearAuthenticatedUserId(); + } + } +} diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/package-info.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/package-info.java new file mode 100644 index 000000000..324d3de0e --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.framework.flowable; diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/resources/META-INF/spring.factories b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..c667d5e55 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + cn.iocoder.yudao.framework.flowable.config.YudaoFlowableConfiguration diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml b/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml index 09822771d..ea48aaf90 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml @@ -23,8 +23,8 @@ - org.flowable - flowable-spring-boot-starter-basic + cn.iocoder.boot + yudao-spring-boot-starter-flowable org.flowable diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java new file mode 100644 index 000000000..d7009a5c6 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.config; + +import cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmProcessInstanceEventListener; +import org.flowable.common.engine.api.delegate.event.FlowableEventListener; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.spring.SpringProcessEngineConfiguration; +import org.flowable.spring.boot.EngineConfigurationConfigurer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.List; +/** + * BPM 模块的 Flowable 配置类 + * + * @author jason + */ +@Configuration +public class BpmFlowableConfiguration { + + /** + *将自定义 listener 加入全局listener + * @param processInstanceListener 自定义监听 {@link ProcessInstance} + */ + @Bean + public EngineConfigurationConfigurer addCustomerListenerConfigurer (BpmProcessInstanceEventListener processInstanceListener) { + return engineConfiguration -> { + List eventListeners = new ArrayList<>(); + eventListeners.add(processInstanceListener); + engineConfiguration.setEventListeners(eventListeners); + }; + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java new file mode 100644 index 000000000..1b5d1c6e5 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener; + +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; +import com.google.common.collect.ImmutableSet; +import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; +import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; +import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener; +import org.flowable.engine.delegate.event.FlowableCancelledEvent; +import org.flowable.engine.delegate.event.FlowableProcessStartedEvent; +import org.flowable.engine.runtime.ProcessInstance; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Set; +/** + * 监听 {@link ProcessInstance} 的开始与完成,创建与更新对应的 {@link BpmProcessInstanceExtDO} 记录 + * + * @author jason + */ +@Component +public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEventListener { + + @Resource + @Lazy + private BpmProcessInstanceService processInstanceService; + + public static final Set PROCESS_INSTANCE_EVENTS = ImmutableSet.builder() + .add(FlowableEngineEventType.PROCESS_CREATED) + .add(FlowableEngineEventType.PROCESS_STARTED) + .add(FlowableEngineEventType.PROCESS_CANCELLED) + .build(); + + public BpmProcessInstanceEventListener(){ + super(PROCESS_INSTANCE_EVENTS); + } + + @Override + protected void processCreated(FlowableEngineEntityEvent event) { + processInstanceService.createProcessInstanceExt((ProcessInstance)event.getEntity()); + } + + @Override + protected void processStarted(FlowableProcessStartedEvent event) { + super.processStarted(event); + } + + + @Override + protected void processCancelled(FlowableCancelledEvent event) { + super.processCancelled(event); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java index 96a0bc1a7..7c26b644e 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java @@ -89,6 +89,16 @@ public interface BpmProcessDefinitionService { */ ProcessDefinition getProcessDefinition(String id); + /** + * 获得编号对应的 ProcessDefinition + * + * 相比 {@link #getProcessDefinition(String)} 方法,category 的取值是正确 + * + * @param id 编号 + * @return 流程定义 + */ + ProcessDefinition getProcessDefinition2(String id); + /** * 获得 deploymentId 对应的 ProcessDefinition * diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java index f56a18fff..d75a1bd68 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java @@ -66,6 +66,11 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ return repositoryService.getProcessDefinition(id); } + @Override + public ProcessDefinition getProcessDefinition2(String id) { + return repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult(); + } + @Override public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) { if (StrUtil.isEmpty(deploymentId)) { diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java index f1d25f1e2..7b6e3638d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessI import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; +import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.runtime.ProcessInstance; @@ -73,4 +74,11 @@ public interface BpmProcessInstanceService { * @return 历史的流程实例 */ HistoricProcessInstance getHistoricProcessInstance(String id); + + /** + * 创建 ProcessInstance 拓展记录 + * + * @param instance 流程任务 + */ + void createProcessInstanceExt(ProcessInstance instance); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index 77f14f3d1..f9295e0f7 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -12,6 +12,8 @@ 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.BpmProcessInstanceResultEnum; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; @@ -32,6 +34,7 @@ import javax.annotation.Resource; import javax.validation.Valid; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -142,6 +145,23 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } + @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); + } + private String createProcessInstance0(Long userId, ProcessDefinition definition, Map variables, String businessKey) { // 校验流程定义 From d6775a5619226611da610eb9785007c90250e5ea Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 13 Feb 2022 16:12:48 +0800 Subject: [PATCH 08/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E5=8F=91=E8=B5=B7=E6=B5=81=E7=A8=8B,=20=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E7=9B=B8=E5=85=B3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../behavior/BpmActivityBehaviorFactory.java | 2 +- ....java => BpmUserTaskActivityBehavior.java} | 4 +- ...a => BpmUserTaskActivityBehaviorTest.java} | 4 +- .../admin/task/BpmTaskController.java | 14 ++ .../task/BpmProcessInstanceConvert.java | 3 + .../bpm/convert/task/BpmTaskConvert.java | 39 ++++ .../config/BpmFlowableConfiguration.java | 30 +++- .../behavior/BpmActivityBehaviorFactory.java | 51 ++++++ .../behavior/BpmUserTaskActivityBehavior.java | 166 ++++++++++++++++++ .../BpmTaskAssignRuleServiceImpl.java | 1 + .../bpm/service/task/BpmTaskService.java | 9 + .../bpm/service/task/BpmTaskServiceImpl.java | 47 ++++- 12 files changed, 362 insertions(+), 8 deletions(-) rename yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/{BpmUserTaskActivitiBehavior.java => BpmUserTaskActivityBehavior.java} (98%) rename yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/{BpmUserTaskActivitiBehaviorTest.java => BpmUserTaskActivityBehaviorTest.java} (98%) create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmActivityBehaviorFactory.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmActivityBehaviorFactory.java index d394f8631..76f0d97a0 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmActivityBehaviorFactory.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmActivityBehaviorFactory.java @@ -44,7 +44,7 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory { @Override public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) { - BpmUserTaskActivitiBehavior userTaskActivityBehavior = new BpmUserTaskActivitiBehavior(userTask); + BpmUserTaskActivityBehavior userTaskActivityBehavior = new BpmUserTaskActivityBehavior(userTask); userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService); userTaskActivityBehavior.setPermissionApi(permissionApi); userTaskActivityBehavior.setDeptApi(deptApi); diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehavior.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehavior.java similarity index 98% rename from yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehavior.java rename to yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehavior.java index 9fb1f5abb..ed95b4c8a 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehavior.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehavior.java @@ -44,7 +44,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_F * @author 芋道源码 */ @Slf4j -public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior { +public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { @Setter private BpmTaskAssignRuleService bpmTaskRuleService; @@ -64,7 +64,7 @@ public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior { */ private Map scriptMap = Collections.emptyMap(); - public BpmUserTaskActivitiBehavior(UserTask userTask) { + public BpmUserTaskActivityBehavior(UserTask userTask) { super(userTask); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehaviorTest.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehaviorTest.java similarity index 98% rename from yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehaviorTest.java rename to yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehaviorTest.java index b05b712a3..dad383a59 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehaviorTest.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehaviorTest.java @@ -33,10 +33,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; -public class BpmUserTaskActivitiBehaviorTest extends BaseMockitoUnitTest { +public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @InjectMocks - private BpmUserTaskActivitiBehavior behavior; + private BpmUserTaskActivityBehavior behavior; @Mock private BpmTaskAssignRuleService bpmTaskRuleService; @Mock diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java index 05c2fe958..cc218ff88 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java @@ -2,10 +2,12 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +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.controller.admin.task.vo.task.BpmTaskTodoPageReqVO; import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.flowable.bpmn.model.BpmnModel; import org.flowable.engine.TaskService; @@ -13,11 +15,14 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.validation.Valid; +import java.util.List; + import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; @@ -36,4 +41,13 @@ public class BpmTaskController { public CommonResult> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) { return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO)); } + + @GetMapping("/list-by-process-instance-id") + @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的") + @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class) + @PreAuthorize("@ss.hasPermission('bpm:task:query')") + public CommonResult> getTaskListByProcessInstanceId( + @RequestParam("processInstanceId") String processInstanceId) { + return success(taskService.getTaskListByProcessInstanceId(processInstanceId)); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java index 4f0e71f9e..7ce1db8f6 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java @@ -37,6 +37,9 @@ public interface BpmProcessInstanceConvert { List convertList(List list); + @Mapping(source = "processInstanceId", target = "id") + BpmProcessInstancePageItemRespVO convert(BpmProcessInstanceExtDO bean); + List convertList2(List tasks); default BpmProcessInstanceRespVO convert2(HistoricProcessInstance processInstance, BpmProcessInstanceExtDO processInstanceExt, diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java index 330d59d0e..b725bea24 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java @@ -62,6 +62,45 @@ public interface BpmTaskConvert { }) BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, AdminUserRespDTO startUser); + default List convertList3(List tasks, Map bpmTaskExtDOMap, + HistoricProcessInstance processInstance, Map userMap, + Map deptMap) { + return CollectionUtils.convertList(tasks, task -> { + BpmTaskRespVO respVO = convert3(task); + BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId()); + copyTo(taskExtDO, respVO); + if (processInstance != null) { + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId())); + respVO.setProcessInstance(convert(processInstance, startUser)); + } + AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee())); + if (assignUser != null) { + respVO.setAssigneeUser(convert3(assignUser)); + DeptRespDTO dept = deptMap.get(assignUser.getDeptId()); + if (dept != null) { + respVO.getAssigneeUser().setDeptName(dept.getName()); + } + } + return respVO; + }); + } + + @Mapping(source = "taskDefinitionKey", target = "definitionKey") + BpmTaskRespVO convert3(HistoricTaskInstance bean); + + BpmTaskRespVO.User convert3(AdminUserRespDTO bean); + + void copyTo(BpmTaskExtDO from, @MappingTarget BpmTaskDonePageItemRespVO to); + + @Mappings({ + @Mapping(source = "processInstance.id", target = "id"), + @Mapping(source = "processInstance.name", target = "name"), + @Mapping(source = "processInstance.startUserId", target = "startUserId"), + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"), + @Mapping(source = "startUser.nickname", target = "startUserNickname") + }) + BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, AdminUserRespDTO startUser); + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java index d7009a5c6..357765b25 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java @@ -1,6 +1,12 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.config; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory; import cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmProcessInstanceEventListener; +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; +import cn.iocoder.yudao.module.system.api.dept.DeptApi; +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import org.flowable.common.engine.api.delegate.event.FlowableEventListener; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.spring.SpringProcessEngineConfiguration; @@ -19,15 +25,35 @@ import java.util.List; public class BpmFlowableConfiguration { /** - *将自定义 listener 加入全局listener + * 将自定义 listener 加入全局listener * @param processInstanceListener 自定义监听 {@link ProcessInstance} */ @Bean - public EngineConfigurationConfigurer addCustomerListenerConfigurer (BpmProcessInstanceEventListener processInstanceListener) { + public EngineConfigurationConfigurer addCustomerListenerConfigurer (BpmProcessInstanceEventListener processInstanceListener, + BpmActivityBehaviorFactory bpmActivityBehaviorFactory) { return engineConfiguration -> { List eventListeners = new ArrayList<>(); eventListeners.add(processInstanceListener); engineConfiguration.setEventListeners(eventListeners); + engineConfiguration.setActivityBehaviorFactory(bpmActivityBehaviorFactory); }; } + + + + @Bean + public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService, + BpmUserGroupService userGroupService, + PermissionApi permissionApi, + DeptApi deptApi, + AdminUserApi adminUserApi) { + BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory(); + bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService); + bpmActivityBehaviorFactory.setUserGroupService(userGroupService); + bpmActivityBehaviorFactory.setAdminUserApi(adminUserApi); + bpmActivityBehaviorFactory.setPermissionApi(permissionApi); + bpmActivityBehaviorFactory.setDeptApi(deptApi); +// bpmActivityBehaviorFactory.setScripts(scripts); + return bpmActivityBehaviorFactory; + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java new file mode 100644 index 000000000..784cd4f69 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; + +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; +import cn.iocoder.yudao.module.system.api.dept.DeptApi; +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Setter; +import lombok.ToString; +import org.flowable.bpmn.model.UserTask; +import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior; +import org.flowable.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory; + +/** + * 自定义的 ActivityBehaviorFactory 实现类,目的如下: + * 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配 + * + * @author 芋道源码 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory { + + @Setter + private BpmTaskAssignRuleService bpmTaskRuleService; + @Setter + private BpmUserGroupService userGroupService; + + @Setter + private PermissionApi permissionApi; + @Setter + private DeptApi deptApi; + @Setter + private AdminUserApi adminUserApi; + + @Override + public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) { + BpmUserTaskActivityBehavior userTaskActivityBehavior = new BpmUserTaskActivityBehavior(userTask); + userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService); + userTaskActivityBehavior.setPermissionApi(permissionApi); + userTaskActivityBehavior.setDeptApi(deptApi); + userTaskActivityBehavior.setUserGroupService(userGroupService); + userTaskActivityBehavior.setAdminUserApi(adminUserApi); + //TODO + //userTaskActivityBehavior.setScripts(scripts); + return userTaskActivityBehavior; + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java new file mode 100644 index 000000000..202ef09fc --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java @@ -0,0 +1,166 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +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.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; +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.permission.PermissionApi; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import com.google.common.annotations.VisibleForTesting; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.model.UserTask; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.common.engine.impl.el.ExpressionManager; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior; +import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.flowable.engine.impl.util.TaskHelper; +import org.flowable.task.service.TaskService; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; + +import java.util.*; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER; + +/** + * 自定义的流程任务的 assignee 负责人的分配 + * 第一步,获得对应的分配规则; + * 第二步,根据分配规则,计算出分配任务的候选人。如果找不到,则直接报业务异常,不继续执行后续的流程; + * 第三步,随机选择一个候选人,则选择作为 assignee 负责人。 + * + * @author 芋道源码 + */ +@Slf4j +public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { + + @Setter + private BpmTaskAssignRuleService bpmTaskRuleService; + @Setter + private BpmUserGroupService userGroupService; + @Setter + private DeptApi deptApi; + @Setter + private AdminUserApi adminUserApi; + @Setter + private PermissionApi permissionApi; + + public BpmUserTaskActivityBehavior(UserTask userTask) { + super(userTask); + } + + @Override + protected void handleAssignments(TaskService taskService, String assignee, String owner, List candidateUsers, List candidateGroups, TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) { + // 第一步,获得任务的规则 + BpmTaskAssignRuleDO rule = getTaskRule(task); + // 第二步,获得任务的候选用户们 + Set candidateUserIds = calculateTaskCandidateUsers(task, rule); + // 第三步,设置一个作为负责人 + Long assigneeUserId = chooseTaskAssignee(candidateUserIds); + TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId)); + } + + private BpmTaskAssignRuleDO getTaskRule(TaskEntity task) { + List taskRules = bpmTaskRuleService.getTaskAssignRuleListByProcessDefinitionId(task.getProcessDefinitionId(), + task.getTaskDefinitionKey()); + if (CollUtil.isEmpty(taskRules)) { + throw new FlowableException(StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则", + task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey())); + } + if (taskRules.size() > 1) { + throw new FlowableException(StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})", + task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), taskRules.size())); + } + return taskRules.get(0); + } + + @VisibleForTesting + Set calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) { + Set assigneeUserIds = null; + if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule); + } +// else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) { +// assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule); +// } + + // 移除被禁用的用户 + removeDisableUsers(assigneeUserIds); + // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人 + if (CollUtil.isEmpty(assigneeUserIds)) { + log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", + task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), toJsonString(rule)); + throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER); + } + return assigneeUserIds; + } + + private Set calculateTaskCandidateUsersByRole(TaskEntity task, BpmTaskAssignRuleDO rule) { + return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions()); + } + + private Set calculateTaskCandidateUsersByDeptMember(TaskEntity task, BpmTaskAssignRuleDO rule) { + List users = adminUserApi.getUsersByDeptIds(rule.getOptions()); + return convertSet(users, AdminUserRespDTO::getId); + } + + private Set calculateTaskCandidateUsersByDeptLeader(TaskEntity task, BpmTaskAssignRuleDO rule) { + List depts = deptApi.getDepts(rule.getOptions()); + return convertSet(depts, DeptRespDTO::getLeaderUserId); + } + + private Set calculateTaskCandidateUsersByPost(TaskEntity task, BpmTaskAssignRuleDO rule) { + List users = adminUserApi.getUsersByPostIds(rule.getOptions()); + return convertSet(users, AdminUserRespDTO::getId); + } + + private Set calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskAssignRuleDO rule) { + return rule.getOptions(); + } + + private Set calculateTaskCandidateUsersByUserGroup(TaskEntity task, BpmTaskAssignRuleDO rule) { + List userGroups = userGroupService.getUserGroupList(rule.getOptions()); + Set userIds = new HashSet<>(); + userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds())); + return userIds; + } + + private Long chooseTaskAssignee(Set candidateUserIds) { + // TODO 芋艿:未来可以优化下,改成轮询的策略 + int index = RandomUtil.randomInt(candidateUserIds.size()); + return CollUtil.get(candidateUserIds, index); + } + + @VisibleForTesting + void removeDisableUsers(Set assigneeUserIds) { + if (CollUtil.isEmpty(assigneeUserIds)) { + return; + } + Map userMap = adminUserApi.getUserMap(assigneeUserIds); + assigneeUserIds.removeIf(id -> { + AdminUserRespDTO user = userMap.get(id); + return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus()); + }); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index 7b375e36a..b1a12e71c 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -47,6 +47,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ @Lazy // 解决循环依赖 private BpmModelService modelService; @Resource + @Lazy // 解决循环依赖 private BpmProcessDefinitionService processDefinitionService; @Resource private BpmUserGroupService userGroupService; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index de4ea3b95..21ff79e90 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.service.task; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +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.controller.admin.task.vo.task.BpmTaskTodoPageReqVO; import org.flowable.task.api.Task; @@ -44,4 +45,12 @@ public interface BpmTaskService { * @return 流程任务列表 */ List getTasksByProcessInstanceIds(List processInstanceIds); + + /** + * 获得指令流程实例的流程任务列表,包括所有状态的 + * + * @param processInstanceId 流程实例的编号 + * @return 流程任务列表 + */ + List getTaskListByProcessInstanceId(String processInstanceId); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 857012a45..eefb418a5 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -3,24 +3,35 @@ package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; 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.framework.common.util.object.PageUtils; +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.controller.admin.task.vo.task.BpmTaskTodoPageReqVO; import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; +import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; +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.TaskService; +import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.flowable.task.api.TaskQuery; +import org.flowable.task.api.history.HistoricTaskInstance; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; /** @@ -36,9 +47,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @Resource private TaskService taskService; @Resource - private AdminUserApi adminUserApi; + private HistoryService historyService; + @Resource private BpmProcessInstanceService processInstanceService; + @Resource + private AdminUserApi adminUserApi; + @Resource + private DeptApi deptApi; + @Resource + private BpmTaskExtMapper taskExtMapper; @Override public PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) { @@ -79,4 +97,31 @@ public class BpmTaskServiceImpl implements BpmTaskService{ } return taskService.createTaskQuery().processInstanceIdIn(processInstanceIds).list(); } + + @Override + public List getTaskListByProcessInstanceId(String processInstanceId) { + // 获得任务列表 + List tasks = historyService.createHistoricTaskInstanceQuery() + .processInstanceId(processInstanceId) + .orderByHistoricTaskInstanceStartTime().desc() // 创建时间倒序 + .list(); + if (CollUtil.isEmpty(tasks)) { + return Collections.emptyList(); + } + + // 获得 TaskExtDO Map + List bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId)); + Map bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId); + // 获得 ProcessInstance Map + HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId); + // 获得 User Map + Set userIds = convertSet(tasks, task -> NumberUtils.parseLong(task.getAssignee())); + userIds.add(NumberUtils.parseLong(processInstance.getStartUserId())); + Map userMap = adminUserApi.getUserMap(userIds); + // 获得 Dept Map + Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); + + // 拼接数据 + return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap); + } } From 075dd83b5fa1e7b653ddbcbccf5d159780132f01 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 13 Feb 2022 23:42:30 +0800 Subject: [PATCH 09/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E5=AE=9E=E4=BE=8B,=20=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E7=9B=B8=E5=85=B3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/task/BpmActivityController.java | 39 +++++++++++++++ .../bpm/convert/task/BpmActivityConvert.java | 29 +++++++++++ .../config/BpmFlowableConfiguration.java | 13 +++-- .../core/listener/BpmTaskEventListener.java | 42 ++++++++++++++++ .../bpm/service/task/BpmActivityService.java | 22 +++++++++ .../service/task/BpmActivityServiceImpl.java | 49 +++++++++++++++++++ .../task/BpmProcessInstanceServiceImpl.java | 2 +- .../bpm/service/task/BpmTaskService.java | 8 +++ .../bpm/service/task/BpmTaskServiceImpl.java | 13 +++++ 9 files changed, 212 insertions(+), 5 deletions(-) create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java new file mode 100644 index 000000000..24d89cd36 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.task; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; +import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Api(tags = "管理后台 - 流程活动实例") +@RestController +@RequestMapping("/bpm/activity") +@Validated +public class BpmActivityController { + + @Resource + private BpmActivityService activityService; + + @GetMapping("/list") + @ApiOperation(value = "生成指定流程实例的高亮流程图", + notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成") + @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class) + @PreAuthorize("@ss.hasPermission('bpm:task:query')") + public CommonResult> getActivityList( + @RequestParam("processInstanceId") String processInstanceId) { + return success(activityService.getActivityListByProcessInstanceId(processInstanceId)); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java new file mode 100644 index 000000000..509408457 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.bpm.convert.task; + +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; +import org.flowable.engine.history.HistoricActivityInstance; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * BPM 活动 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface BpmActivityConvert { + + BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class); + + List convertList(List list); + + @Mappings({ + @Mapping(source = "activityId", target = "key"), + @Mapping(source = "activityType", target = "type") + }) + BpmActivityRespVO convert(HistoricActivityInstance bean); +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java index 357765b25..874df456d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java @@ -11,10 +11,12 @@ import org.flowable.common.engine.api.delegate.event.FlowableEventListener; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.spring.SpringProcessEngineConfiguration; import org.flowable.spring.boot.EngineConfigurationConfigurer; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; /** * BPM 模块的 Flowable 配置类 @@ -26,14 +28,17 @@ public class BpmFlowableConfiguration { /** * 将自定义 listener 加入全局listener - * @param processInstanceListener 自定义监听 {@link ProcessInstance} + * @param listeners 自定义 listener */ @Bean - public EngineConfigurationConfigurer addCustomerListenerConfigurer (BpmProcessInstanceEventListener processInstanceListener, + public EngineConfigurationConfigurer addCustomerListenerConfigurer (ObjectProvider listeners, BpmActivityBehaviorFactory bpmActivityBehaviorFactory) { return engineConfiguration -> { - List eventListeners = new ArrayList<>(); - eventListeners.add(processInstanceListener); + List eventListeners = new ArrayList<>(); + Iterator iterator = listeners.iterator(); + while (iterator.hasNext()) { + eventListeners.add(iterator.next()); + } engineConfiguration.setEventListeners(eventListeners); engineConfiguration.setActivityBehaviorFactory(bpmActivityBehaviorFactory); }; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java new file mode 100644 index 000000000..203689db2 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener; + +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; +import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; +import com.google.common.collect.ImmutableSet; +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.task.api.Task; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Set; + +/** + * 监听 {@link org.flowable.task.api.Task} 的开始与完成,创建与更新对应的 {@link BpmTaskExtDO} 记录 + * + * @author jason + */ +@Component +public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { + + @Resource + @Lazy // 解决循环依赖 + private BpmTaskService taskService; + + public static final Set TASK_EVENTS = ImmutableSet.builder() + .add(FlowableEngineEventType.TASK_CREATED) + .add(FlowableEngineEventType.TASK_ASSIGNED) + .add(FlowableEngineEventType.TASK_COMPLETED) + .build(); + + public BpmTaskEventListener(){ + super(TASK_EVENTS); + } + + @Override + protected void taskCreated(FlowableEngineEntityEvent event) { + taskService.createTaskExt((Task) event.getEntity()); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java new file mode 100644 index 000000000..20d71ec24 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.bpm.service.task; + +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; + +import java.util.List; + +/** + * BPM 活动实例 Service 接口 + * + * @author 芋道源码 + */ +public interface BpmActivityService { + + /** + * 获得指定流程实例的活动实例列表 + * + * @param processInstanceId 流程实例的编号 + * @return 活动实例列表 + */ + List getActivityListByProcessInstanceId(String processInstanceId); + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java new file mode 100644 index 000000000..fdab5a884 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.bpm.service.task; + +import cn.hutool.core.io.IoUtil; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; +import cn.iocoder.yudao.module.bpm.convert.task.BpmActivityConvert; +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; +import lombok.extern.slf4j.Slf4j; + +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.engine.HistoryService; +import org.flowable.engine.history.HistoricActivityInstance; +import org.flowable.engine.history.HistoricProcessInstance; +import org.flowable.image.ProcessDiagramGenerator; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.io.InputStream; +import java.util.Collections; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS; + +/** + * BPM 活动实例 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Slf4j +@Validated +public class BpmActivityServiceImpl implements BpmActivityService { + + @Resource + private HistoryService historyService; + + @Override + public List getActivityListByProcessInstanceId(String processInstanceId) { + List activityList = historyService.createHistoricActivityInstanceQuery() + .processInstanceId(processInstanceId).list(); + return BpmActivityConvert.INSTANCE.convertList(activityList); + } + + + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index f9295e0f7..950403446 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -76,7 +76,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService private DeptApi deptApi; @Override public List getProcessInstances(Set ids) { - return runtimeService.createProcessInstanceQuery().processDefinitionIds(ids).list(); + return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index 21ff79e90..b04f7952c 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java @@ -53,4 +53,12 @@ public interface BpmTaskService { * @return 流程任务列表 */ List getTaskListByProcessInstanceId(String processInstanceId); + + /** + * 创建 Task 拓展记录 + * + * @param task 任务实体 + */ + void createTaskExt(Task task); + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index eefb418a5..b65eea73f 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPage import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; 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; @@ -124,4 +125,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{ // 拼接数据 return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap); } + + @Override + public void createTaskExt(Task task) { + BpmTaskExtDO taskExtDO = new BpmTaskExtDO() + .setTaskId(task.getId()) + .setAssigneeUserId(task.getAssignee() == null ? null : Long.valueOf(task.getAssignee())) + .setProcessDefinitionId(task.getProcessDefinitionId()) + .setProcessInstanceId(task.getProcessInstanceId()) + .setName(task.getName()) + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); + taskExtMapper.insert(taskExtDO); + } } From d30bf0601c92ade4c24a4c0e723164f77feb383f Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 14 Feb 2022 15:47:39 +0800 Subject: [PATCH 10/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=B5=81=E7=A8=8B=E5=AE=9E=E4=BE=8B=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/BpmProcessInstanceController.java | 13 ++- .../task/BpmProcessInstanceConvert.java | 22 ++++- .../bpm/convert/task/BpmTaskConvert.java | 12 ++- .../BpmProcessInstanceEventListener.java | 11 +-- .../core/listener/BpmTaskEventListener.java | 5 + .../task/BpmProcessInstanceService.java | 38 +++++++- .../task/BpmProcessInstanceServiceImpl.java | 91 ++++++++++++++++--- .../bpm/service/task/BpmTaskService.java | 7 ++ .../bpm/service/task/BpmTaskServiceImpl.java | 20 ++-- 9 files changed, 182 insertions(+), 37 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java index 93e1f2fb6..851a83ce5 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; @@ -50,4 +47,12 @@ public class BpmProcessInstanceController { public CommonResult getProcessInstance(@RequestParam("id") String id) { return success(processInstanceService.getProcessInstanceVO(id)); } + + @DeleteMapping("/cancel") + @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程") + @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')") + public CommonResult cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) { + processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO); + return success(true); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java index 7ce1db8f6..8cfaa2cdd 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java @@ -5,18 +5,23 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessI import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent; +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 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.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; +import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; import java.util.List; import java.util.Map; +import java.util.Optional; /** * 流程实例 Convert @@ -73,7 +78,22 @@ public interface BpmProcessInstanceConvert { BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean); + default BpmProcessInstanceResultEvent convert(Object source, HistoricProcessInstance instance, Integer result) { + BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source); + event.setId(instance.getId()); + event.setProcessDefinitionKey(instance.getProcessDefinitionKey()); + event.setBusinessKey(instance.getBusinessKey()); + event.setResult(result); + return event; + } - + default BpmMessageSendWhenProcessInstanceApproveReqDTO convert2ApprovedReq(ProcessInstance instance){ + Long startUserId = instance.getStartUserId() == null ? null : Long.valueOf(instance.getStartUserId()); + BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO = new BpmMessageSendWhenProcessInstanceApproveReqDTO() + .setStartUserId(startUserId) + .setProcessInstanceId(instance.getId()) + .setProcessInstanceName(instance.getName()); + return reqDTO; + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java index b725bea24..4a7ea1ef9 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java @@ -101,7 +101,17 @@ public interface BpmTaskConvert { }) BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, AdminUserRespDTO startUser); - + default BpmTaskExtDO convert2TaskExt(Task task){ + Long assigneeUserId = task.getAssignee() == null ? null : Long.valueOf(task.getAssignee()); + BpmTaskExtDO taskExtDO = new BpmTaskExtDO() + .setTaskId(task.getId()) + .setAssigneeUserId(assigneeUserId) + .setName(task.getName()) + .setProcessDefinitionId(task.getProcessDefinitionId()) + .setProcessInstanceId(task.getProcessInstanceId()); + taskExtDO.setCreateTime(task.getCreateTime()); + return taskExtDO; + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java index 1b5d1c6e5..82d5e9be6 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java @@ -28,8 +28,8 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent public static final Set PROCESS_INSTANCE_EVENTS = ImmutableSet.builder() .add(FlowableEngineEventType.PROCESS_CREATED) - .add(FlowableEngineEventType.PROCESS_STARTED) .add(FlowableEngineEventType.PROCESS_CANCELLED) + .add(FlowableEngineEventType.PROCESS_COMPLETED) .build(); public BpmProcessInstanceEventListener(){ @@ -42,13 +42,12 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent } @Override - protected void processStarted(FlowableProcessStartedEvent event) { - super.processStarted(event); + protected void processCancelled(FlowableCancelledEvent event) { + processInstanceService.updateProcessInstanceExtCancel(event); } - @Override - protected void processCancelled(FlowableCancelledEvent event) { - super.processCancelled(event); + protected void processCompleted(FlowableEngineEntityEvent event) { + processInstanceService.updateProcessInstanceExtComplete((ProcessInstance)event.getEntity()); } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java index 203689db2..8e371fb20 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java @@ -39,4 +39,9 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { protected void taskCreated(FlowableEngineEntityEvent event) { taskService.createTaskExt((Task) event.getEntity()); } + + @Override + protected void taskCompleted(FlowableEngineEntityEvent event) { + super.taskCompleted(event); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java index 7b6e3638d..7b0191edf 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java @@ -2,11 +2,9 @@ package cn.iocoder.yudao.module.bpm.service.task; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; +import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.runtime.ProcessInstance; @@ -22,6 +20,14 @@ import java.util.Set; */ public interface BpmProcessInstanceService { + /** + * 获得流程实例 + * + * @param id 流程实例的编号 + * @return 流程实例 + */ + ProcessInstance getProcessInstance(String id); + /** * 获得流程实例列表 * @@ -67,6 +73,14 @@ public interface BpmProcessInstanceService { */ BpmProcessInstanceRespVO getProcessInstanceVO(String id); + /** + * 取消流程实例 + * + * @param userId 用户编号 + * @param cancelReqVO 取消信息 + */ + void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO); + /** * 获得历史的流程实例 * @@ -81,4 +95,20 @@ public interface BpmProcessInstanceService { * @param instance 流程任务 */ void createProcessInstanceExt(ProcessInstance instance); + + /** + * 更新 ProcessInstance 拓展记录为取消 + * + * @param event 流程取消事件 + */ + void updateProcessInstanceExtCancel(FlowableCancelledEvent event); + + /** + * 更新 ProcessInstance 拓展记录为完成 + * + * @param instance 流程任务 + */ + void updateProcessInstanceExtComplete(ProcessInstance instance); + + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index 950403446..c3ae98e3f 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -4,17 +4,17 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.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; @@ -22,6 +22,7 @@ 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; @@ -32,15 +33,12 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_IS_SUSPENDED; -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF; /** * 流程实例 Service 实现类 @@ -74,6 +72,15 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService 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(); @@ -134,6 +141,24 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } + @Override + public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { + // 校验流程实例存在 + ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); + if (instance == null) { + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); + } + // 只能取消自己的 + if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); + } + + // 通过删除流程实例,实现流程实例的取消, + // 删除流程实例,正则执行任务ACT_RU_TASK. 任务会被删除。通过历史表查询 + runtimeService.deleteProcessInstance(cancelReqVO.getId(), + BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); + } + /** * 获得历史的流程实例 * @@ -162,6 +187,51 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService processInstanceExtMapper.insert(instanceExtDO); } + @Override + public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { + // 判断是否为 Reject 不通过。如果是,则不进行更新 + if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) { + return; + } + + // 需要主动查询,因为 instance 只有 id 属性 + // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance + HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); + // 更新拓展表 + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() + .setProcessInstanceId(event.getProcessInstanceId()) + .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) + .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); + + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); + + // 发送流程实例的状态事件 + processInstanceResultEventPublisher.sendProcessInstanceResultEvent( + BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); + } + + @Override + public void updateProcessInstanceExtComplete(ProcessInstance instance) { + // 需要主动查询,因为 instance 只有 id 属性 + // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance + HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); + // 更新拓展表 + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() + .setProcessInstanceId(instance.getProcessInstanceId()) + .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); + + // 发送流程被通过的消息 + messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance)); + + // 发送流程实例的状态事件 + processInstanceResultEventPublisher.sendProcessInstanceResultEvent( + BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); + } + private String createProcessInstance0(Long userId, ProcessDefinition definition, Map variables, String businessKey) { // 校验流程定义 @@ -181,7 +251,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()) .setFormVariables(variables)); - return instance.getId(); } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index b04f7952c..6bb5e5de5 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java @@ -61,4 +61,11 @@ public interface BpmTaskService { */ void createTaskExt(Task task); + /** + * 更新 Task 拓展记录为完成 + * + * @param task 任务实体 + */ + void updateTaskExtComplete(Task task); + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index b65eea73f..63447315d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -27,10 +27,7 @@ import org.flowable.task.api.history.HistoricTaskInstance; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @@ -128,13 +125,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @Override public void createTaskExt(Task task) { - BpmTaskExtDO taskExtDO = new BpmTaskExtDO() - .setTaskId(task.getId()) - .setAssigneeUserId(task.getAssignee() == null ? null : Long.valueOf(task.getAssignee())) - .setProcessDefinitionId(task.getProcessDefinitionId()) - .setProcessInstanceId(task.getProcessInstanceId()) - .setName(task.getName()) + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); taskExtMapper.insert(taskExtDO); } + + @Override + public void updateTaskExtComplete(Task task) { + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task) + .setEndTime(new Date()) // 此时不能使用 task 的 completeData,因为还是空的。 + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); + taskExtMapper.updateByTaskId(taskExtDO); + } } From c1884c31967a616e55235d749638761e612c8a1e Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 14 Feb 2022 18:11:11 +0800 Subject: [PATCH 11/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E4=BB=BB=E5=8A=A1=EF=BC=8C=E6=8B=92=E7=BB=9D?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=20=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/task/BpmTaskController.java | 25 +++++-- .../task/BpmProcessInstanceConvert.java | 25 +++++-- .../bpm/convert/task/BpmTaskConvert.java | 3 +- .../core/listener/BpmTaskEventListener.java | 2 +- .../task/BpmProcessInstanceService.java | 8 +++ .../task/BpmProcessInstanceServiceImpl.java | 31 ++++++++- .../bpm/service/task/BpmTaskService.java | 21 +++++- .../bpm/service/task/BpmTaskServiceImpl.java | 67 +++++++++++++++++-- 8 files changed, 158 insertions(+), 24 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java index cc218ff88..6d5eeb467 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java @@ -2,9 +2,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -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.controller.admin.task.vo.task.BpmTaskTodoPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; @@ -13,10 +11,7 @@ import org.flowable.bpmn.model.BpmnModel; import org.flowable.engine.TaskService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; @@ -50,4 +45,20 @@ public class BpmTaskController { @RequestParam("processInstanceId") String processInstanceId) { return success(taskService.getTaskListByProcessInstanceId(processInstanceId)); } + + @PutMapping("/approve") + @ApiOperation("通过任务") + @PreAuthorize("@ss.hasPermission('bpm:task:update')") + public CommonResult approveTask(@Valid @RequestBody BpmTaskApproveReqVO reqVO) { + taskService.approveTask(getLoginUserId(), reqVO); + return success(true); + } + + @PutMapping("/reject") + @ApiOperation("不通过任务") + @PreAuthorize("@ss.hasPermission('bpm:task:update')") + public CommonResult rejectTask(@Valid @RequestBody BpmTaskRejectReqVO reqVO) { + taskService.rejectTask(getLoginUserId(), reqVO); + return success(true); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java index 8cfaa2cdd..c6f6cbee5 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java @@ -1,12 +1,14 @@ package cn.iocoder.yudao.module.bpm.convert.task; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent; import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO; +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.flowable.engine.history.HistoricProcessInstance; @@ -87,13 +89,28 @@ public interface BpmProcessInstanceConvert { return event; } + default BpmProcessInstanceResultEvent convert(Object source, ProcessInstance instance, Integer result) { + BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source); + event.setId(instance.getId()); + event.setProcessDefinitionKey(instance.getProcessDefinitionKey()); + event.setBusinessKey(instance.getBusinessKey()); + event.setResult(result); + return event; + } + default BpmMessageSendWhenProcessInstanceApproveReqDTO convert2ApprovedReq(ProcessInstance instance){ - Long startUserId = instance.getStartUserId() == null ? null : Long.valueOf(instance.getStartUserId()); - BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO = new BpmMessageSendWhenProcessInstanceApproveReqDTO() - .setStartUserId(startUserId) + return new BpmMessageSendWhenProcessInstanceApproveReqDTO() + .setStartUserId(NumberUtils.parseLong(instance.getStartUserId())) .setProcessInstanceId(instance.getId()) .setProcessInstanceName(instance.getName()); - return reqDTO; + } + + default BpmMessageSendWhenProcessInstanceRejectReqDTO convert2RejectReq(ProcessInstance instance, String comment) { + return new BpmMessageSendWhenProcessInstanceRejectReqDTO() + .setProcessInstanceName(instance.getName()) + .setProcessInstanceId(instance.getId()) + .setComment(comment) + .setStartUserId(NumberUtils.parseLong(instance.getStartUserId())); } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java index 4a7ea1ef9..44d92354f 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java @@ -102,10 +102,9 @@ public interface BpmTaskConvert { BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, AdminUserRespDTO startUser); default BpmTaskExtDO convert2TaskExt(Task task){ - Long assigneeUserId = task.getAssignee() == null ? null : Long.valueOf(task.getAssignee()); BpmTaskExtDO taskExtDO = new BpmTaskExtDO() .setTaskId(task.getId()) - .setAssigneeUserId(assigneeUserId) + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())) .setName(task.getName()) .setProcessDefinitionId(task.getProcessDefinitionId()) .setProcessInstanceId(task.getProcessInstanceId()); diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java index 8e371fb20..35d3d0e32 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java @@ -42,6 +42,6 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { @Override protected void taskCompleted(FlowableEngineEntityEvent event) { - super.taskCompleted(event); + taskService.updateTaskExtComplete((Task)event.getEntity()); } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java index 7b0191edf..6ca19bb93 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java @@ -110,5 +110,13 @@ public interface BpmProcessInstanceService { */ void updateProcessInstanceExtComplete(ProcessInstance instance); + /** + * 更新 ProcessInstance 拓展记录为不通过 + * + * @param id 流程编号 + * @param comment 理由。例如说,审批不通过时,需要传递该值 + */ + void updateProcessInstanceExtReject(String id, String comment); + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index c3ae98e3f..c55e49032 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -2,6 +2,7 @@ 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.controller.admin.task.vo.instance.*; @@ -29,6 +30,7 @@ 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; @@ -155,7 +157,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService // 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务ACT_RU_TASK. 任务会被删除。通过历史表查询 - runtimeService.deleteProcessInstance(cancelReqVO.getId(), + deleteProcessInstance(cancelReqVO.getId(), BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); } @@ -232,6 +234,33 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } + @Transactional(rollbackFor = Exception.class) + public void updateProcessInstanceExtReject(String id, String comment) { + // 需要主动查询,因为 instance 只有 id 属性 + ProcessInstance processInstance = getProcessInstance(id); + // 删除流程实例,以实现驳回任务时,取消整个审批流程 + deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(comment))); + + // 更新 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, comment)); + + // 发送流程实例的状态事件 + 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) { // 校验流程定义 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index 6bb5e5de5..339234826 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java @@ -2,12 +2,11 @@ package cn.iocoder.yudao.module.bpm.service.task; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -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.controller.admin.task.vo.task.BpmTaskTodoPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; import org.flowable.task.api.Task; +import javax.validation.Valid; import java.util.List; import java.util.Map; @@ -54,6 +53,22 @@ public interface BpmTaskService { */ List getTaskListByProcessInstanceId(String processInstanceId); + /** + * 通过任务 + * + * @param userId 用户编号 + * @param reqVO 通过请求 + */ + void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO); + + /** + * 不通过任务 + * + * @param userId 用户编号 + * @param reqVO 不通过请求 + */ + void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO); + /** * 创建 Task 拓展记录 * diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 63447315d..d0e983702 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -5,9 +5,7 @@ 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.framework.common.util.object.PageUtils; -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.controller.admin.task.vo.task.BpmTaskTodoPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; @@ -27,16 +25,19 @@ import org.flowable.task.api.history.HistoricTaskInstance; import org.springframework.stereotype.Service; 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.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 流程任务实例 Service 实现类 * - * @author jason * @author 芋道源码 + * @author jason */ @Slf4j @Service @@ -123,6 +124,41 @@ public class BpmTaskServiceImpl implements BpmTaskService{ return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap); } + @Override + public void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO) { + // 校验任务存在 + Task task = checkTask(userId, reqVO.getId()); + // 校验流程实例存在 + ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); + if (instance == null) { + throw exception(PROCESS_INSTANCE_NOT_EXISTS); + } + + // 完成任务,审批通过 + taskService.complete(task.getId(), instance.getProcessVariables()); + // 更新任务拓展表为通过 + taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setComment(reqVO.getComment())); + } + + @Override + public void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO) { + Task task = checkTask(userId, reqVO.getId()); + // 校验流程实例存在 + ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); + if (instance == null) { + throw exception(PROCESS_INSTANCE_NOT_EXISTS); + } + + // 更新流程实例为不通过 + processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getComment()); + + // 更新任务拓展表为不通过 + taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) + .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment())); + } + + @Override public void createTaskExt(Task task) { BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task) @@ -133,8 +169,27 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @Override public void updateTaskExtComplete(Task task) { BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task) - .setEndTime(new Date()) // 此时不能使用 task 的 completeData,因为还是空的。 - .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); + .setEndTime(new Date()); taskExtMapper.updateByTaskId(taskExtDO); } + + /** + * 校验任务是否存在, 并且是否是分配给自己的任务 + * @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(); + } } From 41e4283f992d951944b185ed3e6e66cd88263ebf Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Wed, 16 Feb 2022 17:12:48 +0800 Subject: [PATCH 12/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E8=BD=AC=E5=8A=9E=E4=BB=BB=E5=8A=A1=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/task/BpmTaskController.java | 2 +- ...pl.java => BpmProcessInstanceApiImpl.java} | 9 ++- .../admin/task/BpmTaskController.java | 15 ++++ .../bpm/convert/task/BpmTaskConvert.java | 30 ++++++++ .../core/listener/BpmTaskEventListener.java | 5 ++ .../task/BpmProcessInstanceService.java | 29 +++++++- .../task/BpmProcessInstanceServiceImpl.java | 14 ++++ .../bpm/service/task/BpmTaskService.java | 31 ++++++++ .../bpm/service/task/BpmTaskServiceImpl.java | 73 +++++++++++++++++++ 9 files changed, 203 insertions(+), 5 deletions(-) rename yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/{FlowableProcessInstanceApiImpl.java => BpmProcessInstanceApiImpl.java} (63%) diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java index 3c3542aa3..6b8f6dff0 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java @@ -37,7 +37,7 @@ public class BpmTaskController { @GetMapping("done-page") @ApiOperation("获取 Done 已办任务分页") @PreAuthorize("@ss.hasPermission('bpm:task:query')") - public CommonResult> getTodoTaskPage(@Valid BpmTaskDonePageReqVO pageVO) { + public CommonResult> getDoneTaskPage(@Valid BpmTaskDonePageReqVO pageVO) { return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO)); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/FlowableProcessInstanceApiImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java similarity index 63% rename from yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/FlowableProcessInstanceApiImpl.java rename to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java index 0f455ed99..745a61a51 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/FlowableProcessInstanceApiImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.bpm.api.task; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -14,11 +15,13 @@ import javax.validation.Valid; */ @Service @Validated -public class FlowableProcessInstanceApiImpl implements BpmProcessInstanceApi { +public class BpmProcessInstanceApiImpl implements BpmProcessInstanceApi { + + @Resource + private BpmProcessInstanceService processInstanceService; @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO reqDTO) { - //TODO - return null; + return processInstanceService.createProcessInstance(userId, reqDTO); } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java index 6d5eeb467..52b16297d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java @@ -37,6 +37,13 @@ public class BpmTaskController { return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO)); } + @GetMapping("done-page") + @ApiOperation("获取 Done 已办任务分页") + @PreAuthorize("@ss.hasPermission('bpm:task:query')") + public CommonResult> getDoneTaskPage(@Valid BpmTaskDonePageReqVO pageVO) { + return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO)); + } + @GetMapping("/list-by-process-instance-id") @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的") @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class) @@ -61,4 +68,12 @@ public class BpmTaskController { taskService.rejectTask(getLoginUserId(), reqVO); return success(true); } + + @PutMapping("/update-assignee") + @ApiOperation(value = "更新任务的负责人", notes = "用于【流程详情】的【转派】按钮") + @PreAuthorize("@ss.hasPermission('bpm:task:update')") + public CommonResult updateTaskAssignee(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) { + taskService.updateTaskAssignee(getLoginUserId(), reqVO); + return success(true); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java index 44d92354f..32f536959 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java @@ -53,6 +53,24 @@ public interface BpmTaskConvert { SuspensionState.ACTIVE.getStateCode(); } + default List convertList2(List tasks, Map bpmTaskExtDOMap, + Map historicProcessInstanceMap, + Map userMap) { + return CollectionUtils.convertList(tasks, task -> { + BpmTaskDonePageItemRespVO respVO = convert2(task); + BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId()); + copyTo(taskExtDO, respVO); + HistoricProcessInstance processInstance = historicProcessInstanceMap.get(task.getProcessInstanceId()); + if (processInstance != null) { + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId())); + respVO.setProcessInstance(convert(processInstance, startUser)); + } + return respVO; + }); + } + + BpmTaskDonePageItemRespVO convert2(HistoricTaskInstance bean); + @Mappings({ @Mapping(source = "processInstance.id", target = "id"), @Mapping(source = "processInstance.name", target = "name"), @@ -111,6 +129,18 @@ public interface BpmTaskConvert { taskExtDO.setCreateTime(task.getCreateTime()); return taskExtDO; } + + default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser, Task task) { + BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO(); + reqDTO.setProcessInstanceId(processInstance.getProcessInstanceId()) + .setProcessInstanceName(processInstance.getName()) + .setStartUserId(startUser.getId()) + .setStartUserNickname(startUser.getNickname()) + .setTaskId(task.getId()) + .setTaskName(task.getName()) + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())); + return reqDTO; + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java index 35d3d0e32..f9c9cb769 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java @@ -44,4 +44,9 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { protected void taskCompleted(FlowableEngineEntityEvent event) { taskService.updateTaskExtComplete((Task)event.getEntity()); } + + @Override + protected void taskAssigned(FlowableEngineEntityEvent event) { + taskService.updateTaskExtAssign((Task)event.getEntity()); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java index 6ca19bb93..831af4d3d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.service.task; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; import org.flowable.engine.delegate.event.FlowableCancelledEvent; @@ -55,7 +56,6 @@ public interface BpmProcessInstanceService { */ PageResult getMyProcessInstancePage(Long userId, @Valid BpmProcessInstanceMyPageReqVO pageReqVO); - /** * 创建流程实例(提供给前端) * @@ -65,6 +65,15 @@ public interface BpmProcessInstanceService { */ String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO); + /** + * 创建流程实例(提供给内部) + * + * @param userId 用户编号 + * @param createReqDTO 创建信息 + * @return 实例的编号 + */ + String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO); + /** * 获得流程实例 VO 信息 * @@ -89,6 +98,24 @@ public interface BpmProcessInstanceService { */ HistoricProcessInstance getHistoricProcessInstance(String id); + /** + * 获得历史的流程实例列表 + * + * @param ids 流程实例的编号集合 + * @return 历史的流程实例列表 + */ + List getHistoricProcessInstances(Set ids); + + /** + * 获得历史的流程实例 Map + * + * @param ids 流程实例的编号集合 + * @return 历史的流程实例列表 Map + */ + default Map getHistoricProcessInstanceMap(Set ids) { + return CollectionUtils.convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId); + } + /** * 创建 ProcessInstance 拓展记录 * diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index c55e49032..440ecd916 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -5,6 +5,7 @@ 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; @@ -112,6 +113,14 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService 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) { // 获得流程实例 @@ -172,6 +181,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } + @Override + public List getHistoricProcessInstances(Set ids) { + return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); + } + @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index 339234826..e8aab6aa8 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java @@ -25,6 +25,14 @@ public interface BpmTaskService { * @return 流程任务分页 */ PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO); + /** + * 获得已办的流程任务分页 + * + * @param userId 用户编号 + * @param pageReqVO 分页请求 + * @return 流程任务分页 + */ + PageResult getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageReqVO); /** * 获得流程任务 Map @@ -69,6 +77,22 @@ public interface BpmTaskService { */ void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO); + /** + * 将流程任务分配给指定用户 + * + * @param userId 用户编号 + * @param reqVO 分配请求 + */ + void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO); + + /** + * 将流程任务分配给指定用户 + * + * @param id 流程任务编号 + * @param userId 用户编号 + */ + void updateTaskAssignee(String id, Long userId); + /** * 创建 Task 拓展记录 * @@ -83,4 +107,11 @@ public interface BpmTaskService { */ void updateTaskExtComplete(Task task); + /** + * 更新 Task 拓展记录,并发送通知 + * + * @param task 任务实体 + */ + void updateTaskExtAssign(Task task); + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index d0e983702..4028679e0 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; +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; @@ -22,7 +23,10 @@ import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.flowable.task.api.TaskQuery; import org.flowable.task.api.history.HistoricTaskInstance; +import org.flowable.task.api.history.HistoricTaskInstanceQuery; import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.support.TransactionSynchronizationManager; import javax.annotation.Resource; import javax.validation.Valid; @@ -56,6 +60,8 @@ public class BpmTaskServiceImpl implements BpmTaskService{ private DeptApi deptApi; @Resource private BpmTaskExtMapper taskExtMapper; + @Resource + private BpmMessageService messageService; @Override public PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) { @@ -89,6 +95,42 @@ public class BpmTaskServiceImpl implements BpmTaskService{ taskQuery.count()); } + @Override + public PageResult getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) { + // 查询已办任务 + HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery() + .finished() // 已完成 + .taskAssignee(String.valueOf(userId)) // 分配给自己 + .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序 + if (StrUtil.isNotBlank(pageVO.getName())) { + taskQuery.taskNameLike("%" + pageVO.getName() + "%"); + } + if (pageVO.getBeginCreateTime() != null) { + taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime()); + } + if (pageVO.getEndCreateTime() != null) { + taskQuery.taskCreatedBefore(pageVO.getEndCreateTime()); + } + // 执行查询 + List tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); + if (CollUtil.isEmpty(tasks)) { + return PageResult.empty(taskQuery.count()); + } + + // 获得 TaskExtDO Map + List bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId)); + Map bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId); + // 获得 ProcessInstance Map + Map historicProcessInstanceMap = processInstanceService.getHistoricProcessInstanceMap( + convertSet(tasks, HistoricTaskInstance::getProcessInstanceId)); + // 获得 User Map + Map userMap = adminUserApi.getUserMap( + convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()))); + // 拼接结果 + return new PageResult<>(BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap), + taskQuery.count()); + } + @Override public List getTasksByProcessInstanceIds(List processInstanceIds) { if (CollUtil.isEmpty(processInstanceIds)) { @@ -158,6 +200,19 @@ public class BpmTaskServiceImpl implements BpmTaskService{ .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment())); } + @Override + public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) { + // 校验任务存在 + Task task = checkTask(userId, reqVO.getId()); + // 更新负责人 + updateTaskAssignee(task.getId(), reqVO.getAssigneeUserId()); + } + + @Override + public void updateTaskAssignee(String id, Long userId) { + taskService.setAssignee(id, String.valueOf(userId)); + } + @Override public void createTaskExt(Task task) { @@ -173,6 +228,24 @@ public class BpmTaskServiceImpl implements BpmTaskService{ taskExtMapper.updateByTaskId(taskExtDO); } + @Override + public void updateTaskExtAssign(Task task) { + BpmTaskExtDO taskExtDO = new BpmTaskExtDO() + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())) + .setTaskId(task.getId()); + taskExtMapper.updateByTaskId(taskExtDO); + //TODO 创建任务时候 也会调用 updateTaskExtAssign, processInstance 名称为空 校验不通过 + // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。 +// TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { +// @Override +// public void afterCommit() { +// ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); +// AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId())); +// messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task)); +// } +// }); + } + /** * 校验任务是否存在, 并且是否是分配给自己的任务 * @param userId 用户 id From e01acfb18e12915523b293c81e386a1cb87c6242 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Thu, 17 Feb 2022 17:14:46 +0800 Subject: [PATCH 13/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=20=E4=BB=BB=E5=8A=A1=E8=87=AA=E5=AE=9A=E4=B9=89=20Script=20?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=20=E7=9B=B8=E5=85=B3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flowable/core/util/FlowableUtils.java | 48 +++++++++++++ .../config/BpmFlowableConfiguration.java | 9 ++- .../behavior/BpmActivityBehaviorFactory.java | 8 ++- .../behavior/BpmUserTaskActivityBehavior.java | 32 ++++++++- .../behavior/script/BpmTaskAssignScript.java | 34 +++++++++ .../BpmTaskAssignLeaderAbstractScript.java | 71 +++++++++++++++++++ .../impl/BpmTaskAssignLeaderX1Script.java | 27 +++++++ .../impl/BpmTaskAssignLeaderX2Script.java | 27 +++++++ .../impl/BpmTaskAssignStartUserScript.java | 41 +++++++++++ .../BpmProcessDefinitionServiceImpl.java | 18 ++--- .../BpmTaskAssignRuleServiceImpl.java | 25 +------ .../task/BpmProcessInstanceServiceImpl.java | 1 + .../bpm/service/task/BpmTaskServiceImpl.java | 20 +++--- 13 files changed, 307 insertions(+), 54 deletions(-) create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java index 641c699c9..3621d9d99 100644 --- a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java @@ -1,7 +1,14 @@ package cn.iocoder.yudao.framework.flowable.core.util; +import org.flowable.bpmn.converter.BpmnXMLConverter; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.FlowElement; import org.flowable.common.engine.impl.identity.Authentication; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class FlowableUtils { public static void setAuthenticatedUserId(Long userId) { @@ -11,4 +18,45 @@ public class FlowableUtils { public static void clearAuthenticatedUserId() { Authentication.setAuthenticatedUserId(null); } + + /** + * 获得 BPMN 流程中,指定的元素们 + * + * @param model + * @param clazz 指定元素。例如说,{@link org.flowable.bpmn.model.UserTask}、{@link org.flowable.bpmn.model.Gateway} 等等 + * @return 元素们 + */ + public static List getBpmnModelElements(BpmnModel model, Class clazz) { + List result = new ArrayList<>(); + model.getProcesses().forEach(process -> { + process.getFlowElements().forEach(flowElement -> { + if (flowElement.getClass().isAssignableFrom(clazz)) { + result.add((T) flowElement); + } + }); + }); + return result; + } + + /** + * 比较 两个bpmnModel 是否相同 + * @param oldModel 老的bpmn model + * @param newModel 新的bpmn model + */ + public static boolean equals(BpmnModel oldModel, BpmnModel newModel) { + // 由于 BpmnModel 未提供 equals 方法,所以只能转成字节数组,进行比较 + return Arrays.equals(getBpmnBytes(oldModel), getBpmnBytes(newModel)); + } + + /** + * 把 bpmnModel 转换成 byte[] + * @param model bpmnModel + */ + public static byte[] getBpmnBytes(BpmnModel model) { + if (model == null) { + return new byte[0]; + } + BpmnXMLConverter converter = new BpmnXMLConverter(); + return converter.convertToXML(model); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java index 874df456d..f22dcb04a 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.config; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmProcessInstanceEventListener; import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; @@ -27,8 +28,9 @@ import java.util.List; public class BpmFlowableConfiguration { /** - * 将自定义 listener 加入全局listener + * Flowable engines 自定义的配置 * @param listeners 自定义 listener + * @param bpmActivityBehaviorFactory 自定义的 ActivityBehaviorFactory 实现 */ @Bean public EngineConfigurationConfigurer addCustomerListenerConfigurer (ObjectProvider listeners, @@ -51,14 +53,15 @@ public class BpmFlowableConfiguration { BpmUserGroupService userGroupService, PermissionApi permissionApi, DeptApi deptApi, - AdminUserApi adminUserApi) { + AdminUserApi adminUserApi, + List scripts) { BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory(); bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService); bpmActivityBehaviorFactory.setUserGroupService(userGroupService); bpmActivityBehaviorFactory.setAdminUserApi(adminUserApi); bpmActivityBehaviorFactory.setPermissionApi(permissionApi); bpmActivityBehaviorFactory.setDeptApi(deptApi); -// bpmActivityBehaviorFactory.setScripts(scripts); + bpmActivityBehaviorFactory.setScripts(scripts); return bpmActivityBehaviorFactory; } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java index 784cd4f69..0d8de4f62 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -13,6 +14,8 @@ import org.flowable.bpmn.model.UserTask; import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior; import org.flowable.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory; +import java.util.List; + /** * 自定义的 ActivityBehaviorFactory 实现类,目的如下: * 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配 @@ -35,6 +38,8 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory { private DeptApi deptApi; @Setter private AdminUserApi adminUserApi; + @Setter + private List scripts; @Override public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) { @@ -44,8 +49,7 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory { userTaskActivityBehavior.setDeptApi(deptApi); userTaskActivityBehavior.setUserGroupService(userGroupService); userTaskActivityBehavior.setAdminUserApi(adminUserApi); - //TODO - //userTaskActivityBehavior.setScripts(scripts); + userTaskActivityBehavior.setScripts(scripts); return userTaskActivityBehavior; } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java index 202ef09fc..e364b3199 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 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.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -30,8 +31,10 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntity; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER; /** @@ -56,9 +59,17 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { @Setter private PermissionApi permissionApi; + /** + * 任务分配脚本 + */ + private Map scriptMap = Collections.emptyMap(); + public BpmUserTaskActivityBehavior(UserTask userTask) { super(userTask); } + public void setScripts(List scripts) { + this.scriptMap = convertMap(scripts, script -> script.getEnum().getId()); + } @Override protected void handleAssignments(TaskService taskService, String assignee, String owner, List candidateUsers, List candidateGroups, TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) { @@ -100,10 +111,9 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule); } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) { assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule); } -// else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) { -// assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule); -// } // 移除被禁用的用户 removeDisableUsers(assigneeUserIds); @@ -146,6 +156,22 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { return userIds; } + private Set calculateTaskCandidateUsersByScript(TaskEntity task, BpmTaskAssignRuleDO rule) { + // 获得对应的脚本 + List scripts = new ArrayList<>(rule.getOptions().size()); + rule.getOptions().forEach(id -> { + BpmTaskAssignScript script = scriptMap.get(id); + if (script == null) { + throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id); + } + scripts.add(script); + }); + // 逐个计算任务 + Set userIds = new HashSet<>(); + scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(task))); + return userIds; + } + private Long chooseTaskAssignee(Set candidateUserIds) { // TODO 芋艿:未来可以优化下,改成轮询的策略 int index = RandomUtil.randomInt(candidateUserIds.size()); diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java new file mode 100644 index 000000000..10392c714 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script; + +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; + +import java.util.Set; + +/** + * Bpm 任务分配的自定义 Script 脚本 + * 使用场景: + * 1. 设置审批人为发起人 + * 2. 设置审批人为发起人的 Leader + * 3. 甚至审批人为发起人的 Leader 的 Leader + * + * @author 芋道源码 + */ +public interface BpmTaskAssignScript { + + /** + * 基于流程任务,获得任务的候选用户们 + * + * @param task 任务 + * @return 候选人用户的编号数组 + */ + Set calculateTaskCandidateUsers(TaskEntity task); + + /** + * 获得枚举值 + * + * @return 枚举值 + */ + BpmTaskRuleScriptEnum getEnum(); +} + diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java new file mode 100644 index 000000000..06b8c52f0 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java @@ -0,0 +1,71 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; + +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; +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 org.flowable.engine.runtime.ProcessInstance; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; +import org.springframework.context.annotation.Lazy; +import org.springframework.util.Assert; + +import javax.annotation.Resource; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static java.util.Collections.emptySet; + +/** + * 分配给发起人的 Leader 审批的 Script 实现类 + * 目前 Leader 的定义是, + * + * @author 芋道源码 + */ +public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssignScript { + + @Resource + private AdminUserApi adminUserApi; + @Resource + private DeptApi deptApi; + @Resource + @Lazy // 解决循环依赖 + private BpmProcessInstanceService bpmProcessInstanceService; + + protected Set calculateTaskCandidateUsers(TaskEntity task, int level) { + Assert.isTrue(level > 0, "level 必须大于 0"); + // 获得发起人 + ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(task.getProcessInstanceId()); + Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); + // 获得对应 leve 的部门 + DeptRespDTO dept = null; + for (int i = 0; i < level; i++) { + // 获得 level 对应的部门 + if (dept == null) { + dept = getStartUserDept(startUserId); + if (dept == null) { // 找不到发起人的部门,所以无法使用该规则 + return emptySet(); + } + } else { + DeptRespDTO parentDept = deptApi.getDept(dept.getParentId()); + if (parentDept == null) { // 找不到父级部门,所以只好结束寻找。原因是:例如说,级别比较高的人,所在部门层级比较少 + break; + } + dept = parentDept; + } + } + return dept.getLeaderUserId() != null ? asSet(dept.getLeaderUserId()) : emptySet(); + } + + private DeptRespDTO getStartUserDept(Long startUserId) { + AdminUserRespDTO startUser = adminUserApi.getUser(startUserId); + if (startUser.getDeptId() == null) { // 找不到部门,所以无法使用该规则 + return null; + } + return deptApi.getDept(startUser.getDeptId()); + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java new file mode 100644 index 000000000..55e7df7b8 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; + +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; +import org.springframework.stereotype.Component; + +import java.util.Set; + +/** + * 分配给发起人的一级 Leader 审批的 Script 实现类 + * + * @author 芋道源码 + */ +@Component +public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript { + + @Override + public Set calculateTaskCandidateUsers(TaskEntity task) { + return calculateTaskCandidateUsers(task, 1); + } + + @Override + public BpmTaskRuleScriptEnum getEnum() { + return BpmTaskRuleScriptEnum.LEADER_X1; + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java new file mode 100644 index 000000000..a4455ea40 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; + +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; +import org.springframework.stereotype.Component; + +import java.util.Set; + +/** + * 分配给发起人的二级 Leader 审批的 Script 实现类 + * + * @author 芋道源码 + */ +@Component +public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript { + + @Override + public Set calculateTaskCandidateUsers(TaskEntity task) { + return calculateTaskCandidateUsers(task, 2); + } + + @Override + public BpmTaskRuleScriptEnum getEnum() { + return BpmTaskRuleScriptEnum.LEADER_X2; + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java new file mode 100644 index 000000000..653918b0b --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java @@ -0,0 +1,41 @@ +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.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.runtime.ProcessInstance; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Set; + +/** + * 分配给发起人审批的 Script 实现类 + * + * @author 芋道源码 + */ +@Component +public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript { + + @Resource + @Lazy // 解决循环依赖 + private BpmProcessInstanceService bpmProcessInstanceService; + + @Override + public Set calculateTaskCandidateUsers(TaskEntity task) { + ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(task.getProcessInstanceId()); + Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); + return SetUtils.asSet(startUserId); + } + + @Override + public BpmTaskRuleScriptEnum getEnum() { + return BpmTaskRuleScriptEnum.START_USER; + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java index d75a1bd68..694da78d4 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.PageUtils; +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; @@ -198,7 +199,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ BpmnModel newModel = buildBpmnModel(createReqDTO.getBpmnBytes()); BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId()); //TODO 貌似 flowable 不修改这个也不同。需要看看。 sourceSystemId 不同 - if (equals(oldModel, newModel)) { + if (FlowableUtils.equals(oldModel, newModel)) { return false; } // 最终发现都一致,则返回 true @@ -216,19 +217,8 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ BpmnXMLConverter converter = new BpmnXMLConverter(); return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true); } - //TODO 移出去 - public boolean equals(BpmnModel oldModel, BpmnModel newModel) { - // 由于 BpmnModel 未提供 equals 方法,所以只能转成字节数组,进行比较 - return Arrays.equals(getBpmnBytes(oldModel), getBpmnBytes(newModel)); - } - //TODO 移出去 - public byte[] getBpmnBytes(BpmnModel model) { - if (model == null) { - return new byte[0]; - } - BpmnXMLConverter converter = new BpmnXMLConverter(); - return converter.convertToXML(model); - } + + @Override public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) { diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index b1a12e71c..6d6430da8 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; @@ -87,37 +88,15 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ if (model == null) { return Collections.emptyList(); } - // 获得用户任务,只有用户任务才可以设置分配规则 - List userTasks = getBpmnModelElements(model, UserTask.class); + List userTasks = FlowableUtils.getBpmnModelElements(model, UserTask.class); if (CollUtil.isEmpty(userTasks)) { return Collections.emptyList(); } - // 转换数据 return BpmTaskAssignRuleConvert.INSTANCE.convertList(userTasks, rules); } - /** - * TODO 需要移出去 - * 获得 BPMN 流程中,指定的元素们 - * - * @param model - * @param clazz 指定元素。例如说,{@link org.flowable.bpmn.model.UserTask}、{@link org.flowable.bpmn.model.Gateway} 等等 - * @return 元素们 - */ - public static List getBpmnModelElements(BpmnModel model, Class clazz) { - List result = new ArrayList<>(); - model.getProcesses().forEach(process -> { - process.getFlowElements().forEach(flowElement -> { - if (flowElement.getClass().isAssignableFrom(clazz)) { - result.add((T) flowElement); - } - }); - }); - return result; - } - @Override public Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO) { // 校验参数 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index 440ecd916..9c21bd8a9 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -106,6 +106,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService } @Override + @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 4028679e0..5c004977c 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -25,6 +25,7 @@ import org.flowable.task.api.TaskQuery; import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.api.history.HistoricTaskInstanceQuery; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; @@ -167,6 +168,7 @@ public class BpmTaskServiceImpl implements BpmTaskService{ } @Override + @Transactional(rollbackFor = Exception.class) public void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO) { // 校验任务存在 Task task = checkTask(userId, reqVO.getId()); @@ -184,6 +186,7 @@ public class BpmTaskServiceImpl implements BpmTaskService{ } @Override + @Transactional(rollbackFor = Exception.class) public void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO) { Task task = checkTask(userId, reqVO.getId()); // 校验流程实例存在 @@ -234,16 +237,15 @@ public class BpmTaskServiceImpl implements BpmTaskService{ .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())) .setTaskId(task.getId()); taskExtMapper.updateByTaskId(taskExtDO); - //TODO 创建任务时候 也会调用 updateTaskExtAssign, processInstance 名称为空 校验不通过 // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。 -// TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { -// @Override -// public void afterCommit() { -// ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); -// AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId())); -// messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task)); -// } -// }); + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + @Override + public void afterCommit() { + ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); + AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId())); + messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task)); + } + }); } /** From 1f08a2725e337233d2c9719f8c04deea622a92de Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Thu, 17 Feb 2022 23:59:05 +0800 Subject: [PATCH 14/19] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=20=E5=88=86=E9=85=8Dleader=20=E5=AE=A1=E6=89=B9=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=20=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml | 4 ++++ .../flowable/core/behavior/BpmUserTaskActivityBehavior.java | 3 +++ .../behavior/script/impl/BpmTaskAssignLeaderX1Script.java | 3 +++ .../behavior/script/impl/BpmTaskAssignLeaderX2Script.java | 5 +++++ 4 files changed, 15 insertions(+) diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml b/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml index ea48aaf90..ffd2412e5 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml @@ -26,6 +26,10 @@ cn.iocoder.boot yudao-spring-boot-starter-flowable + + cn.iocoder.boot + yudao-spring-boot-starter-biz-data-permission + org.flowable flowable-spring-boot-starter-actuator diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java index e364b3199..fb2551cbc 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java @@ -4,6 +4,8 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; +import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule; 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.enums.definition.BpmTaskAssignRuleTypeEnum; @@ -183,6 +185,7 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { if (CollUtil.isEmpty(assigneeUserIds)) { return; } + //TODO 芋艿 这里有数据权限的问题。默认会加上数据权限 dept_id IN (deptId). 导致查询不到数据 Map userMap = adminUserApi.getUserMap(assigneeUserIds); assigneeUserIds.removeIf(id -> { AdminUserRespDTO user = userMap.get(id); diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java index 55e7df7b8..fef8ecc4b 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; +import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.springframework.stereotype.Component; @@ -15,6 +17,7 @@ import java.util.Set; public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript { @Override + @DataPermission(excludeRules = DeptDataPermissionRule.class) public Set calculateTaskCandidateUsers(TaskEntity task) { return calculateTaskCandidateUsers(task, 1); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java index a4455ea40..ccb4b944e 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; +import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.springframework.stereotype.Component; @@ -14,7 +16,10 @@ import java.util.Set; @Component public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript { + @Override + //不需要处理数据权限, 不然会有问题,查询不到数据 + @DataPermission(excludeRules = DeptDataPermissionRule.class) public Set calculateTaskCandidateUsers(TaskEntity task) { return calculateTaskCandidateUsers(task, 2); } From d8d81e835f71cea69de06da584024fcc10c90494 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Fri, 18 Feb 2022 12:03:45 +0800 Subject: [PATCH 15/19] =?UTF-8?q?=E5=90=88=E5=B9=B6=20master=20=E5=88=86?= =?UTF-8?q?=E6=94=AF,=20=E4=BF=AE=E6=94=B9=E5=AF=BC=E5=85=A5=E6=B5=81?= =?UTF-8?q?=E7=A8=8Bbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bpm/controller/admin/definition/BpmModelController.java | 1 + .../iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java | 1 + .../module/bpm/service/definition/BpmModelServiceImpl.java | 2 ++ yudao-ui-admin/src/views/bpm/model/index.vue | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java index 1bac1888e..3dd0a0a4d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java @@ -61,6 +61,7 @@ public class BpmModelController { @PostMapping("/import") @ApiOperation(value = "导入模型") + @PreAuthorize("@ss.hasPermission('bpm:model:import')") public CommonResult importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException { BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO); // 读取文件 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java index 32f536959..d128dba2c 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java @@ -108,6 +108,7 @@ public interface BpmTaskConvert { BpmTaskRespVO.User convert3(AdminUserRespDTO bean); + @Mapping(target = "id", ignore = true) void copyTo(BpmTaskExtDO from, @MappingTarget BpmTaskDonePageItemRespVO to); @Mappings({ diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java index 7c4e0b208..dcb0b9e47 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java @@ -132,6 +132,7 @@ public class BpmModelServiceImpl implements BpmModelService { } @Override + @Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务 public void updateModel(@Valid BpmModelUpdateReqVO updateReqVO) { // 校验流程模型存在 Model model = repositoryService.getModel(updateReqVO.getId()); @@ -148,6 +149,7 @@ public class BpmModelServiceImpl implements BpmModelService { } @Override + @Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务 public void deployModel(String id) { // 校验流程模型存在 Model model = repositoryService.getModel(id); diff --git a/yudao-ui-admin/src/views/bpm/model/index.vue b/yudao-ui-admin/src/views/bpm/model/index.vue index d3f157b33..029ad9f60 100644 --- a/yudao-ui-admin/src/views/bpm/model/index.vue +++ b/yudao-ui-admin/src/views/bpm/model/index.vue @@ -291,7 +291,7 @@ export default { // 设置上传的请求头部 headers: getBaseHeader(), // 上传的地址 - url: process.env.VUE_APP_BASE_API + '/admin-api/' + "/bpm/model/import", + url: process.env.VUE_APP_BASE_API + '/admin-api' + "/bpm/model/import", // 表单 form: {}, // 校验规则 From 5d90760c39ca74bb29a2148f5b4b241e3562b785 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 27 Feb 2022 16:28:43 +0800 Subject: [PATCH 16/19] =?UTF-8?q?v.1.5.1=20=E5=8F=91=E5=B8=83=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=A4=9A=E7=A7=9F=E6=88=B7=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E8=87=AA=E5=8A=A8=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E3=80=81=E8=A7=92=E8=89=B2=E7=AD=89=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/ruoyi-vue-pro.sql | 23 +++++++++++-------- .../service/tenant/TenantServiceImpl.java | 11 ++++++--- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/sql/ruoyi-vue-pro.sql b/sql/ruoyi-vue-pro.sql index 954028769..0692c8761 100644 --- a/sql/ruoyi-vue-pro.sql +++ b/sql/ruoyi-vue-pro.sql @@ -11,7 +11,7 @@ Target Server Version : 80026 File Encoding : 65001 - Date: 27/02/2022 13:16:21 + Date: 27/02/2022 16:28:08 */ SET NAMES utf8mb4; @@ -1169,7 +1169,7 @@ CREATE TABLE `infra_api_error_log` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=290 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统异常日志'; +) ENGINE=InnoDB AUTO_INCREMENT=291 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统异常日志'; -- ---------------------------- -- Records of infra_api_error_log @@ -1235,6 +1235,7 @@ INSERT INTO `infra_api_error_log` VALUES (286, '', 104, 2, 'yudao-admin-server', INSERT INTO `infra_api_error_log` VALUES (287, '', 104, 2, 'yudao-admin-server', 'GET', '/admin-api/system/user/page', '{\"query\":{\"pageNo\":\"1\",\"pageSize\":\"10\"},\"body\":\"\"}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', '2022-02-27 11:43:12', 'org.mybatis.spring.MyBatisSystemException', 'MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database. Cause: java.lang.NullPointerException\n### Cause: java.lang.NullPointerException', 'NullPointerException: null', 'org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database. Cause: java.lang.NullPointerException\n### Cause: java.lang.NullPointerException\n at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96)\n at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)\n at com.sun.proxy.$Proxy131.selectList(Unknown Source)\n at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224)\n at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForIPage(MybatisMapperMethod.java:121)\n at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:85)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)\n at com.sun.proxy.$Proxy189.selectPage(Unknown Source)\n at cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX.selectPage(BaseMapperX.java:25)\n at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:162)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)\n at com.sun.proxy.$Proxy189.selectPage(Unknown Source)\n at cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper.selectPage(AdminUserMapper.java:31)\n at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:162)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)\n at com.sun.proxy.$Proxy189.selectPage(Unknown Source)\n at cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl.getUserPage(AdminUserServiceImpl.java:172)\n at cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl$$FastClassBySpringCGLIB$$b9a860de.invoke()\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)\n at cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl$$EnhancerBySpringCGLIB$$b11b0ddc.getUserPage()\n at cn.iocoder.yudao.module.system.controller.admin.user.UserController.getUserPage(UserController.java:94)\n at cn.iocoder.yudao.module.system.controller.admin.user.UserController$$FastClassBySpringCGLIB$$bc2558c0.invoke()\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:123)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)\n at cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect.around0(OperateLogAspect.java:96)\n at cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect.around(OperateLogAspect.java:77)\n at sun.reflect.GeneratedMethodAccessor319.invoke(Unknown Source)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)\n at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:61)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)\n at cn.iocoder.yudao.module.system.controller.admin.user.UserController$$EnhancerBySpringCGLIB$$98330277.getUserPage()\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)\n at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)\n at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\n at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\n at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)\n at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)\n at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\n at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)\n at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at de.codecentric.boot.admin.server.ui.web.servlet.HomepageForwardingFilter.doFilter(HomepageForwardingFilter.java:78)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:111)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:124)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.activiti.core.web.ActivitiWebFilter.doFilterInternal(ActivitiWebFilter.java:30)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter.doFilterInternal(TenantSecurityWebFilter.java:98)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121)\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at cn.iocoder.yudao.framework.security.core.filter.JWTAuthenticationTokenFilter.doFilterInternal(JWTAuthenticationTokenFilter.java:60)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)\n at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)\n at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)\n at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)\n at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter.doFilterInternal(TenantContextWebFilter.java:32)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.tracer.core.filter.TraceFilter.doFilterInternal(TraceFilter.java:30)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)\n at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\n at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)\n at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)\n at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\n at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\n at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)\n at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)\n at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\n at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)\n at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)\n at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\n at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)\n at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)\n at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\n at java.lang.Thread.run(Thread.java:748)\nCaused by: org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database. Cause: java.lang.NullPointerException\n### Cause: java.lang.NullPointerException\n at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:153)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)\n at sun.reflect.GeneratedMethodAccessor278.invoke(Unknown Source)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)\n ... 183 more\nCaused by: java.lang.NullPointerException\n at cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule.getExpression(DeptDataPermissionRule.java:116)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.buildDataPermissionExpression(DataPermissionDatabaseInterceptor.java:379)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.builderExpression(DataPermissionDatabaseInterceptor.java:341)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.processPlainSelect(DataPermissionDatabaseInterceptor.java:154)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.processSelectBody(DataPermissionDatabaseInterceptor.java:115)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.processSelect(DataPermissionDatabaseInterceptor.java:103)\n at com.baomidou.mybatisplus.extension.parser.JsqlParserSupport.processParser(JsqlParserSupport.java:91)\n at com.baomidou.mybatisplus.extension.parser.JsqlParserSupport.parserSingle(JsqlParserSupport.java:50)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.beforeQuery(DataPermissionDatabaseInterceptor.java:69)\n at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:78)\n at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)\n at com.sun.proxy.$Proxy154.query(Unknown Source)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151)\n ... 189 more\n', 'org.mybatis.spring.MyBatisExceptionTranslator', 'MyBatisExceptionTranslator.java', 'translateExceptionIfPossible', 96, 0, NULL, 0, NULL, '2022-02-27 11:43:12', NULL, '2022-02-27 11:43:12', b'0', 1); INSERT INTO `infra_api_error_log` VALUES (288, '', 104, 2, 'yudao-admin-server', 'GET', '/admin-api/system/dept/list-all-simple', '{\"query\":{},\"body\":\"\"}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', '2022-02-27 11:47:41', 'org.mybatis.spring.MyBatisSystemException', 'MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database. Cause: java.lang.NullPointerException\n### Cause: java.lang.NullPointerException', 'NullPointerException: null', 'org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database. Cause: java.lang.NullPointerException\n### Cause: java.lang.NullPointerException\n at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96)\n at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)\n at com.sun.proxy.$Proxy131.selectList(Unknown Source)\n at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224)\n at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:166)\n at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:77)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)\n at com.sun.proxy.$Proxy159.selectList(Unknown Source)\n at cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper.selectList(DeptMapper.java:18)\n at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:162)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)\n at com.sun.proxy.$Proxy159.selectList(Unknown Source)\n at cn.iocoder.yudao.module.system.service.dept.DeptServiceImpl.getSimpleDepts(DeptServiceImpl.java:174)\n at cn.iocoder.yudao.module.system.service.dept.DeptServiceImpl$$FastClassBySpringCGLIB$$c56b7507.invoke()\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:123)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)\n at cn.iocoder.yudao.module.system.service.dept.DeptServiceImpl$$EnhancerBySpringCGLIB$$ebcdbef1.getSimpleDepts()\n at cn.iocoder.yudao.module.system.controller.admin.dept.DeptController.getSimpleDepts(DeptController.java:72)\n at cn.iocoder.yudao.module.system.controller.admin.dept.DeptController$$FastClassBySpringCGLIB$$1d18500.invoke()\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:123)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)\n at cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect.around0(OperateLogAspect.java:96)\n at cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect.around(OperateLogAspect.java:77)\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)\n at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)\n at cn.iocoder.yudao.module.system.controller.admin.dept.DeptController$$EnhancerBySpringCGLIB$$e292a6a6.getSimpleDepts()\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)\n at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)\n at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\n at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\n at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)\n at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)\n at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\n at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)\n at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at de.codecentric.boot.admin.server.ui.web.servlet.HomepageForwardingFilter.doFilter(HomepageForwardingFilter.java:78)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:111)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:124)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.activiti.core.web.ActivitiWebFilter.doFilterInternal(ActivitiWebFilter.java:30)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter.doFilterInternal(TenantSecurityWebFilter.java:98)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121)\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at cn.iocoder.yudao.framework.security.core.filter.JWTAuthenticationTokenFilter.doFilterInternal(JWTAuthenticationTokenFilter.java:60)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)\n at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)\n at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)\n at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)\n at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter.doFilterInternal(TenantContextWebFilter.java:32)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.tracer.core.filter.TraceFilter.doFilterInternal(TraceFilter.java:30)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)\n at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\n at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)\n at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)\n at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\n at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\n at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)\n at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)\n at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\n at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)\n at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)\n at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\n at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)\n at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)\n at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\n at java.lang.Thread.run(Thread.java:748)\nCaused by: org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database. Cause: java.lang.NullPointerException\n### Cause: java.lang.NullPointerException\n at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:153)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)\n ... 185 more\nCaused by: java.lang.NullPointerException\n at cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule.getExpression(DeptDataPermissionRule.java:116)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.buildDataPermissionExpression(DataPermissionDatabaseInterceptor.java:379)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.builderExpression(DataPermissionDatabaseInterceptor.java:341)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.processPlainSelect(DataPermissionDatabaseInterceptor.java:154)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.processSelectBody(DataPermissionDatabaseInterceptor.java:115)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.processSelect(DataPermissionDatabaseInterceptor.java:103)\n at com.baomidou.mybatisplus.extension.parser.JsqlParserSupport.processParser(JsqlParserSupport.java:91)\n at com.baomidou.mybatisplus.extension.parser.JsqlParserSupport.parserSingle(JsqlParserSupport.java:50)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.beforeQuery(DataPermissionDatabaseInterceptor.java:69)\n at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:78)\n at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)\n at com.sun.proxy.$Proxy154.query(Unknown Source)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151)\n ... 192 more\n', 'org.mybatis.spring.MyBatisExceptionTranslator', 'MyBatisExceptionTranslator.java', 'translateExceptionIfPossible', 96, 0, NULL, 0, NULL, '2022-02-27 11:47:43', NULL, '2022-02-27 11:47:43', b'0', 1); INSERT INTO `infra_api_error_log` VALUES (289, '', 104, 2, 'yudao-admin-server', 'GET', '/admin-api/system/user/page', '{\"query\":{\"pageNo\":\"1\",\"pageSize\":\"10\"},\"body\":\"\"}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', '2022-02-27 11:47:43', 'org.mybatis.spring.MyBatisSystemException', 'MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database. Cause: java.lang.NullPointerException\n### Cause: java.lang.NullPointerException', 'NullPointerException: null', 'org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database. Cause: java.lang.NullPointerException\n### Cause: java.lang.NullPointerException\n at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96)\n at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)\n at com.sun.proxy.$Proxy131.selectList(Unknown Source)\n at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224)\n at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForIPage(MybatisMapperMethod.java:121)\n at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:85)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)\n at com.sun.proxy.$Proxy189.selectPage(Unknown Source)\n at cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX.selectPage(BaseMapperX.java:25)\n at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:162)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)\n at com.sun.proxy.$Proxy189.selectPage(Unknown Source)\n at cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper.selectPage(AdminUserMapper.java:31)\n at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:162)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)\n at com.sun.proxy.$Proxy189.selectPage(Unknown Source)\n at cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl.getUserPage(AdminUserServiceImpl.java:172)\n at cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl$$FastClassBySpringCGLIB$$b9a860de.invoke()\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)\n at cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl$$EnhancerBySpringCGLIB$$23e8d9cb.getUserPage()\n at cn.iocoder.yudao.module.system.controller.admin.user.UserController.getUserPage(UserController.java:94)\n at cn.iocoder.yudao.module.system.controller.admin.user.UserController$$FastClassBySpringCGLIB$$bc2558c0.invoke()\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:123)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)\n at cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect.around0(OperateLogAspect.java:96)\n at cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect.around(OperateLogAspect.java:77)\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)\n at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:61)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)\n at cn.iocoder.yudao.module.system.controller.admin.user.UserController$$EnhancerBySpringCGLIB$$83b079e6.getUserPage()\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)\n at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)\n at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\n at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\n at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)\n at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)\n at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\n at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)\n at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at de.codecentric.boot.admin.server.ui.web.servlet.HomepageForwardingFilter.doFilter(HomepageForwardingFilter.java:78)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:111)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:124)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.activiti.core.web.ActivitiWebFilter.doFilterInternal(ActivitiWebFilter.java:30)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter.doFilterInternal(TenantSecurityWebFilter.java:98)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121)\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at cn.iocoder.yudao.framework.security.core.filter.JWTAuthenticationTokenFilter.doFilterInternal(JWTAuthenticationTokenFilter.java:60)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)\n at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)\n at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)\n at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)\n at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter.doFilterInternal(TenantContextWebFilter.java:32)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.tracer.core.filter.TraceFilter.doFilterInternal(TraceFilter.java:30)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)\n at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\n at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)\n at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)\n at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\n at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\n at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)\n at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)\n at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\n at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)\n at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)\n at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\n at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)\n at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)\n at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\n at java.lang.Thread.run(Thread.java:748)\nCaused by: org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database. Cause: java.lang.NullPointerException\n### Cause: java.lang.NullPointerException\n at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:153)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)\n at sun.reflect.GeneratedMethodAccessor272.invoke(Unknown Source)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)\n ... 184 more\nCaused by: java.lang.NullPointerException\n at cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule.getExpression(DeptDataPermissionRule.java:116)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.buildDataPermissionExpression(DataPermissionDatabaseInterceptor.java:379)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.builderExpression(DataPermissionDatabaseInterceptor.java:341)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.processPlainSelect(DataPermissionDatabaseInterceptor.java:154)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.processSelectBody(DataPermissionDatabaseInterceptor.java:115)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.processSelect(DataPermissionDatabaseInterceptor.java:103)\n at com.baomidou.mybatisplus.extension.parser.JsqlParserSupport.processParser(JsqlParserSupport.java:91)\n at com.baomidou.mybatisplus.extension.parser.JsqlParserSupport.parserSingle(JsqlParserSupport.java:50)\n at cn.iocoder.yudao.framework.datapermission.core.db.DataPermissionDatabaseInterceptor.beforeQuery(DataPermissionDatabaseInterceptor.java:69)\n at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:78)\n at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)\n at com.sun.proxy.$Proxy154.query(Unknown Source)\n at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151)\n ... 190 more\n', 'org.mybatis.spring.MyBatisExceptionTranslator', 'MyBatisExceptionTranslator.java', 'translateExceptionIfPossible', 96, 0, NULL, 0, NULL, '2022-02-27 11:47:43', NULL, '2022-02-27 11:47:43', b'0', 1); +INSERT INTO `infra_api_error_log` VALUES (290, '', 0, 0, 'yudao-admin-server', 'POST', '/admin-api/system/login', '{\"query\":{},\"body\":\"{\\\"username\\\":\\\"admin\\\",\\\"password\\\":\\\"admin123\\\",\\\"code\\\":\\\"oo6v3\\\",\\\"uuid\\\":\\\"981b710d1bc94ac4bc0cd41c3468d7d3\\\"}\"}', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', '2022-02-27 16:25:59', 'com.baomidou.mybatisplus.core.exceptions.MybatisPlusException', 'MybatisPlusException: One record is expected, but the query result is multiple records', 'MybatisPlusException: One record is expected, but the query result is multiple records', 'com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: One record is expected, but the query result is multiple records\n at com.baomidou.mybatisplus.core.toolkit.ExceptionUtils.mpe(ExceptionUtils.java:49)\n at com.baomidou.mybatisplus.core.mapper.BaseMapper.selectOne(BaseMapper.java:177)\n at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:162)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)\n at com.sun.proxy.$Proxy154.selectOne(Unknown Source)\n at cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper.selectByUsername(AdminUserMapper.java:19)\n at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:162)\n at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)\n at com.sun.proxy.$Proxy154.selectByUsername(Unknown Source)\n at cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl.getUserByUsername(AdminUserServiceImpl.java:167)\n at cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl$$FastClassBySpringCGLIB$$b9a860de.invoke()\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)\n at cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl$$EnhancerBySpringCGLIB$$3e8ecaaa.getUserByUsername()\n at cn.iocoder.yudao.module.system.service.auth.AdminAuthServiceImpl.loadUserByUsername(AdminAuthServiceImpl.java:80)\n at cn.iocoder.yudao.framework.security.core.authentication.MultiUserDetailsAuthenticationProvider.retrieveUser(MultiUserDetailsAuthenticationProvider.java:56)\n at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:133)\n at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182)\n at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:201)\n at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:518)\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)\n at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)\n at com.sun.proxy.$Proxy148.authenticate(Unknown Source)\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)\n at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)\n at com.sun.proxy.$Proxy148.authenticate(Unknown Source)\n at cn.iocoder.yudao.module.system.service.auth.AdminAuthServiceImpl.login0(AdminAuthServiceImpl.java:145)\n at cn.iocoder.yudao.module.system.service.auth.AdminAuthServiceImpl.login(AdminAuthServiceImpl.java:107)\n at cn.iocoder.yudao.module.system.controller.admin.auth.AuthController.login(AuthController.java:60)\n at cn.iocoder.yudao.module.system.controller.admin.auth.AuthController$$FastClassBySpringCGLIB$$f866d2e0.invoke()\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:123)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)\n at cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect.around0(OperateLogAspect.java:89)\n at cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect.around(OperateLogAspect.java:77)\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)\n at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)\n at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)\n at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)\n at cn.iocoder.yudao.module.system.controller.admin.auth.AuthController$$EnhancerBySpringCGLIB$$73274b63.login()\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.lang.reflect.Method.invoke(Method.java:498)\n at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)\n at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)\n at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)\n at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\n at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\n at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)\n at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)\n at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\n at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)\n at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at de.codecentric.boot.admin.server.ui.web.servlet.HomepageForwardingFilter.doFilter(HomepageForwardingFilter.java:78)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:111)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:124)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.activiti.core.web.ActivitiWebFilter.doFilterInternal(ActivitiWebFilter.java:30)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)\n at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121)\n at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)\n at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at cn.iocoder.yudao.framework.security.core.filter.JWTAuthenticationTokenFilter.doFilterInternal(JWTAuthenticationTokenFilter.java:60)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)\n at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)\n at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)\n at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)\n at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)\n at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)\n at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)\n at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.web.core.filter.CacheRequestBodyFilter.doFilterInternal(CacheRequestBodyFilter.java:22)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at cn.iocoder.yudao.framework.tracer.core.filter.TraceFilter.doFilterInternal(TraceFilter.java:30)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)\n at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\n at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\n at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\n at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)\n at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\n at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)\n at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)\n at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\n at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\n at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)\n at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)\n at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\n at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)\n at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)\n at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\n at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)\n at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)\n at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\n at java.lang.Thread.run(Thread.java:748)\n', 'com.baomidou.mybatisplus.core.toolkit.ExceptionUtils', 'ExceptionUtils.java', 'mpe', 49, 0, NULL, 0, NULL, '2022-02-27 16:25:59', NULL, '2022-02-27 16:25:59', b'0', 0); COMMIT; -- ---------------------------- @@ -2355,7 +2356,7 @@ CREATE TABLE `system_login_log` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=998 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统访问记录'; +) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统访问记录'; -- ---------------------------- -- Records of system_login_log @@ -2468,6 +2469,9 @@ INSERT INTO `system_login_log` VALUES (994, 100, '', 104, 2, 'test', 31, '127.0. INSERT INTO `system_login_log` VALUES (995, 100, '', 104, 2, 'test', 0, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 11:10:07', NULL, '2022-02-27 11:10:07', b'0', 1); INSERT INTO `system_login_log` VALUES (996, 100, '', 1, 2, 'admin', 31, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 11:56:16', NULL, '2022-02-27 11:56:16', b'0', 1); INSERT INTO `system_login_log` VALUES (997, 100, '', 1, 2, 'admin', 0, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 11:56:22', NULL, '2022-02-27 11:56:22', b'0', 1); +INSERT INTO `system_login_log` VALUES (998, 200, '', 1, 2, 'admin', 0, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 16:25:28', NULL, '2022-02-27 16:25:28', b'0', 0); +INSERT INTO `system_login_log` VALUES (999, 100, '', 1, 2, 'admin', 31, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 16:27:01', NULL, '2022-02-27 16:27:01', b'0', 0); +INSERT INTO `system_login_log` VALUES (1000, 100, '', 1, 2, 'admin', 0, '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 16:27:05', NULL, '2022-02-27 16:27:05', b'0', 0); COMMIT; -- ---------------------------- @@ -4759,14 +4763,14 @@ CREATE TABLE `system_user` ( -- Records of system_user -- ---------------------------- BEGIN; -INSERT INTO `system_user` VALUES (1, 'admin', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://127.0.0.1:48080/admin-api/infra/file/get/b7de3474-3805-4e09-80e3-185f20c31a74', 0, '127.0.0.1', '2022-02-27 11:56:22', 'admin', '2021-01-05 17:03:47', NULL, '2022-02-27 11:56:22', b'0', 1); +INSERT INTO `system_user` VALUES (1, 'admin', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://127.0.0.1:48080/admin-api/infra/file/get/b7de3474-3805-4e09-80e3-185f20c31a74', 0, '127.0.0.1', '2022-02-27 16:27:05', 'admin', '2021-01-05 17:03:47', NULL, '2022-02-27 16:27:05', b'0', 1); INSERT INTO `system_user` VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '', NULL, '', '2021-01-07 09:07:17', '104', '2021-12-16 09:26:10', b'0', 1); INSERT INTO `system_user` VALUES (103, 'yuanma', '$2a$10$wWoPT7sqriM2O1YXRL.je.GiL538OR6ZTN8aQZr9JAGdnpCH2tpYe', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '127.0.0.1', '2022-01-18 00:33:40', '', '2021-01-13 23:50:35', NULL, '2022-01-18 00:33:40', b'0', 1); INSERT INTO `system_user` VALUES (104, 'test', '$2a$10$scdhm8AdaYkG6XvV/R21xu7SEBhgyU7QmdmDLv7aR8iWV5IUiwVEC', '测试号', NULL, 107, '[]', '', '15601691200', 1, '', 0, '127.0.0.1', '2022-02-27 11:10:07', '', '2021-01-21 02:13:53', NULL, '2022-02-27 11:10:07', b'0', 1); -INSERT INTO `system_user` VALUES (107, 'admin', '$2a$10$dYOOBKMO93v/.ReCqzyFg.o67Tqk.bbc2bhrpyBGkIw9aypCtr2pm', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 22:59:33', '1', '2022-02-20 22:59:33', b'0', 118); -INSERT INTO `system_user` VALUES (108, 'admin', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2022-02-20 23:00:50', b'0', 119); -INSERT INTO `system_user` VALUES (109, 'admin', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2022-02-20 23:11:50', b'0', 120); -INSERT INTO `system_user` VALUES (110, 'admin', '$2a$10$qYxoXs0ogPHgYllyEneYde9xcCW5hZgukrxeXZ9lmLhKse8TK6IwW', '小王', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-02-23 19:36:28', '1', '2022-02-22 00:56:14', NULL, '2022-02-23 19:36:28', b'0', 121); +INSERT INTO `system_user` VALUES (107, 'admin107', '$2a$10$dYOOBKMO93v/.ReCqzyFg.o67Tqk.bbc2bhrpyBGkIw9aypCtr2pm', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 22:59:33', '1', '2022-02-27 08:26:51', b'0', 118); +INSERT INTO `system_user` VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2022-02-27 08:26:53', b'0', 119); +INSERT INTO `system_user` VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2022-02-27 08:26:56', b'0', 120); +INSERT INTO `system_user` VALUES (110, 'admin110', '$2a$10$qYxoXs0ogPHgYllyEneYde9xcCW5hZgukrxeXZ9lmLhKse8TK6IwW', '小王', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-02-23 19:36:28', '1', '2022-02-22 00:56:14', NULL, '2022-02-27 08:26:59', b'0', 121); INSERT INTO `system_user` VALUES (111, 'test', '$2a$10$mExveopHUx9Q4QiLtAzhDeH3n4/QlNLzEsM4AqgxKrU.ciUZDXZCy', '测试用户', NULL, NULL, '[]', '', '', 0, '', 0, '', NULL, '110', '2022-02-23 13:14:33', '110', '2022-02-23 13:14:33', b'0', 121); INSERT INTO `system_user` VALUES (112, 'newobject', '$2a$10$jh5MsR.ud/gKe3mVeUp5t.nEXGDSmHyv5OYjWQwHO8wlGmMSI9Twy', '新对象', NULL, NULL, '[]', '', '', 0, '', 0, '', NULL, '1', '2022-02-23 19:08:03', '1', '2022-02-23 19:08:03', b'0', 1); COMMIT; @@ -4833,9 +4837,10 @@ CREATE TABLE `system_user_session` ( -- Records of system_user_session -- ---------------------------- BEGIN; -INSERT INTO `system_user_session` VALUES ('0d7a900b4a5e4089a48a54a71bca83e6', 1, 2, '2022-02-28 11:56:22', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 11:56:22', NULL, '2022-02-27 11:56:22', b'0', 1); +INSERT INTO `system_user_session` VALUES ('0d7a900b4a5e4089a48a54a71bca83e6', 1, 2, '2022-02-28 11:56:22', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 11:56:22', NULL, '2022-02-27 08:25:28', b'1', 1); INSERT INTO `system_user_session` VALUES ('2935322c671b43fbbe7eb5532800bbcf', 110, 2, '2022-02-24 19:36:28', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-23 19:36:28', NULL, '2022-02-23 19:36:28', b'0', 121); INSERT INTO `system_user_session` VALUES ('3bb5bae78cc24cb5a1c1df9c479b50ad', 1, 2, '2022-02-21 23:57:11', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-20 23:57:11', NULL, '2022-02-20 23:57:11', b'0', 1); +INSERT INTO `system_user_session` VALUES ('9c93fd1cd23a43e3854451b781420aed', 1, 2, '2022-02-28 16:27:05', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 16:27:05', NULL, '2022-02-27 16:27:05', b'0', 0); INSERT INTO `system_user_session` VALUES ('b1bd95d813024acab14dd171ca887a94', 1, 2, '2022-02-28 10:52:17', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 10:52:17', NULL, '2022-02-27 10:52:17', b'0', 1); INSERT INTO `system_user_session` VALUES ('e769a8511c4043a886f68d1d6c39bddd', 104, 2, '2022-02-28 11:10:07', 'test', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-27 11:10:07', NULL, '2022-02-27 11:10:07', b'0', 1); INSERT INTO `system_user_session` VALUES ('ec60e16dfd2546e1a118eef7a42c07ef', 1, 2, '2022-02-24 22:33:28', 'admin', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', NULL, '2022-02-22 00:44:08', NULL, '2022-02-23 22:33:28', b'0', 1); diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java index 2cc877066..7f3b4008a 100755 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java +++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java @@ -32,6 +32,7 @@ import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler; import cn.iocoder.yudao.module.system.service.user.AdminUserService; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -80,7 +81,7 @@ public class TenantServiceImpl implements TenantService { @Getter private volatile Date maxUpdateTime; - @Resource + @Autowired(required = false) // 由于 yudao.tenant.enable 配置项,可以关闭多租户的功能,所以这里只能不强制注入 private TenantProperties tenantProperties; @Resource @@ -313,7 +314,7 @@ public class TenantServiceImpl implements TenantService { @Override public void handleTenantInfo(TenantInfoHandler handler) { // 如果禁用,则不执行逻辑 - if (Boolean.FALSE.equals(tenantProperties.getEnable())) { + if (isTenantDisable()) { return; } // 获得租户 @@ -325,7 +326,7 @@ public class TenantServiceImpl implements TenantService { @Override public void handleTenantMenu(TenantMenuHandler handler) { // 如果禁用,则不执行逻辑 - if (Boolean.FALSE.equals(tenantProperties.getEnable())) { + if (isTenantDisable()) { return; } // 获得租户,然后获得菜单 @@ -344,4 +345,8 @@ public class TenantServiceImpl implements TenantService { return Objects.equals(tenant.getPackageId(), TenantDO.PACKAGE_ID_SYSTEM); } + private boolean isTenantDisable() { + return tenantProperties == null || Boolean.FALSE.equals(tenantProperties.getEnable()); + } + } From 32012880368051d4842a6c65606a1b3fbec25f62 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 28 Feb 2022 00:58:11 +0800 Subject: [PATCH 17/19] =?UTF-8?q?review=20flowable=20=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=AE=9E=E7=8E=B0=EF=BC=8C=E6=B5=8B=E8=AF=95=E9=80=9A?= =?UTF-8?q?=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/{activiti.sql => bpm_activiti.sql} | 0 sql/bpm_flowable.sql | 1329 +++++++++++++++++ .../pom.xml | 8 +- .../yudao-module-bpm-base/pom.xml | 4 + .../api/task/BpmProcessInstanceApiImpl.java | 2 +- .../admin/definition/BpmModelController.java | 1 - .../impl/BpmTaskAssignLeaderX1Script.java | 2 + .../impl/BpmTaskAssignLeaderX2Script.java | 2 + .../yudao-module-bpm-impl-flowable/pom.xml | 10 +- .../api/task/BpmProcessInstanceApiImpl.java | 1 + .../BpmTaskAssignRuleController.java | 1 - .../config/BpmFlowableConfiguration.java | 33 +- .../impl/BpmTaskAssignLeaderX1Script.java | 3 +- .../impl/BpmTaskAssignLeaderX2Script.java | 4 +- .../module/bpm/framework/package-info.java | 6 + .../BpmProcessDefinitionServiceImpl.java | 1 - yudao-server/pom.xml | 9 +- .../src/main/resources/application-local.yaml | 6 +- .../src/main/resources/application.yaml | 13 +- 19 files changed, 1396 insertions(+), 39 deletions(-) rename sql/{activiti.sql => bpm_activiti.sql} (100%) create mode 100644 sql/bpm_flowable.sql create mode 100644 yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java diff --git a/sql/activiti.sql b/sql/bpm_activiti.sql similarity index 100% rename from sql/activiti.sql rename to sql/bpm_activiti.sql diff --git a/sql/bpm_flowable.sql b/sql/bpm_flowable.sql new file mode 100644 index 000000000..d5d4ee33d --- /dev/null +++ b/sql/bpm_flowable.sql @@ -0,0 +1,1329 @@ +/* + Navicat Premium Data Transfer + + Source Server : 127.0.0.1 + Source Server Type : MySQL + Source Server Version : 80026 + Source Host : localhost:3306 + Source Schema : ruoyi-vue-pro-flowable + + Target Server Type : MySQL + Target Server Version : 80026 + File Encoding : 65001 + + Date: 28/02/2022 00:57:25 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for ACT_EVT_LOG +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_EVT_LOG`; +CREATE TABLE `ACT_EVT_LOG` ( + `LOG_NR_` bigint NOT NULL AUTO_INCREMENT, + `TYPE_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TIME_STAMP_` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `DATA_` longblob, + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `LOCK_TIME_` timestamp(3) NULL DEFAULT NULL, + `IS_PROCESSED_` tinyint DEFAULT '0', + PRIMARY KEY (`LOG_NR_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_EVT_LOG +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_GE_BYTEARRAY +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_GE_BYTEARRAY`; +CREATE TABLE `ACT_GE_BYTEARRAY` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `DEPLOYMENT_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `BYTES_` longblob, + `GENERATED_` tinyint DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_FK_BYTEARR_DEPL` (`DEPLOYMENT_ID_`), + CONSTRAINT `ACT_FK_BYTEARR_DEPL` FOREIGN KEY (`DEPLOYMENT_ID_`) REFERENCES `ACT_RE_DEPLOYMENT` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_GE_BYTEARRAY +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_GE_BYTEARRAY` VALUES ('7bac85f2-97ed-11ec-a2b9-862bc1a4a054', 2, 'source', NULL, 0x3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C62706D6E323A646566696E6974696F6E7320786D6C6E733A7873693D22687474703A2F2F7777772E77332E6F72672F323030312F584D4C536368656D612D696E7374616E63652220786D6C6E733A62706D6E323D22687474703A2F2F7777772E6F6D672E6F72672F737065632F42504D4E2F32303130303532342F4D4F44454C2220786D6C6E733A62706D6E64693D22687474703A2F2F7777772E6F6D672E6F72672F737065632F42504D4E2F32303130303532342F44492220786D6C6E733A64633D22687474703A2F2F7777772E6F6D672E6F72672F737065632F44442F32303130303532342F44432220786D6C6E733A64693D22687474703A2F2F7777772E6F6D672E6F72672F737065632F44442F32303130303532342F4449222069643D226469616772616D5F50726F636573735F3136343539383036353033313122207461726765744E616D6573706163653D22687474703A2F2F61637469766974692E6F72672F62706D6E223E3C62706D6E323A70726F636573732069643D22666C6F7761626C655F303122206E616D653D22666C6F7761626C65E6B58BE8AF952220697345786563757461626C653D2274727565223E3C62706D6E323A73746172744576656E742069643D224576656E745F3169727578696D223E3C62706D6E323A6F7574676F696E673E466C6F775F30383034676D6F3C2F62706D6E323A6F7574676F696E673E3C2F62706D6E323A73746172744576656E743E3C62706D6E323A757365725461736B2069643D227461736B303122206E616D653D227461736B3031223E3C62706D6E323A696E636F6D696E673E466C6F775F30383034676D6F3C2F62706D6E323A696E636F6D696E673E3C62706D6E323A6F7574676F696E673E466C6F775F306378343739783C2F62706D6E323A6F7574676F696E673E3C2F62706D6E323A757365725461736B3E3C62706D6E323A73657175656E6365466C6F772069643D22466C6F775F30383034676D6F2220736F757263655265663D224576656E745F3169727578696D22207461726765745265663D227461736B303122202F3E3C62706D6E323A656E644576656E742069643D224576656E745F316D647363637A223E3C62706D6E323A696E636F6D696E673E466C6F775F306378343739783C2F62706D6E323A696E636F6D696E673E3C2F62706D6E323A656E644576656E743E3C62706D6E323A73657175656E6365466C6F772069643D22466C6F775F306378343739782220736F757263655265663D227461736B303122207461726765745265663D224576656E745F316D647363637A22202F3E3C2F62706D6E323A70726F636573733E3C62706D6E64693A42504D4E4469616772616D2069643D2242504D4E4469616772616D5F31223E3C62706D6E64693A42504D4E506C616E652069643D22666C6F7761626C655F30315F6469222062706D6E456C656D656E743D22666C6F7761626C655F3031223E3C62706D6E64693A42504D4E456467652069643D22466C6F775F306378343739785F6469222062706D6E456C656D656E743D22466C6F775F30637834373978223E3C64693A776179706F696E7420783D223434302220793D2233353022202F3E3C64693A776179706F696E7420783D223439322220793D2233353022202F3E3C2F62706D6E64693A42504D4E456467653E3C62706D6E64693A42504D4E456467652069643D22466C6F775F30383034676D6F5F6469222062706D6E456C656D656E743D22466C6F775F30383034676D6F223E3C64693A776179706F696E7420783D223238382220793D2233353022202F3E3C64693A776179706F696E7420783D223334302220793D2233353022202F3E3C2F62706D6E64693A42504D4E456467653E3C62706D6E64693A42504D4E53686170652069643D224576656E745F3169727578696D5F6469222062706D6E456C656D656E743D224576656E745F3169727578696D223E3C64633A426F756E647320783D223235322220793D22333332222077696474683D22333622206865696768743D22333622202F3E3C2F62706D6E64693A42504D4E53686170653E3C62706D6E64693A42504D4E53686170652069643D227461736B30315F6469222062706D6E456C656D656E743D227461736B3031223E3C64633A426F756E647320783D223334302220793D22333130222077696474683D2231303022206865696768743D22383022202F3E3C2F62706D6E64693A42504D4E53686170653E3C62706D6E64693A42504D4E53686170652069643D224576656E745F316D647363637A5F6469222062706D6E456C656D656E743D224576656E745F316D647363637A223E3C64633A426F756E647320783D223439322220793D22333332222077696474683D22333622206865696768743D22333622202F3E3C2F62706D6E64693A42504D4E53686170653E3C2F62706D6E64693A42504D4E506C616E653E3C2F62706D6E64693A42504D4E4469616772616D3E3C2F62706D6E323A646566696E6974696F6E733E, NULL); +INSERT INTO `ACT_GE_BYTEARRAY` VALUES ('bfb4c0a4-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01.bpmn', 'bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', 0x3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C62706D6E323A646566696E6974696F6E7320786D6C6E733A7873693D22687474703A2F2F7777772E77332E6F72672F323030312F584D4C536368656D612D696E7374616E63652220786D6C6E733A62706D6E323D22687474703A2F2F7777772E6F6D672E6F72672F737065632F42504D4E2F32303130303532342F4D4F44454C2220786D6C6E733A62706D6E64693D22687474703A2F2F7777772E6F6D672E6F72672F737065632F42504D4E2F32303130303532342F44492220786D6C6E733A64633D22687474703A2F2F7777772E6F6D672E6F72672F737065632F44442F32303130303532342F44432220786D6C6E733A64693D22687474703A2F2F7777772E6F6D672E6F72672F737065632F44442F32303130303532342F4449222069643D226469616772616D5F50726F636573735F3136343539383036353033313122207461726765744E616D6573706163653D22687474703A2F2F61637469766974692E6F72672F62706D6E223E3C62706D6E323A70726F636573732069643D22666C6F7761626C655F303122206E616D653D22666C6F7761626C65E6B58BE8AF952220697345786563757461626C653D2274727565223E3C62706D6E323A73746172744576656E742069643D224576656E745F3169727578696D223E3C62706D6E323A6F7574676F696E673E466C6F775F30383034676D6F3C2F62706D6E323A6F7574676F696E673E3C2F62706D6E323A73746172744576656E743E3C62706D6E323A757365725461736B2069643D227461736B303122206E616D653D227461736B3031223E3C62706D6E323A696E636F6D696E673E466C6F775F30383034676D6F3C2F62706D6E323A696E636F6D696E673E3C62706D6E323A6F7574676F696E673E466C6F775F306378343739783C2F62706D6E323A6F7574676F696E673E3C2F62706D6E323A757365725461736B3E3C62706D6E323A73657175656E6365466C6F772069643D22466C6F775F30383034676D6F2220736F757263655265663D224576656E745F3169727578696D22207461726765745265663D227461736B303122202F3E3C62706D6E323A656E644576656E742069643D224576656E745F316D647363637A223E3C62706D6E323A696E636F6D696E673E466C6F775F306378343739783C2F62706D6E323A696E636F6D696E673E3C2F62706D6E323A656E644576656E743E3C62706D6E323A73657175656E6365466C6F772069643D22466C6F775F306378343739782220736F757263655265663D227461736B303122207461726765745265663D224576656E745F316D647363637A22202F3E3C2F62706D6E323A70726F636573733E3C62706D6E64693A42504D4E4469616772616D2069643D2242504D4E4469616772616D5F31223E3C62706D6E64693A42504D4E506C616E652069643D22666C6F7761626C655F30315F6469222062706D6E456C656D656E743D22666C6F7761626C655F3031223E3C62706D6E64693A42504D4E456467652069643D22466C6F775F306378343739785F6469222062706D6E456C656D656E743D22466C6F775F30637834373978223E3C64693A776179706F696E7420783D223434302220793D2233353022202F3E3C64693A776179706F696E7420783D223439322220793D2233353022202F3E3C2F62706D6E64693A42504D4E456467653E3C62706D6E64693A42504D4E456467652069643D22466C6F775F30383034676D6F5F6469222062706D6E456C656D656E743D22466C6F775F30383034676D6F223E3C64693A776179706F696E7420783D223238382220793D2233353022202F3E3C64693A776179706F696E7420783D223334302220793D2233353022202F3E3C2F62706D6E64693A42504D4E456467653E3C62706D6E64693A42504D4E53686170652069643D224576656E745F3169727578696D5F6469222062706D6E456C656D656E743D224576656E745F3169727578696D223E3C64633A426F756E647320783D223235322220793D22333332222077696474683D22333622206865696768743D22333622202F3E3C2F62706D6E64693A42504D4E53686170653E3C62706D6E64693A42504D4E53686170652069643D227461736B30315F6469222062706D6E456C656D656E743D227461736B3031223E3C64633A426F756E647320783D223334302220793D22333130222077696474683D2231303022206865696768743D22383022202F3E3C2F62706D6E64693A42504D4E53686170653E3C62706D6E64693A42504D4E53686170652069643D224576656E745F316D647363637A5F6469222062706D6E456C656D656E743D224576656E745F316D647363637A223E3C64633A426F756E647320783D223439322220793D22333332222077696474683D22333622206865696768743D22333622202F3E3C2F62706D6E64693A42504D4E53686170653E3C2F62706D6E64693A42504D4E506C616E653E3C2F62706D6E64693A42504D4E4469616772616D3E3C2F62706D6E323A646566696E6974696F6E733E, 0); +INSERT INTO `ACT_GE_BYTEARRAY` VALUES ('c0bae605-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01.flowable_01.png', 'bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', 0x89504E470D0A1A0A0000000D494844520000021A000001900806000000E87AC905000010174944415478DAEDDD0B8896F59E07F0531854D8952516929038D021160A3AD0424B146C6450ED093273D4AC316D2D1BEDA25D305BCDAE6BB638854442EDD9A2C432375BCE76BCA4633A8A5D5C2F15999D2E8EB38EBA9AE6F136F5ECF37B9877781C9D1C67E6BDCCF8F9C01FDF79DF77DE9197E7F93FDFE77FFDCD6F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003A2549923EDF7CF3CD9C952B57FEBC68D1A264C182054A89CBC2850B93BABABAED6919EA8804A0578990B16CD9B2A4A9A9293970E08052A6B26DDBB664E9D2A53FA6A1E366472500BD46B46408191513360E2C58B0E00B472500BD467497B8C8574E4983C621472500BD468C117081AFA8A091382A0138E182C64FBB1A936F56BF9A6C5838252BF1389E130E040D00E852D0D8B3B32159FFC163C9FFFCD7F8C34A3C17AF0908820600743A68FCB0E1BD234246A16CDE305F40103400A0F341E38B0F9F6D3768C46B0282A001009D0E1AEB17FC4BBB41235E1310040D001034040D00A8BCA011B34CDA0B1AF19A8020680040A783C6C6E52FB61B34E2350141D000804E078D1D0D6B93F57F7EFCC86E93F4B9784D40103400A0D34123CA5F3EFEE31141239E130E040D00E85AD0D8BF3FD9B862E691DD26E973F19A8020680040A78246ACFCF9D5F2DA76C768C46B5607153400E0F882C6FEFD49E3C6C5C9BAFF7EB4DD905128F19E78AFD60D4103008E19348ED58AA17543D000804E078D8EB462FC5AEB86C020680040BB41A3B321A3500406410300DA0D1A8AA0512EB7DF7EFBD9B7DE7AEBCD69A94D4B7D5A1AD392E44AFC5C3F68D0A057060F1E3C342D7FE32C064A6AF3E6CD97BCFBEEBBFFF6D24B2FAD9F3871E29E3163C6FC3C64C890D68A6AE4C891071F78E0811D93274FAE9B366DDA3FA715DBA982860BBCA0515E6970B83E3D3FE7A7C1A1B94DB03866497F67415AFE70D55557F5510302459124499FFAFAFA093366CC684C8344F2F4D34F2773E7CE4DD6AC599334343424CDCDCD49C18E1D3B92B56BD726F3E6CD4B5E7CF1C5240D1ACDE3C78F5F515D5D7D89A0A1081AA5950685DFA72161E5F1868B76CAEAF4B306A811816EB574E9D2EA175E7861CFDD77DF9DCC993327696C6C4C8EC7CE9D3BB3CAFD9E7BEE39545353B33CADACFA0B1A8AA0515CD1FA908682A78FD682F1D0430F65E7F2F2E5CB93EFBFFF3ED9B76F5F76AE1E3C7830FB79E5CA95D98DC4638F3DD65EE0A83DD15B2A816E6AC5983D7BF6BAEAEAEAE4CD37DF6CAD8C3A2B5A3DA29563D8B06187468C18F190A0A1081AC53164C8907E6D5B31D2F32E79F5D5578FFB46E1DB6FBF4D66CD9A152D936DC3C6BAF83B6A4AA053D2CAA87F6D6D6DD3B871E3B28AA63BC5E7DD77DF7DFB468E1CF9FA8970572468081AA594068CDF5555556DC98782E8EA6C6A6AEAD2791B5DA253A64C691B367E38D15A28816E0A19D15512CDA6D1ED510CD13AF2E4934FEE1D3162C49F7AFB00334143D028654B463E64442BC692254B0E1B43D555CB962DCB3E57D8003A25BA4BA22523424657BB4A3AD2953275EAD4DD69A5354BD050048DAE691993D1DA5D1233C1BEFCF2CBA29CBB3186A34D57CABA810307F6558302C7146332A2BB64F7EEDD49294498A9A9A9D99D568A13040D45D0E8BC18F8996FC92856C8C8878DFCB4F61820AA06057E555D5DDDC818F8D9DD63323A326623ADB0F6A57744BF15341441E3F8B54C616D9D5D12DD25A510DD286DD6DB30F51538BAE83279FEF9E77F8AD925E53077EEDC5D69D8982B68288246A75A3356E6077E76E7988C6369334074B545BD80A38AC5B8629D8C628FCBF8B5F11AD5D5D55BABAAAA2E15341441A3E35A56FC6CED32E9EAEC92CECC46C98FD7881544D5A8C011A64F9FDE180BF894D3FCF9F363F4FA7F081A8AA0D171B1AC78E1221FEB6494C3EBAFBF7ED872E56A54E030B177492C2B7EBC0BF974B7984A5B5555F57FBD6D6D0D4143D02896D8202D3F36A35CE770B4A2E40786DA880D384C6C90F6DC73CF2595E091471E591D4DC13DE17B6BD968EA1F040D41A35CC757CB2EACADCB8A97537EB9F2D8F555CD0AB49A3163C686D8D7A012BCF6DA6BEB7ACA34B97C53711A8EFE5ED010344A7D7CB56CF59EBDAFDC5D9F518714FE2FB1C5BC9A1568155BBDC72EAC95E0D34F3FDD985654F53DE942902B7F3ADA1DA8A0216814EBF88A73A5F07A6C90564EB1AE46EEFF5AAF66055A8D1933E6E7728FCF28D8BE7DFB4F6925D5D8432F04AD77A0F90B82A0216814EBF88A73A5F07CECBA5A4E0D0D0DF9FF67A39A15681583B84A39EFFE58A2A2EAC91782FC1D6834790B1A8246B18EAFFCCFB1C57B39C5DFCFFF7FD4ACC061155A25E94005DBA38AA05159A5B71D5F855269E7AE9A15A8D4168D3DBDA045239B39535821F1440A1AFBF7EF3FEAF33FFEF863B6189C168DEE3DBEF2CF976BB13D2D1AC0318D1E3DFA40A58CD1D8BA75EBFA1E3C46E3B080515029412342C0AC59B39237DE78A353BFFFD65B6FC5C52379E79D778E786DEAD4A9C959679D959C79E699D934C7FC6BB18854FCDECC9933058D6E3EBEF263344ABD4791311A40874D9830E17F2B65D6497D7DFD921E38EBA43E965D6E6F8F874A091A2B56ACC82EF8D3A64DEB52D078FBEDB70F7B3E8E9D934E3A29B9EEBAEB921B6EB8217B4FCC40D8B3674FF2ECB3CF26A79F7EBAA051A4E3CBAC13A047983265CA9F2B651D8DE9D3A7CFEF41EB681CB505A35283C6A5975E9A5DF0CF3DF7DCA4B6B6366B6ABFF3CE3B93F3CF3F3F39F5D45393ABAFBE3ABB2B8DD6ADE84E3BEFBCF392BE7DFB66FB58446B483E68BCF2CA2B49FFFEFD93B163C726CF3CF34CF67C0499CF3EFB2C7BFCF8E38F27AB56ADCA3EF7C61B6F14348A747CE5D7D1983D7BB6753480CA94DE75DE91DEE5FE520941E3AEBBEE9ADF535606EDA84A091AE3C78FCF2EF8D1F250575797BCF7DE7B5957C7A44993927BEFBD377B2D02C4C48913B3C7D1CD128F2FBEF8E2ECFD85A0317AF4E8E494534E49AEBCF2CA6CEC454D4D4DF6FCC68D1B93CD9B37678F478D1A956CD9B225F9EAABAF92850B170A1AC50B235606052A5FEC2D525D5D7D3076612CF31A1A313E639BBD4E4AD775B278F1E264C28409C965975D96BD165B7EBFFFFEFBD9E3E8F2B8E69A6BB280B077EFDED6A051281F7DF451F61963C68CC97EFEFAEBAF5B8346B49414FE86A051D473F7ECF49C3954B8C06FDAB4A96C7B9D545555FD62AF13A05DE9DDD087F3E7CF2F6BD0A8ADADFD77BBB7962E6844EB45A185235A35E2F1134F3CD13A80F3A69B6ECA5A3CE2F9E86A29048D0B2FBC3039EDB4D3926BAFBD367B6FFC4E3C1F5D256BD7AECD1EE707840A1A456FD568DDBDF5E5975FB67B2B5099AAABAB2F19356A5473B9A6C8353737FF9056505FA77745970A1AC5291F7FFC7176C14FBFE3E4934F3EC9BA37E2E70F3EF82079F4D147B3C7D155124DF0E79C734E12C133C663C4F3E3C68D6B0D1A3116E0E1871FCE1E47F74B74ABC4E341830625B7DD765BF6385A4A048DD288AEC6C2457ED8B06159EB4229454BE8F0E1C3F3AD197F50A302473576ECD8A5E51A14FAD4534FBD965652737AE3F75A294163E7CE9D49BF7EFDB28BFE830F3E18337C920B2EB820FBF9F2CB2F4FCE38E38CAC15E3BBEFBE4BAEB8E28AA44F9F3E59CBC5800103B22E91FCF4D6EDDBB76783452FBAE8A26C5069749F9C7CF2C9D9EC937CB789A051B2568DD6D927D1FD55CA7571E2EFE5A7E01E6B703470021B3870E0DFDE71C71D074A3D1FFFF3CF3F5F9A56507BD2BFFF5B41A3B825C65A4468C8AFAD11334D8EF6DEB853DDB56B57873F3BDEBF6DDB364B9097C12DB7DCF28FF93537962C5952927377D9B2656DF76119A026057E55555555CDB871E3FE5AAA2E94F4C2B721FD9B1BD24AEAC1DEFA9D5A825CD02851ABC6BF162EF8313D394240B1D7CD183A74E82FB9A051AB06053A64C488117F9C3C7972D1C3467373F3B7D5D5D58BD30A6A666FFE3E050D41A3145A9624AFCF878D622DE2152163F8F0E13FE742C6BA810307F6557B021DAEB0D200F09F93264DDA5DACB0112D1969A0F930C665F4B6E9AC8286A0512E69B8E8979E531BF36123BA51BA73CC46B494B469C9F8212DFDD59CC071878DAAAAAA976B6A6A7677F7988D1893D1D25D32B3B7870C4143D028B5B8E8E7C3466180685767A3C4189C36033F850CA0EB060D1A3426BD2BFA69F6ECD93B6377C6AE4E616D995DB2A7378FC91034048D0A69D9A8CF878298FA1AEBA31CEF068A1150629D8CFC14D64277899001748B988D3278F0E0B7D38A66D79C397336A57736878E77C5CF588C2BFD8C2FA3AB24FDF77727D2F72768081AE56A954C6F145E38DA56F3B16E4AAC87126338A2C5B2701311FFC62CA41883316FDEBC6CE1B5FC8A9FF9819FC66400C568DDF8BBD82C29AD7876DF7FFFFD6B66CD9AB566D5AA559BB66CD9B237972BF644B0885D586383B4D8BB2496154FC3C59BBD71312E4143D0A8742D535FEB8F16383A51569BC20A145D8CAB68A9BC623A5D0CE8FC4B7EBF85B434B6546CB5B16AE189300E43D010347AC08DC2F52DCB951F3ADE8011CB8AB7B7553D0082862268E46F14CE4E43C7AD2D5BCCD7B7DC18246D6F14A2F53276618DAE53673180A0A1081A00081A8AA001008286A0010082862268002068B8C00B1A002068081A00206828820600081A820600081A820600081A8AA001008286A001008286A00100828622680080A021680080A021680080A0A1081A002068081A00502E8B162D7281AF9CB22F0D1A871C9500F41A7575758D4D4D4D2EF215501A1A1ADE4A83C6178E4A007A8DC58B17FFD392254B766DDDBAF5AF2EF6E56BC98890B170E1C2EFD272B3A312805E25BDB85D9FDE49AF8E66FB1823A094BCC4F7FE859001000000000000000000000000000000000000F408FF0FC85213564CA9202B0000000049454E44AE426082, 1); +INSERT INTO `ACT_GE_BYTEARRAY` VALUES ('c969093d-97ed-11ec-a2b9-862bc1a4a054', 1, 'hist.var-field122', NULL, 0xACED0005737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A65787000000001770400000001737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000178, NULL); +INSERT INTO `ACT_GE_BYTEARRAY` VALUES ('c969304e-97ed-11ec-a2b9-862bc1a4a054', 1, 'hist.detail.var-field122', NULL, 0xACED0005737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A65787000000001770400000001737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000178, NULL); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_GE_PROPERTY +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_GE_PROPERTY`; +CREATE TABLE `ACT_GE_PROPERTY` ( + `NAME_` varchar(64) COLLATE utf8_bin NOT NULL, + `VALUE_` varchar(300) COLLATE utf8_bin DEFAULT NULL, + `REV_` int DEFAULT NULL, + PRIMARY KEY (`NAME_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_GE_PROPERTY +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_GE_PROPERTY` VALUES ('batch.schema.version', '6.7.0.0', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('cfg.execution-related-entities-count', 'true', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('cfg.task-related-entities-count', 'true', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('common.schema.version', '6.7.0.0', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('entitylink.schema.version', '6.7.0.0', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('eventsubscription.schema.version', '6.7.0.0', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('identitylink.schema.version', '6.7.0.0', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('job.schema.version', '6.7.0.0', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('next.dbid', '1', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('schema.history', 'create(6.7.0.0)', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('schema.version', '6.7.0.0', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('task.schema.version', '6.7.0.0', 1); +INSERT INTO `ACT_GE_PROPERTY` VALUES ('variable.schema.version', '6.7.0.0', 1); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_HI_ACTINST +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_HI_ACTINST`; +CREATE TABLE `ACT_HI_ACTINST` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT '1', + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `ACT_ID_` varchar(255) COLLATE utf8_bin NOT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `CALL_PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ACT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ACT_TYPE_` varchar(255) COLLATE utf8_bin NOT NULL, + `ASSIGNEE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `START_TIME_` datetime(3) NOT NULL, + `END_TIME_` datetime(3) DEFAULT NULL, + `TRANSACTION_ORDER_` int DEFAULT NULL, + `DURATION_` bigint DEFAULT NULL, + `DELETE_REASON_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_HI_ACT_INST_START` (`START_TIME_`), + KEY `ACT_IDX_HI_ACT_INST_END` (`END_TIME_`), + KEY `ACT_IDX_HI_ACT_INST_PROCINST` (`PROC_INST_ID_`,`ACT_ID_`), + KEY `ACT_IDX_HI_ACT_INST_EXEC` (`EXECUTION_ID_`,`ACT_ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_HI_ACTINST +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_HI_ACTINST` VALUES ('c9695761-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', 'Event_1iruxim', NULL, NULL, NULL, 'startEvent', NULL, '2022-02-28 00:53:28.382', '2022-02-28 00:53:28.388', 1, 6, NULL, ''); +INSERT INTO `ACT_HI_ACTINST` VALUES ('c96b0512-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', 'Flow_0804gmo', NULL, NULL, NULL, 'sequenceFlow', NULL, '2022-02-28 00:53:28.392', '2022-02-28 00:53:28.392', 2, 0, NULL, ''); +INSERT INTO `ACT_HI_ACTINST` VALUES ('c96b0513-97ed-11ec-a2b9-862bc1a4a054', 2, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', 'task01', 'c97146a4-97ed-11ec-a2b9-862bc1a4a054', NULL, 'task01', 'userTask', '1', '2022-02-28 00:53:28.392', '2022-02-28 00:53:34.789', 3, 6397, NULL, ''); +INSERT INTO `ACT_HI_ACTINST` VALUES ('cd3b6e08-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', 'Flow_0cx479x', NULL, NULL, NULL, 'sequenceFlow', NULL, '2022-02-28 00:53:34.792', '2022-02-28 00:53:34.792', 1, 0, NULL, ''); +INSERT INTO `ACT_HI_ACTINST` VALUES ('cd3be339-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', 'Event_1mdsccz', NULL, NULL, NULL, 'endEvent', NULL, '2022-02-28 00:53:34.794', '2022-02-28 00:53:34.796', 2, 2, NULL, ''); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_HI_ATTACHMENT +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_HI_ATTACHMENT`; +CREATE TABLE `ACT_HI_ATTACHMENT` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `DESCRIPTION_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `URL_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `CONTENT_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TIME_` datetime(3) DEFAULT NULL, + PRIMARY KEY (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_HI_ATTACHMENT +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_HI_COMMENT +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_HI_COMMENT`; +CREATE TABLE `ACT_HI_COMMENT` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TIME_` datetime(3) NOT NULL, + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ACTION_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `MESSAGE_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `FULL_MSG_` longblob, + PRIMARY KEY (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_HI_COMMENT +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_HI_DETAIL +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_HI_DETAIL`; +CREATE TABLE `ACT_HI_DETAIL` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ACT_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `NAME_` varchar(255) COLLATE utf8_bin NOT NULL, + `VAR_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REV_` int DEFAULT NULL, + `TIME_` datetime(3) NOT NULL, + `BYTEARRAY_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `DOUBLE_` double DEFAULT NULL, + `LONG_` bigint DEFAULT NULL, + `TEXT_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `TEXT2_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_HI_DETAIL_PROC_INST` (`PROC_INST_ID_`), + KEY `ACT_IDX_HI_DETAIL_ACT_INST` (`ACT_INST_ID_`), + KEY `ACT_IDX_HI_DETAIL_TIME` (`TIME_`), + KEY `ACT_IDX_HI_DETAIL_NAME` (`NAME_`), + KEY `ACT_IDX_HI_DETAIL_TASK_ID` (`TASK_ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_HI_DETAIL +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_HI_DETAIL` VALUES ('c9681eda-97ed-11ec-a2b9-862bc1a4a054', 'VariableUpdate', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, 'field121', 'string', 0, '2022-02-28 00:53:28.373', NULL, NULL, NULL, 'AAA', NULL); +INSERT INTO `ACT_HI_DETAIL` VALUES ('c969304f-97ed-11ec-a2b9-862bc1a4a054', 'VariableUpdate', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, 'field122', 'serializable', 0, '2022-02-28 00:53:28.379', 'c969304e-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_HI_ENTITYLINK +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_HI_ENTITYLINK`; +CREATE TABLE `ACT_HI_ENTITYLINK` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `LINK_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CREATE_TIME_` datetime(3) DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PARENT_ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REF_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REF_SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REF_SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ROOT_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ROOT_SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HIERARCHY_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_HI_ENT_LNK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`,`LINK_TYPE_`), + KEY `ACT_IDX_HI_ENT_LNK_REF_SCOPE` (`REF_SCOPE_ID_`,`REF_SCOPE_TYPE_`,`LINK_TYPE_`), + KEY `ACT_IDX_HI_ENT_LNK_ROOT_SCOPE` (`ROOT_SCOPE_ID_`,`ROOT_SCOPE_TYPE_`,`LINK_TYPE_`), + KEY `ACT_IDX_HI_ENT_LNK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`,`LINK_TYPE_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_HI_ENTITYLINK +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_HI_IDENTITYLINK +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_HI_IDENTITYLINK`; +CREATE TABLE `ACT_HI_IDENTITYLINK` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `GROUP_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `CREATE_TIME_` datetime(3) DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_HI_IDENT_LNK_USER` (`USER_ID_`), + KEY `ACT_IDX_HI_IDENT_LNK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_HI_IDENT_LNK_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_HI_IDENT_LNK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_HI_IDENT_LNK_TASK` (`TASK_ID_`), + KEY `ACT_IDX_HI_IDENT_LNK_PROCINST` (`PROC_INST_ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_HI_IDENTITYLINK +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_HI_IDENTITYLINK` VALUES ('c9651198-97ed-11ec-a2b9-862bc1a4a054', NULL, 'starter', '1', NULL, '2022-02-28 00:53:28.353', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL); +INSERT INTO `ACT_HI_IDENTITYLINK` VALUES ('c9769dd5-97ed-11ec-a2b9-862bc1a4a054', NULL, 'assignee', '1', 'c97146a4-97ed-11ec-a2b9-862bc1a4a054', '2022-02-28 00:53:28.468', NULL, NULL, NULL, NULL, NULL); +INSERT INTO `ACT_HI_IDENTITYLINK` VALUES ('c978e7c6-97ed-11ec-a2b9-862bc1a4a054', NULL, 'participant', '1', NULL, '2022-02-28 00:53:28.483', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL); +INSERT INTO `ACT_HI_IDENTITYLINK` VALUES ('cd377667-97ed-11ec-a2b9-862bc1a4a054', NULL, 'participant', '1', NULL, '2022-02-28 00:53:34.765', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_HI_PROCINST +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_HI_PROCINST`; +CREATE TABLE `ACT_HI_PROCINST` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT '1', + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `BUSINESS_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `START_TIME_` datetime(3) NOT NULL, + `END_TIME_` datetime(3) DEFAULT NULL, + `DURATION_` bigint DEFAULT NULL, + `START_USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `START_ACT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `END_ACT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUPER_PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `DELETE_REASON_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CALLBACK_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CALLBACK_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REFERENCE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REFERENCE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PROPAGATED_STAGE_INST_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`), + UNIQUE KEY `PROC_INST_ID_` (`PROC_INST_ID_`), + KEY `ACT_IDX_HI_PRO_INST_END` (`END_TIME_`), + KEY `ACT_IDX_HI_PRO_I_BUSKEY` (`BUSINESS_KEY_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_HI_PROCINST +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_HI_PROCINST` VALUES ('c964c377-97ed-11ec-a2b9-862bc1a4a054', 3, 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', '2022-02-28 00:53:28.351', '2022-02-28 00:53:34.899', 6548, '1', 'Event_1iruxim', 'Event_1mdsccz', NULL, NULL, '', 'flowable测试', NULL, NULL, NULL, NULL, NULL); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_HI_TASKINST +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_HI_TASKINST`; +CREATE TABLE `ACT_HI_TASKINST` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT '1', + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TASK_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TASK_DEF_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PROPAGATED_STAGE_INST_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PARENT_TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `DESCRIPTION_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ASSIGNEE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `START_TIME_` datetime(3) NOT NULL, + `CLAIM_TIME_` datetime(3) DEFAULT NULL, + `END_TIME_` datetime(3) DEFAULT NULL, + `DURATION_` bigint DEFAULT NULL, + `DELETE_REASON_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `PRIORITY_` int DEFAULT NULL, + `DUE_DATE_` datetime(3) DEFAULT NULL, + `FORM_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + `LAST_UPDATED_TIME_` datetime(3) DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_HI_TASK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_HI_TASK_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_HI_TASK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_HI_TASK_INST_PROCINST` (`PROC_INST_ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_HI_TASKINST +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_HI_TASKINST` VALUES ('c97146a4-97ed-11ec-a2b9-862bc1a4a054', 2, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', NULL, 'task01', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL, NULL, 'task01', NULL, NULL, NULL, '1', '2022-02-28 00:53:28.392', NULL, '2022-02-28 00:53:34.779', 6387, NULL, 50, NULL, NULL, NULL, '', '2022-02-28 00:53:34.779'); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_HI_TSK_LOG +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_HI_TSK_LOG`; +CREATE TABLE `ACT_HI_TSK_LOG` ( + `ID_` bigint NOT NULL AUTO_INCREMENT, + `TYPE_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `TIME_STAMP_` timestamp(3) NOT NULL, + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `DATA_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_HI_TSK_LOG +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_HI_VARINST +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_HI_VARINST`; +CREATE TABLE `ACT_HI_VARINST` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT '1', + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `NAME_` varchar(255) COLLATE utf8_bin NOT NULL, + `VAR_TYPE_` varchar(100) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `BYTEARRAY_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `DOUBLE_` double DEFAULT NULL, + `LONG_` bigint DEFAULT NULL, + `TEXT_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `TEXT2_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `CREATE_TIME_` datetime(3) DEFAULT NULL, + `LAST_UPDATED_TIME_` datetime(3) DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_HI_PROCVAR_NAME_TYPE` (`NAME_`,`VAR_TYPE_`), + KEY `ACT_IDX_HI_VAR_SCOPE_ID_TYPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_HI_VAR_SUB_ID_TYPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_HI_PROCVAR_PROC_INST` (`PROC_INST_ID_`), + KEY `ACT_IDX_HI_PROCVAR_TASK_ID` (`TASK_ID_`), + KEY `ACT_IDX_HI_PROCVAR_EXE` (`EXECUTION_ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_HI_VARINST +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_HI_VARINST` VALUES ('c9678299-97ed-11ec-a2b9-862bc1a4a054', 0, 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, 'field121', 'string', NULL, NULL, NULL, NULL, NULL, NULL, 'AAA', NULL, '2022-02-28 00:53:28.373', '2022-02-28 00:53:28.373'); +INSERT INTO `ACT_HI_VARINST` VALUES ('c969093c-97ed-11ec-a2b9-862bc1a4a054', 0, 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, 'field122', 'serializable', NULL, NULL, NULL, 'c969093d-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL, '2022-02-28 00:53:28.379', '2022-02-28 00:53:28.379'); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_ID_BYTEARRAY +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_ID_BYTEARRAY`; +CREATE TABLE `ACT_ID_BYTEARRAY` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `BYTES_` longblob, + PRIMARY KEY (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_ID_BYTEARRAY +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_ID_GROUP +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_ID_GROUP`; +CREATE TABLE `ACT_ID_GROUP` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_ID_GROUP +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_ID_INFO +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_ID_INFO`; +CREATE TABLE `ACT_ID_INFO` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `USER_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TYPE_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `VALUE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PASSWORD_` longblob, + `PARENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_ID_INFO +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_ID_MEMBERSHIP +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_ID_MEMBERSHIP`; +CREATE TABLE `ACT_ID_MEMBERSHIP` ( + `USER_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `GROUP_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + PRIMARY KEY (`USER_ID_`,`GROUP_ID_`), + KEY `ACT_FK_MEMB_GROUP` (`GROUP_ID_`), + CONSTRAINT `ACT_FK_MEMB_GROUP` FOREIGN KEY (`GROUP_ID_`) REFERENCES `ACT_ID_GROUP` (`ID_`), + CONSTRAINT `ACT_FK_MEMB_USER` FOREIGN KEY (`USER_ID_`) REFERENCES `ACT_ID_USER` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_ID_MEMBERSHIP +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_ID_PRIV +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_ID_PRIV`; +CREATE TABLE `ACT_ID_PRIV` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `NAME_` varchar(255) COLLATE utf8_bin NOT NULL, + PRIMARY KEY (`ID_`), + UNIQUE KEY `ACT_UNIQ_PRIV_NAME` (`NAME_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_ID_PRIV +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_ID_PRIV_MAPPING +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_ID_PRIV_MAPPING`; +CREATE TABLE `ACT_ID_PRIV_MAPPING` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `PRIV_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `GROUP_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_FK_PRIV_MAPPING` (`PRIV_ID_`), + KEY `ACT_IDX_PRIV_USER` (`USER_ID_`), + KEY `ACT_IDX_PRIV_GROUP` (`GROUP_ID_`), + CONSTRAINT `ACT_FK_PRIV_MAPPING` FOREIGN KEY (`PRIV_ID_`) REFERENCES `ACT_ID_PRIV` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_ID_PRIV_MAPPING +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_ID_PROPERTY +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_ID_PROPERTY`; +CREATE TABLE `ACT_ID_PROPERTY` ( + `NAME_` varchar(64) COLLATE utf8_bin NOT NULL, + `VALUE_` varchar(300) COLLATE utf8_bin DEFAULT NULL, + `REV_` int DEFAULT NULL, + PRIMARY KEY (`NAME_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_ID_PROPERTY +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_ID_PROPERTY` VALUES ('schema.version', '6.7.0.0', 1); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_ID_TOKEN +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_ID_TOKEN`; +CREATE TABLE `ACT_ID_TOKEN` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `TOKEN_VALUE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TOKEN_DATE_` timestamp(3) NULL DEFAULT NULL, + `IP_ADDRESS_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `USER_AGENT_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TOKEN_DATA_` varchar(2000) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_ID_TOKEN +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_ID_USER +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_ID_USER`; +CREATE TABLE `ACT_ID_USER` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `FIRST_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `LAST_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `DISPLAY_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `EMAIL_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PWD_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PICTURE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_ID_USER +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_PROCDEF_INFO +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_PROCDEF_INFO`; +CREATE TABLE `ACT_PROCDEF_INFO` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `INFO_JSON_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`), + UNIQUE KEY `ACT_UNIQ_INFO_PROCDEF` (`PROC_DEF_ID_`), + KEY `ACT_IDX_INFO_PROCDEF` (`PROC_DEF_ID_`), + KEY `ACT_FK_INFO_JSON_BA` (`INFO_JSON_ID_`), + CONSTRAINT `ACT_FK_INFO_JSON_BA` FOREIGN KEY (`INFO_JSON_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_INFO_PROCDEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_PROCDEF_INFO +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RE_DEPLOYMENT +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RE_DEPLOYMENT`; +CREATE TABLE `ACT_RE_DEPLOYMENT` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + `DEPLOY_TIME_` timestamp(3) NULL DEFAULT NULL, + `DERIVED_FROM_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `DERIVED_FROM_ROOT_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PARENT_DEPLOYMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ENGINE_VERSION_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RE_DEPLOYMENT +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_RE_DEPLOYMENT` VALUES ('bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', 'flowable测试', '1', 'flowable_01', '', '2022-02-28 00:53:12.098', NULL, NULL, 'bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', NULL); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RE_MODEL +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RE_MODEL`; +CREATE TABLE `ACT_RE_MODEL` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL, + `LAST_UPDATE_TIME_` timestamp(3) NULL DEFAULT NULL, + `VERSION_` int DEFAULT NULL, + `META_INFO_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `DEPLOYMENT_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EDITOR_SOURCE_VALUE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EDITOR_SOURCE_EXTRA_VALUE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`), + KEY `ACT_FK_MODEL_SOURCE` (`EDITOR_SOURCE_VALUE_ID_`), + KEY `ACT_FK_MODEL_SOURCE_EXTRA` (`EDITOR_SOURCE_EXTRA_VALUE_ID_`), + KEY `ACT_FK_MODEL_DEPLOYMENT` (`DEPLOYMENT_ID_`), + CONSTRAINT `ACT_FK_MODEL_DEPLOYMENT` FOREIGN KEY (`DEPLOYMENT_ID_`) REFERENCES `ACT_RE_DEPLOYMENT` (`ID_`), + CONSTRAINT `ACT_FK_MODEL_SOURCE` FOREIGN KEY (`EDITOR_SOURCE_VALUE_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_MODEL_SOURCE_EXTRA` FOREIGN KEY (`EDITOR_SOURCE_EXTRA_VALUE_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RE_MODEL +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_RE_MODEL` VALUES ('4b4909d8-97e7-11ec-8e20-862bc1a4a054', 6, 'flowable测试', 'flowable_01', '1', '2022-02-28 00:06:59.795', '2022-02-28 00:53:13.893', 1, '{\"description\":\"ooxx\",\"formType\":10,\"formId\":11,\"formCustomCreatePath\":null,\"formCustomViewPath\":null}', 'bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', '7bac85f2-97ed-11ec-a2b9-862bc1a4a054', NULL, ''); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RE_PROCDEF +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RE_PROCDEF`; +CREATE TABLE `ACT_RE_PROCDEF` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `KEY_` varchar(255) COLLATE utf8_bin NOT NULL, + `VERSION_` int NOT NULL, + `DEPLOYMENT_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `RESOURCE_NAME_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `DGRM_RESOURCE_NAME_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `DESCRIPTION_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `HAS_START_FORM_KEY_` tinyint DEFAULT NULL, + `HAS_GRAPHICAL_NOTATION_` tinyint DEFAULT NULL, + `SUSPENSION_STATE_` int DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + `ENGINE_VERSION_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `DERIVED_FROM_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `DERIVED_FROM_ROOT_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `DERIVED_VERSION_` int NOT NULL DEFAULT '0', + PRIMARY KEY (`ID_`), + UNIQUE KEY `ACT_UNIQ_PROCDEF` (`KEY_`,`VERSION_`,`DERIVED_VERSION_`,`TENANT_ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RE_PROCDEF +-- ---------------------------- +BEGIN; +INSERT INTO `ACT_RE_PROCDEF` VALUES ('flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 2, '1', 'flowable测试', 'flowable_01', 1, 'bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', 'flowable_01.bpmn', 'flowable_01.flowable_01.png', NULL, 0, 1, 1, '', NULL, NULL, NULL, 0); +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_ACTINST +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_ACTINST`; +CREATE TABLE `ACT_RU_ACTINST` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT '1', + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `ACT_ID_` varchar(255) COLLATE utf8_bin NOT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `CALL_PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ACT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ACT_TYPE_` varchar(255) COLLATE utf8_bin NOT NULL, + `ASSIGNEE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `START_TIME_` datetime(3) NOT NULL, + `END_TIME_` datetime(3) DEFAULT NULL, + `DURATION_` bigint DEFAULT NULL, + `TRANSACTION_ORDER_` int DEFAULT NULL, + `DELETE_REASON_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_RU_ACTI_START` (`START_TIME_`), + KEY `ACT_IDX_RU_ACTI_END` (`END_TIME_`), + KEY `ACT_IDX_RU_ACTI_PROC` (`PROC_INST_ID_`), + KEY `ACT_IDX_RU_ACTI_PROC_ACT` (`PROC_INST_ID_`,`ACT_ID_`), + KEY `ACT_IDX_RU_ACTI_EXEC` (`EXECUTION_ID_`), + KEY `ACT_IDX_RU_ACTI_EXEC_ACT` (`EXECUTION_ID_`,`ACT_ID_`), + KEY `ACT_IDX_RU_ACTI_TASK` (`TASK_ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_ACTINST +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_DEADLETTER_JOB +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_DEADLETTER_JOB`; +CREATE TABLE `ACT_RU_DEADLETTER_JOB` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL, + `EXCLUSIVE_` tinyint(1) DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ELEMENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CORRELATION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `DUEDATE_` timestamp(3) NULL DEFAULT NULL, + `REPEAT_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_DEADLETTER_JOB_EXCEPTION_STACK_ID` (`EXCEPTION_STACK_ID_`), + KEY `ACT_IDX_DEADLETTER_JOB_CUSTOM_VALUES_ID` (`CUSTOM_VALUES_ID_`), + KEY `ACT_IDX_DEADLETTER_JOB_CORRELATION_ID` (`CORRELATION_ID_`), + KEY `ACT_IDX_DJOB_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_DJOB_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_DJOB_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`), + KEY `ACT_FK_DEADLETTER_JOB_EXECUTION` (`EXECUTION_ID_`), + KEY `ACT_FK_DEADLETTER_JOB_PROCESS_INSTANCE` (`PROCESS_INSTANCE_ID_`), + KEY `ACT_FK_DEADLETTER_JOB_PROC_DEF` (`PROC_DEF_ID_`), + CONSTRAINT `ACT_FK_DEADLETTER_JOB_CUSTOM_VALUES` FOREIGN KEY (`CUSTOM_VALUES_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_DEADLETTER_JOB_EXCEPTION` FOREIGN KEY (`EXCEPTION_STACK_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_DEADLETTER_JOB_EXECUTION` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`), + CONSTRAINT `ACT_FK_DEADLETTER_JOB_PROC_DEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`), + CONSTRAINT `ACT_FK_DEADLETTER_JOB_PROCESS_INSTANCE` FOREIGN KEY (`PROCESS_INSTANCE_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_DEADLETTER_JOB +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_ENTITYLINK +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_ENTITYLINK`; +CREATE TABLE `ACT_RU_ENTITYLINK` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `CREATE_TIME_` datetime(3) DEFAULT NULL, + `LINK_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PARENT_ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REF_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REF_SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REF_SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ROOT_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ROOT_SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HIERARCHY_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_ENT_LNK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`,`LINK_TYPE_`), + KEY `ACT_IDX_ENT_LNK_REF_SCOPE` (`REF_SCOPE_ID_`,`REF_SCOPE_TYPE_`,`LINK_TYPE_`), + KEY `ACT_IDX_ENT_LNK_ROOT_SCOPE` (`ROOT_SCOPE_ID_`,`ROOT_SCOPE_TYPE_`,`LINK_TYPE_`), + KEY `ACT_IDX_ENT_LNK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`,`LINK_TYPE_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_ENTITYLINK +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_EVENT_SUBSCR +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_EVENT_SUBSCR`; +CREATE TABLE `ACT_RU_EVENT_SUBSCR` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `EVENT_TYPE_` varchar(255) COLLATE utf8_bin NOT NULL, + `EVENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ACTIVITY_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `CONFIGURATION_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CREATED_` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_EVENT_SUBSCR_CONFIG_` (`CONFIGURATION_`), + KEY `ACT_FK_EVENT_EXEC` (`EXECUTION_ID_`), + CONSTRAINT `ACT_FK_EVENT_EXEC` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_EVENT_SUBSCR +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_EXECUTION +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_EXECUTION`; +CREATE TABLE `ACT_RU_EXECUTION` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `BUSINESS_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PARENT_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SUPER_EXEC_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ROOT_PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ACT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `IS_ACTIVE_` tinyint DEFAULT NULL, + `IS_CONCURRENT_` tinyint DEFAULT NULL, + `IS_SCOPE_` tinyint DEFAULT NULL, + `IS_EVENT_SCOPE_` tinyint DEFAULT NULL, + `IS_MI_ROOT_` tinyint DEFAULT NULL, + `SUSPENSION_STATE_` int DEFAULT NULL, + `CACHED_ENT_STATE_` int DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `START_ACT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `START_TIME_` datetime(3) DEFAULT NULL, + `START_USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `LOCK_TIME_` timestamp(3) NULL DEFAULT NULL, + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `IS_COUNT_ENABLED_` tinyint DEFAULT NULL, + `EVT_SUBSCR_COUNT_` int DEFAULT NULL, + `TASK_COUNT_` int DEFAULT NULL, + `JOB_COUNT_` int DEFAULT NULL, + `TIMER_JOB_COUNT_` int DEFAULT NULL, + `SUSP_JOB_COUNT_` int DEFAULT NULL, + `DEADLETTER_JOB_COUNT_` int DEFAULT NULL, + `EXTERNAL_WORKER_JOB_COUNT_` int DEFAULT NULL, + `VAR_COUNT_` int DEFAULT NULL, + `ID_LINK_COUNT_` int DEFAULT NULL, + `CALLBACK_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CALLBACK_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REFERENCE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `REFERENCE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PROPAGATED_STAGE_INST_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_EXEC_BUSKEY` (`BUSINESS_KEY_`), + KEY `ACT_IDC_EXEC_ROOT` (`ROOT_PROC_INST_ID_`), + KEY `ACT_IDX_EXEC_REF_ID_` (`REFERENCE_ID_`), + KEY `ACT_FK_EXE_PROCINST` (`PROC_INST_ID_`), + KEY `ACT_FK_EXE_PARENT` (`PARENT_ID_`), + KEY `ACT_FK_EXE_SUPER` (`SUPER_EXEC_`), + KEY `ACT_FK_EXE_PROCDEF` (`PROC_DEF_ID_`), + CONSTRAINT `ACT_FK_EXE_PARENT` FOREIGN KEY (`PARENT_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) ON DELETE CASCADE, + CONSTRAINT `ACT_FK_EXE_PROCDEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`), + CONSTRAINT `ACT_FK_EXE_PROCINST` FOREIGN KEY (`PROC_INST_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `ACT_FK_EXE_SUPER` FOREIGN KEY (`SUPER_EXEC_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_EXECUTION +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_EXTERNAL_JOB +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_EXTERNAL_JOB`; +CREATE TABLE `ACT_RU_EXTERNAL_JOB` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL, + `LOCK_EXP_TIME_` timestamp(3) NULL DEFAULT NULL, + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `EXCLUSIVE_` tinyint(1) DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ELEMENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CORRELATION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `RETRIES_` int DEFAULT NULL, + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `DUEDATE_` timestamp(3) NULL DEFAULT NULL, + `REPEAT_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_EXTERNAL_JOB_EXCEPTION_STACK_ID` (`EXCEPTION_STACK_ID_`), + KEY `ACT_IDX_EXTERNAL_JOB_CUSTOM_VALUES_ID` (`CUSTOM_VALUES_ID_`), + KEY `ACT_IDX_EXTERNAL_JOB_CORRELATION_ID` (`CORRELATION_ID_`), + KEY `ACT_IDX_EJOB_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_EJOB_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_EJOB_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`), + CONSTRAINT `ACT_FK_EXTERNAL_JOB_CUSTOM_VALUES` FOREIGN KEY (`CUSTOM_VALUES_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_EXTERNAL_JOB_EXCEPTION` FOREIGN KEY (`EXCEPTION_STACK_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_EXTERNAL_JOB +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_HISTORY_JOB +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_HISTORY_JOB`; +CREATE TABLE `ACT_RU_HISTORY_JOB` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `LOCK_EXP_TIME_` timestamp(3) NULL DEFAULT NULL, + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `RETRIES_` int DEFAULT NULL, + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ADV_HANDLER_CFG_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_HISTORY_JOB +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_IDENTITYLINK +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_IDENTITYLINK`; +CREATE TABLE `ACT_RU_IDENTITYLINK` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `GROUP_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_IDENT_LNK_USER` (`USER_ID_`), + KEY `ACT_IDX_IDENT_LNK_GROUP` (`GROUP_ID_`), + KEY `ACT_IDX_IDENT_LNK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_IDENT_LNK_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_IDENT_LNK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_ATHRZ_PROCEDEF` (`PROC_DEF_ID_`), + KEY `ACT_FK_TSKASS_TASK` (`TASK_ID_`), + KEY `ACT_FK_IDL_PROCINST` (`PROC_INST_ID_`), + CONSTRAINT `ACT_FK_ATHRZ_PROCEDEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`), + CONSTRAINT `ACT_FK_IDL_PROCINST` FOREIGN KEY (`PROC_INST_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`), + CONSTRAINT `ACT_FK_TSKASS_TASK` FOREIGN KEY (`TASK_ID_`) REFERENCES `ACT_RU_TASK` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_IDENTITYLINK +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_JOB +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_JOB`; +CREATE TABLE `ACT_RU_JOB` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL, + `LOCK_EXP_TIME_` timestamp(3) NULL DEFAULT NULL, + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `EXCLUSIVE_` tinyint(1) DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ELEMENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CORRELATION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `RETRIES_` int DEFAULT NULL, + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `DUEDATE_` timestamp(3) NULL DEFAULT NULL, + `REPEAT_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_JOB_EXCEPTION_STACK_ID` (`EXCEPTION_STACK_ID_`), + KEY `ACT_IDX_JOB_CUSTOM_VALUES_ID` (`CUSTOM_VALUES_ID_`), + KEY `ACT_IDX_JOB_CORRELATION_ID` (`CORRELATION_ID_`), + KEY `ACT_IDX_JOB_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_JOB_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_JOB_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`), + KEY `ACT_FK_JOB_EXECUTION` (`EXECUTION_ID_`), + KEY `ACT_FK_JOB_PROCESS_INSTANCE` (`PROCESS_INSTANCE_ID_`), + KEY `ACT_FK_JOB_PROC_DEF` (`PROC_DEF_ID_`), + CONSTRAINT `ACT_FK_JOB_CUSTOM_VALUES` FOREIGN KEY (`CUSTOM_VALUES_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_JOB_EXCEPTION` FOREIGN KEY (`EXCEPTION_STACK_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_JOB_EXECUTION` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`), + CONSTRAINT `ACT_FK_JOB_PROC_DEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`), + CONSTRAINT `ACT_FK_JOB_PROCESS_INSTANCE` FOREIGN KEY (`PROCESS_INSTANCE_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_JOB +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_SUSPENDED_JOB +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_SUSPENDED_JOB`; +CREATE TABLE `ACT_RU_SUSPENDED_JOB` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL, + `EXCLUSIVE_` tinyint(1) DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ELEMENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CORRELATION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `RETRIES_` int DEFAULT NULL, + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `DUEDATE_` timestamp(3) NULL DEFAULT NULL, + `REPEAT_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_SUSPENDED_JOB_EXCEPTION_STACK_ID` (`EXCEPTION_STACK_ID_`), + KEY `ACT_IDX_SUSPENDED_JOB_CUSTOM_VALUES_ID` (`CUSTOM_VALUES_ID_`), + KEY `ACT_IDX_SUSPENDED_JOB_CORRELATION_ID` (`CORRELATION_ID_`), + KEY `ACT_IDX_SJOB_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_SJOB_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_SJOB_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`), + KEY `ACT_FK_SUSPENDED_JOB_EXECUTION` (`EXECUTION_ID_`), + KEY `ACT_FK_SUSPENDED_JOB_PROCESS_INSTANCE` (`PROCESS_INSTANCE_ID_`), + KEY `ACT_FK_SUSPENDED_JOB_PROC_DEF` (`PROC_DEF_ID_`), + CONSTRAINT `ACT_FK_SUSPENDED_JOB_CUSTOM_VALUES` FOREIGN KEY (`CUSTOM_VALUES_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_SUSPENDED_JOB_EXCEPTION` FOREIGN KEY (`EXCEPTION_STACK_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_SUSPENDED_JOB_EXECUTION` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`), + CONSTRAINT `ACT_FK_SUSPENDED_JOB_PROC_DEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`), + CONSTRAINT `ACT_FK_SUSPENDED_JOB_PROCESS_INSTANCE` FOREIGN KEY (`PROCESS_INSTANCE_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_SUSPENDED_JOB +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_TASK +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_TASK`; +CREATE TABLE `ACT_RU_TASK` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TASK_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PROPAGATED_STAGE_INST_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `PARENT_TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `DESCRIPTION_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `TASK_DEF_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ASSIGNEE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `DELEGATION_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PRIORITY_` int DEFAULT NULL, + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL, + `DUE_DATE_` datetime(3) DEFAULT NULL, + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUSPENSION_STATE_` int DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + `FORM_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CLAIM_TIME_` datetime(3) DEFAULT NULL, + `IS_COUNT_ENABLED_` tinyint DEFAULT NULL, + `VAR_COUNT_` int DEFAULT NULL, + `ID_LINK_COUNT_` int DEFAULT NULL, + `SUB_TASK_COUNT_` int DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_TASK_CREATE` (`CREATE_TIME_`), + KEY `ACT_IDX_TASK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_TASK_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_TASK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`), + KEY `ACT_FK_TASK_EXE` (`EXECUTION_ID_`), + KEY `ACT_FK_TASK_PROCINST` (`PROC_INST_ID_`), + KEY `ACT_FK_TASK_PROCDEF` (`PROC_DEF_ID_`), + CONSTRAINT `ACT_FK_TASK_EXE` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`), + CONSTRAINT `ACT_FK_TASK_PROCDEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`), + CONSTRAINT `ACT_FK_TASK_PROCINST` FOREIGN KEY (`PROC_INST_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_TASK +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_TIMER_JOB +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_TIMER_JOB`; +CREATE TABLE `ACT_RU_TIMER_JOB` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL, + `LOCK_EXP_TIME_` timestamp(3) NULL DEFAULT NULL, + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `EXCLUSIVE_` tinyint(1) DEFAULT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `ELEMENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `CORRELATION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `RETRIES_` int DEFAULT NULL, + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `DUEDATE_` timestamp(3) NULL DEFAULT NULL, + `REPEAT_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL, + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_TIMER_JOB_EXCEPTION_STACK_ID` (`EXCEPTION_STACK_ID_`), + KEY `ACT_IDX_TIMER_JOB_CUSTOM_VALUES_ID` (`CUSTOM_VALUES_ID_`), + KEY `ACT_IDX_TIMER_JOB_CORRELATION_ID` (`CORRELATION_ID_`), + KEY `ACT_IDX_TIMER_JOB_DUEDATE` (`DUEDATE_`), + KEY `ACT_IDX_TJOB_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_TJOB_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_TJOB_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`), + KEY `ACT_FK_TIMER_JOB_EXECUTION` (`EXECUTION_ID_`), + KEY `ACT_FK_TIMER_JOB_PROCESS_INSTANCE` (`PROCESS_INSTANCE_ID_`), + KEY `ACT_FK_TIMER_JOB_PROC_DEF` (`PROC_DEF_ID_`), + CONSTRAINT `ACT_FK_TIMER_JOB_CUSTOM_VALUES` FOREIGN KEY (`CUSTOM_VALUES_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_TIMER_JOB_EXCEPTION` FOREIGN KEY (`EXCEPTION_STACK_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_TIMER_JOB_EXECUTION` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`), + CONSTRAINT `ACT_FK_TIMER_JOB_PROC_DEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`), + CONSTRAINT `ACT_FK_TIMER_JOB_PROCESS_INSTANCE` FOREIGN KEY (`PROCESS_INSTANCE_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_TIMER_JOB +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for ACT_RU_VARIABLE +-- ---------------------------- +DROP TABLE IF EXISTS `ACT_RU_VARIABLE`; +CREATE TABLE `ACT_RU_VARIABLE` ( + `ID_` varchar(64) COLLATE utf8_bin NOT NULL, + `REV_` int DEFAULT NULL, + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL, + `NAME_` varchar(255) COLLATE utf8_bin NOT NULL, + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `BYTEARRAY_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, + `DOUBLE_` double DEFAULT NULL, + `LONG_` bigint DEFAULT NULL, + `TEXT_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + `TEXT2_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`ID_`), + KEY `ACT_IDX_RU_VAR_SCOPE_ID_TYPE` (`SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_IDX_RU_VAR_SUB_ID_TYPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`), + KEY `ACT_FK_VAR_BYTEARRAY` (`BYTEARRAY_ID_`), + KEY `ACT_IDX_VARIABLE_TASK_ID` (`TASK_ID_`), + KEY `ACT_FK_VAR_EXE` (`EXECUTION_ID_`), + KEY `ACT_FK_VAR_PROCINST` (`PROC_INST_ID_`), + CONSTRAINT `ACT_FK_VAR_BYTEARRAY` FOREIGN KEY (`BYTEARRAY_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`), + CONSTRAINT `ACT_FK_VAR_EXE` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`), + CONSTRAINT `ACT_FK_VAR_PROCINST` FOREIGN KEY (`PROC_INST_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- ---------------------------- +-- Records of ACT_RU_VARIABLE +-- ---------------------------- +BEGIN; +COMMIT; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/pom.xml b/yudao-framework/yudao-spring-boot-starter-flowable/pom.xml index f778e2a54..0ad946284 100644 --- a/yudao-framework/yudao-spring-boot-starter-flowable/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-flowable/pom.xml @@ -16,16 +16,22 @@ cn.iocoder.boot yudao-common + cn.iocoder.boot yudao-spring-boot-starter-security + org.flowable flowable-spring-boot-starter-basic + + org.flowable + flowable-spring-boot-starter-actuator + - \ No newline at end of file + diff --git a/yudao-module-bpm/yudao-module-bpm-base/pom.xml b/yudao-module-bpm/yudao-module-bpm-base/pom.xml index 44a0dbd2a..1980a094d 100644 --- a/yudao-module-bpm/yudao-module-bpm-base/pom.xml +++ b/yudao-module-bpm/yudao-module-bpm-base/pom.xml @@ -32,6 +32,10 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-operatelog + + cn.iocoder.boot + yudao-spring-boot-starter-biz-data-permission + diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java index a1d05e4fc..ff3966025 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java @@ -8,7 +8,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; /** - * 流程实例 Api 实现类 + * Activiti 流程实例 Api 实现类 * * @author 芋道源码 */ diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java index 4a570d1fc..5d8b4bfcc 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java @@ -93,5 +93,4 @@ public class BpmModelController { bpmModelService.updateModelState(reqVO.getId(), reqVO.getState()); return success(true); } - } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java index e0714731a..4b0a7c1eb 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.impl; +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import org.activiti.engine.impl.persistence.entity.TaskEntity; import org.springframework.stereotype.Component; @@ -15,6 +16,7 @@ import java.util.Set; public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript { @Override + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据 public Set calculateTaskCandidateUsers(TaskEntity task) { return calculateTaskCandidateUsers(task, 1); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java index 7ad928c8d..41ee8254b 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.impl; +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import org.activiti.engine.impl.persistence.entity.TaskEntity; import org.springframework.stereotype.Component; @@ -15,6 +16,7 @@ import java.util.Set; public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript { @Override + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据 public Set calculateTaskCandidateUsers(TaskEntity task) { return calculateTaskCandidateUsers(task, 2); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml b/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml index ffd2412e5..bf4626d05 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml @@ -21,18 +21,18 @@ yudao-module-bpm-base ${revision} + cn.iocoder.boot yudao-spring-boot-starter-flowable + + cn.iocoder.boot - yudao-spring-boot-starter-biz-data-permission - - - org.flowable - flowable-spring-boot-starter-actuator + yudao-spring-boot-starter-test + test diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java index 745a61a51..596c9981a 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java @@ -7,6 +7,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; + /** * Flowable 流程实例 Api 实现类 * diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java index b51a4661b..3e946707a 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java @@ -55,5 +55,4 @@ public class BpmTaskAssignRuleController { taskAssignRuleService.updateTaskAssignRule(reqVO); return success(true); } - } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java index f22dcb04a..bf2feb840 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java @@ -1,24 +1,22 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.config; +import cn.hutool.core.collection.ListUtil; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; -import cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmProcessInstanceEventListener; import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import org.flowable.common.engine.api.delegate.event.FlowableEventListener; -import org.flowable.engine.runtime.ProcessInstance; import org.flowable.spring.SpringProcessEngineConfiguration; import org.flowable.spring.boot.EngineConfigurationConfigurer; import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.ArrayList; -import java.util.Iterator; import java.util.List; + /** * BPM 模块的 Flowable 配置类 * @@ -28,26 +26,23 @@ import java.util.List; public class BpmFlowableConfiguration { /** - * Flowable engines 自定义的配置 - * @param listeners 自定义 listener - * @param bpmActivityBehaviorFactory 自定义的 ActivityBehaviorFactory 实现 + * BPM 模块的 ProcessEngineConfigurationConfigurer 实现类: + * + * 1. 设置各种监听器 + * 2. 设置自定义的 ActivityBehaviorFactory 实现 */ @Bean - public EngineConfigurationConfigurer addCustomerListenerConfigurer (ObjectProvider listeners, - BpmActivityBehaviorFactory bpmActivityBehaviorFactory) { - return engineConfiguration -> { - List eventListeners = new ArrayList<>(); - Iterator iterator = listeners.iterator(); - while (iterator.hasNext()) { - eventListeners.add(iterator.next()); - } - engineConfiguration.setEventListeners(eventListeners); - engineConfiguration.setActivityBehaviorFactory(bpmActivityBehaviorFactory); + public EngineConfigurationConfigurer bpmProcessEngineConfigurationConfigurer( + ObjectProvider listeners, + BpmActivityBehaviorFactory bpmActivityBehaviorFactory) { + return configuration -> { + // 注册监听器,例如说 BpmActivitiEventListener + configuration.setEventListeners(ListUtil.toList(listeners.iterator())); + // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义 + configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory); }; } - - @Bean public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService, BpmUserGroupService userGroupService, diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java index fef8ecc4b..adcece67b 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; -import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.springframework.stereotype.Component; @@ -17,7 +16,7 @@ import java.util.Set; public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript { @Override - @DataPermission(excludeRules = DeptDataPermissionRule.class) + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据 public Set calculateTaskCandidateUsers(TaskEntity task) { return calculateTaskCandidateUsers(task, 1); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java index ccb4b944e..59c0732dc 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; -import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.springframework.stereotype.Component; @@ -18,8 +17,7 @@ public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScri @Override - //不需要处理数据权限, 不然会有问题,查询不到数据 - @DataPermission(excludeRules = DeptDataPermissionRule.class) + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据 public Set calculateTaskCandidateUsers(TaskEntity task) { return calculateTaskCandidateUsers(task, 2); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java new file mode 100644 index 000000000..52fdb7f93 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java @@ -0,0 +1,6 @@ +/** + * 属于 bpm 模块的 framework 封装 + * + * @author 芋道源码 + */ +package cn.iocoder.yudao.module.bpm.framework; diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java index 694da78d4..a6591bd93 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java @@ -281,5 +281,4 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ processDefinitionDOMap, formMap), definitionCount); } - } diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index c9163a0f4..1b7bdbe94 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -47,12 +47,17 @@ yudao-module-pay-impl ${revision} - + cn.iocoder.boot - yudao-module-bpm-impl-activiti + yudao-module-bpm-impl-flowable ${revision} + + + + + diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index ef43d2b4d..1f3261307 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -43,13 +43,15 @@ spring: primary: master datasource: master: - name: ruoyi-vue-pro +# name: ruoyi-vue-pro + name: ruoyi-vue-pro-flowable url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT driver-class-name: com.mysql.jdbc.Driver username: root password: 123456 slave: # 模拟从库,可根据自己需要修改 - name: ruoyi-vue-pro +# name: ruoyi-vue-pro + name: ruoyi-vue-pro-flowable url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT driver-class-name: com.mysql.jdbc.Driver username: root diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 67c06c7f4..cd42d7fac 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -27,10 +27,21 @@ spring: # 3. create_drop: 启动时自动创建表,关闭时自动删除表 # 4. drop_create: 启动时,删除旧表,再创建新表 database-schema-update: false # 设置为 false,可通过 sql/activiti.sql 初始化 - db-history-used: true # activiti7 默认不生成历史信息表,需手动设置开启 + db-history-used: true # activiti7 默认 false 不生成历史信息表,需手动设置开启 check-process-definitions: false # 设置为 false,禁用 /resources/processes 自动部署 BPMN XML 流程 history-level: full # full:保存历史数据的最高级别,可保存全部流程相关细节,包括流程流转各节点参数 +# 工作流 Flowable 配置 +flowable: + # 1. false: 默认值,activiti启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常 + # 2. true: 启动时会对数据库中所有表进行更新操作,如果表存在,不做处理,反之,自动创建表 + # 3. create_drop: 启动时自动创建表,关闭时自动删除表 + # 4. drop_create: 启动时,删除旧表,再创建新表 + database-schema-update: false # 设置为 false,可通过 https://github.com/flowable/flowable-sql 初始化 + db-history-used: true # flowable6 默认 true 生成信息表,无需手动设置 + check-process-definitions: false # 设置为 false,禁用 /resources/processes 自动部署 BPMN XML 流程 + history-level: full # full:保存历史数据的最高级别,可保存全部流程相关细节,包括流程流转各节点参数 + # MyBatis Plus 的配置项 mybatis-plus: configuration: From d2636a77873b4aa9144c71df1d5a8c271e32256e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 3 Mar 2022 13:12:52 +0800 Subject: [PATCH 18/19] =?UTF-8?q?=E8=B0=83=E6=95=B4=20DataScopeEnum=20?= =?UTF-8?q?=E5=88=B0=20yudao-module-system-api=20=E5=8C=85=E4=B8=8B?= =?UTF-8?q?=EF=BC=8C=E5=90=88=E7=90=86~?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- sql/{bpm_activiti.sql => bpm-activiti.sql} | 0 sql/{bpm_flowable.sql => bpm-flowable.sql} | 0 yudao-framework/yudao-spring-boot-starter-web/pom.xml | 2 +- .../module/system/enums/permission}/DataScopeEnum.java | 2 +- .../module/system/dal/dataobject/permission/RoleDO.java | 2 +- .../system/service/permission/PermissionServiceImpl.java | 2 +- .../module/system/service/permission/RoleServiceImpl.java | 2 +- .../system/service/permission/PermissionServiceTest.java | 2 +- .../module/system/service/permission/RoleServiceTest.java | 2 +- yudao-server/src/main/resources/application-local.yaml | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) rename sql/{bpm_activiti.sql => bpm-activiti.sql} (100%) rename sql/{bpm_flowable.sql => bpm-flowable.sql} (100%) rename {yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/enums => yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission}/DataScopeEnum.java (89%) diff --git a/README.md b/README.md index c4b05cf36..bb441757c 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,10 @@ * 集成微信小程序、微信公众号、企业微信、钉钉等三方登陆,集成支付宝、微信等支付与退款。 * 集成阿里云、腾讯云、云片等短信渠道,集成阿里云、腾讯云、七牛云等云存储服务。 -| 项目名 | 说明 | 传说门 | -| ---- | ---- | ---- | -| `ruoyi-vue-pro` | Spring Boot 版本 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro)**     [Github](https://github.com/YunaiV/ruoyi-vue-pro) | -| `ruoyi-vue-cloud` | Spring Cloud 版本 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-cloud)**     [Github](https://github.com/YunaiV/onemall) | +| 项目名 | 说明 | 传说门 | +| ---- |------------------------| ---- | +| `ruoyi-vue-pro` | Spring Boot 多模块 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro)**     [Github](https://github.com/YunaiV/ruoyi-vue-pro) | +| `ruoyi-vue-cloud` | Spring Cloud 微服务 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-cloud)**     [Github](https://github.com/YunaiV/onemall) | | `Spring-Boot-Labs` | Spring Boot & Cloud 入门 | **[Gitee](https://gitee.com/zhijiantianya/SpringBoot-Labs)**     [Github](https://github.com/YunaiV/SpringBoot-Labs) | ## 🐶 在线体验 diff --git a/sql/bpm_activiti.sql b/sql/bpm-activiti.sql similarity index 100% rename from sql/bpm_activiti.sql rename to sql/bpm-activiti.sql diff --git a/sql/bpm_flowable.sql b/sql/bpm-flowable.sql similarity index 100% rename from sql/bpm_flowable.sql rename to sql/bpm-flowable.sql diff --git a/yudao-framework/yudao-spring-boot-starter-web/pom.xml b/yudao-framework/yudao-spring-boot-starter-web/pom.xml index ff6cd817f..44081d86b 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-web/pom.xml @@ -12,7 +12,7 @@ jar ${project.artifactId} - 用户的认证、权限的校验 + Web 框架,全局异常、API 日志等 https://github.com/YunaiV/ruoyi-vue-pro diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/enums/DataScopeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/DataScopeEnum.java similarity index 89% rename from yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/enums/DataScopeEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/DataScopeEnum.java index c67a526d4..7146b98ef 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/enums/DataScopeEnum.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/DataScopeEnum.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.framework.security.core.enums; +package cn.iocoder.yudao.module.system.enums.permission; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleDO.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleDO.java index ce58219b5..4944be16b 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleDO.java +++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleDO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.system.dal.dataobject.permission; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; -import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum; +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum; import com.baomidou.mybatisplus.annotation.TableField; diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java index f47e83b02..15c4396bd 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java +++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java @@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO; import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum; +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java index 1c47dc35a..ebea1f88c 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java +++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java @@ -6,7 +6,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum; +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleExportReqVO; diff --git a/yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java b/yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java index f9b636340..9e2e95e1e 100644 --- a/yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java +++ b/yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java @@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer; import cn.iocoder.yudao.module.system.service.dept.DeptService; import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO; import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum; +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; import cn.iocoder.yudao.module.system.test.BaseDbUnitTest; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; diff --git a/yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java b/yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java index 6e8f291ab..21f46b8bb 100644 --- a/yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java +++ b/yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.service.permission; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum; +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleUpdateReqVO; diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 1f3261307..3e8b3b636 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -43,7 +43,7 @@ spring: primary: master datasource: master: -# name: ruoyi-vue-pro +# name: ruoyi-vue-pro俺吧 name: ruoyi-vue-pro-flowable url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT driver-class-name: com.mysql.jdbc.Driver From cd919daf64399ced603b63877924b678219bd452 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 4 Mar 2022 00:19:19 +0800 Subject: [PATCH 19/19] =?UTF-8?q?=E8=B0=83=E6=95=B4=20yudao-module-system?= =?UTF-8?q?=20=E7=9A=84=E6=9E=9A=E4=B8=BE=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-framework/pom.xml | 2 +- .../controller/admin/user/UserController.java | 4 +++ .../module/system/enums/common/SexEnum.java | 0 .../module/system/enums/dept/DeptIdEnum.java | 0 .../enums/errorcode/ErrorCodeTypeEnum.java | 0 .../system/enums/notice/NoticeTypeEnum.java | 0 .../system/enums/permission/MenuIdEnum.java | 0 .../system/enums/permission/MenuTypeEnum.java | 0 .../system/enums/permission/RoleCodeEnum.java | 0 .../system/enums/permission/RoleTypeEnum.java | 0 .../enums/sms/SmsReceiveStatusEnum.java | 0 .../system/enums/sms/SmsSendStatusEnum.java | 0 .../system/enums/sms/SmsTemplateTypeEnum.java | 0 .../app/dict/AppDictDataController.java | 4 +++ .../system/enums/logger/LoginLogTypeEnum.java | 29 ------------------- .../system/enums/logger/LoginResultEnum.java | 27 ----------------- 16 files changed, 9 insertions(+), 57 deletions(-) create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/UserController.java rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/common/SexEnum.java (100%) rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/dept/DeptIdEnum.java (100%) rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/errorcode/ErrorCodeTypeEnum.java (100%) rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/notice/NoticeTypeEnum.java (100%) rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java (100%) rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuTypeEnum.java (100%) rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleCodeEnum.java (100%) rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java (100%) rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsReceiveStatusEnum.java (100%) rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsSendStatusEnum.java (100%) rename yudao-module-system/{yudao-module-system-impl => yudao-module-system-api}/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsTemplateTypeEnum.java (100%) create mode 100644 yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/AppDictDataController.java delete mode 100644 yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/logger/LoginLogTypeEnum.java delete mode 100644 yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/logger/LoginResultEnum.java diff --git a/yudao-framework/pom.xml b/yudao-framework/pom.xml index 21452b4d1..8c4a9b586 100644 --- a/yudao-framework/pom.xml +++ b/yudao-framework/pom.xml @@ -41,7 +41,7 @@ yudao-framework 该包是技术组件,每个子包,代表一个组件。每个组件包括两部分: - 1. core 包:是该组件的核心分装 + 1. core 包:是该组件的核心封装 2. config 包:是该组件基于 Spring 的配置 技术组件,也分成两类: diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/UserController.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/UserController.java new file mode 100644 index 000000000..ce5667d32 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/UserController.java @@ -0,0 +1,4 @@ +package cn.iocoder.yudao.module.member.controller.admin.user; + +public class UserController { +} diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/common/SexEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/common/SexEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/common/SexEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/common/SexEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/dept/DeptIdEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/dept/DeptIdEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/dept/DeptIdEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/dept/DeptIdEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/errorcode/ErrorCodeTypeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/errorcode/ErrorCodeTypeEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/errorcode/ErrorCodeTypeEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/errorcode/ErrorCodeTypeEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/notice/NoticeTypeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/notice/NoticeTypeEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/notice/NoticeTypeEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/notice/NoticeTypeEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuTypeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuTypeEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuTypeEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuTypeEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleCodeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleCodeEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleCodeEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleCodeEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsReceiveStatusEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsReceiveStatusEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsReceiveStatusEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsReceiveStatusEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsSendStatusEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsSendStatusEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsSendStatusEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsSendStatusEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsTemplateTypeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsTemplateTypeEnum.java similarity index 100% rename from yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsTemplateTypeEnum.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsTemplateTypeEnum.java diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/AppDictDataController.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/AppDictDataController.java new file mode 100644 index 000000000..c4946c371 --- /dev/null +++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/AppDictDataController.java @@ -0,0 +1,4 @@ +package cn.iocoder.yudao.module.system.controller.app.dict; + +public class AppDictDataController { +} diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/logger/LoginLogTypeEnum.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/logger/LoginLogTypeEnum.java deleted file mode 100644 index 2f845fd10..000000000 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/logger/LoginLogTypeEnum.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.system.enums.logger; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 登录日志的类型枚举 - */ -@Getter -@AllArgsConstructor -public enum LoginLogTypeEnum { - - LOGIN_USERNAME(100), // 使用账号登录 - LOGIN_SOCIAL(101), // 使用社交登录 - LOGIN_MOCK(102), // 使用 Mock 登录 - LOGIN_MOBILE(103), // 使用手机登陆 - LOGIN_SMS(104), // 使用短信登陆 - - LOGOUT_SELF(200), // 自己主动登出 - LOGOUT_TIMEOUT(201), // 超时登出 - LOGOUT_DELETE(202), // 强制退出 - ; - - /** - * 日志类型 - */ - private final Integer type; - -} diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/logger/LoginResultEnum.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/logger/LoginResultEnum.java deleted file mode 100644 index 7084e13da..000000000 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/logger/LoginResultEnum.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.iocoder.yudao.module.system.enums.logger; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 登录结果的枚举类 - */ -@Getter -@AllArgsConstructor -public enum LoginResultEnum { - - SUCCESS(0), // 成功 - BAD_CREDENTIALS(10), // 账号或密码不正确 - USER_DISABLED(20), // 用户被禁用 - CAPTCHA_NOT_FOUND(30), // 图片验证码不存在 - CAPTCHA_CODE_ERROR(31), // 图片验证码不正确 - - UNKNOWN_ERROR(100), // 未知异常 - ; - - /** - * 结果 - */ - private final Integer result; - -}