From fe7a68c41e0e1502483be2769c133be635ef4dad Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 22 Jan 2022 02:15:04 +0800 Subject: [PATCH] =?UTF-8?q?bpm=20=E5=A2=9E=E5=8A=A0=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E7=9A=84=E4=BF=A1=E6=81=AF=E6=9C=AA=E5=8F=91?= =?UTF-8?q?=E7=94=9F=E5=8F=98=E5=8C=96=E6=97=B6=EF=BC=8C=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E4=B8=8D=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/vo/activity/BpmActivityRespVO.java | 16 ----- .../convert/definition/BpmModelConvert.java | 8 +-- .../BpmProcessDefinitionConvert.java | 4 +- .../bpm/convert/task/BpmActivityConvert.java | 11 +--- .../bpm/enums/BpmErrorCodeConstants.java | 1 + .../BpmProcessDefinitionService.java | 12 +++- .../definition/BpmTaskAssignRuleService.java | 9 +++ ... => BpmProcessDefinitionCreateReqDTO.java} | 4 +- .../definition/impl/BpmModelServiceImpl.java | 16 ++--- .../impl/BpmProcessDefinitionServiceImpl.java | 61 ++++++++++++++++--- .../impl/BpmTaskAssignRuleServiceImpl.java | 33 ++++++++-- .../task/impl/BpmActivityServiceImpl.java | 5 +- .../activiti/core/util/ActivitiUtils.java | 17 +++++- 13 files changed, 136 insertions(+), 61 deletions(-) rename yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/{BpmDefinitionCreateReqDTO.java => BpmProcessDefinitionCreateReqDTO.java} (97%) diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/activity/BpmActivityRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/activity/BpmActivityRespVO.java index 23e1b8168..447c59000 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/activity/BpmActivityRespVO.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/activity/BpmActivityRespVO.java @@ -23,20 +23,4 @@ public class BpmActivityRespVO { @ApiModelProperty(value = "关联的流程任务的编号", example = "2048", notes = "关联的流程任务,只有 UserTask 等类型才有") private String taskId; - /** - * 关联的流程任务,只有 UserTask 类型才有 - */ - private Task task; - - @ApiModel(value = "流程任务") - @Data - public static class Task { - - @ApiModelProperty(value = "关联的流程任务的编号", required = true, example = "2048") - private String id; - @ApiModelProperty(value = "关联的流程任务的结果", required = true, example = "2", notes = "参见 bpm_process_instance_result 枚举") - private Integer result; - - } - } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmModelConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmModelConvert.java index ceecfcfa4..eb3362ac6 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmModelConvert.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmModelConvert.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.convert.definition; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*; import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO; -import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO; +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; @@ -83,8 +83,8 @@ public interface BpmModelConvert { void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to); - default BpmDefinitionCreateReqDTO convert2(Model model, BpmFormDO form) { - BpmDefinitionCreateReqDTO createReqDTO = new BpmDefinitionCreateReqDTO(); + default BpmProcessDefinitionCreateReqDTO convert2(Model model, BpmFormDO form) { + BpmProcessDefinitionCreateReqDTO createReqDTO = new BpmProcessDefinitionCreateReqDTO(); createReqDTO.setModelId(model.getId()); createReqDTO.setName(model.getName()); createReqDTO.setKey(model.getKey()); @@ -100,7 +100,7 @@ public interface BpmModelConvert { return createReqDTO; } - void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmDefinitionCreateReqDTO to); + void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmProcessDefinitionCreateReqDTO to); default void copy(Model model, BpmModelCreateReqVO bean) { model.setName(bean.getName()); diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmProcessDefinitionConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmProcessDefinitionConvert.java index 8cb9fb356..fb11704e6 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmProcessDefinitionConvert.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/definition/BpmProcessDefinitionConvert.java @@ -4,7 +4,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO; import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO; -import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO; +import cn.iocoder.yudao.adminserver.modules.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; @@ -55,7 +55,7 @@ public interface BpmProcessDefinitionConvert { BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean); - BpmProcessDefinitionExtDO convert2(BpmDefinitionCreateReqDTO bean); + BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean); default List convertList3(List list, Map processDefinitionDOMap) { diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmActivityConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmActivityConvert.java index 8e9b1a9b3..b72e28ac6 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmActivityConvert.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmActivityConvert.java @@ -22,16 +22,7 @@ public interface BpmActivityConvert { BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class); - default List convertList(List list, Map taskExtMap) { - return CollectionUtils.convertList(list, bean -> { - BpmActivityRespVO respVO = convert(bean); - BpmTaskExtDO taskExt = taskExtMap.get(bean.getTaskId()); - if (taskExt != null) { - respVO.setTask(new BpmActivityRespVO.Task().setId(taskExt.getTaskId()).setResult(taskExt.getResult())); - } - return respVO; - }); - } + List convertList(List list); @Mappings({ @Mapping(source = "activityId", target = "key"), diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java index 6f762f04f..e2a0ff3d7 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java @@ -28,6 +28,7 @@ public interface BpmErrorCodeConstants { ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1009002003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置"); ErrorCode MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG = new ErrorCode(1009002004, "部署流程失败," + "原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置"); + ErrorCode MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS = new ErrorCode(1009003005, "流程定义部署失败,原因:信息未发生变化"); // ========== 流程定义 1-009-003-000 ========== ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图"); diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmProcessDefinitionService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmProcessDefinitionService.java index 8579a4239..b7ebe80d6 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmProcessDefinitionService.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmProcessDefinitionService.java @@ -5,7 +5,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO; import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; -import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO; +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import org.activiti.bpmn.model.BpmnModel; @@ -125,13 +125,21 @@ public interface BpmProcessDefinitionService { */ List getProcessDefinitionListByDeploymentIds(Set deploymentIds); + /** + * 获得需要创建的流程定义,是否和当前激活的流程定义相等 + * + * @param createReqDTO 创建信息 + * @return 是否相等 + */ + boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); + /** * 创建流程定义 * * @param createReqDTO 创建信息 * @return 流程编号 */ - String createProcessDefinition(@Valid BpmDefinitionCreateReqDTO createReqDTO); + String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO); /** * 更新流程定义的挂起状态 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmTaskAssignRuleService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmTaskAssignRuleService.java index 9dcfdb5a6..1105ddaa7 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmTaskAssignRuleService.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmTaskAssignRuleService.java @@ -59,6 +59,15 @@ public interface BpmTaskAssignRuleService { */ void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO); + /** + * 判断指定流程模型和流程定义的分配规则是否相等 + * + * @param modelId 流程模型编号 + * @param processDefinitionId 流程定义编号 + * @return 是否相等 + */ + boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId); + /** * 将流程流程模型的任务分配规则,复制一份给流程定义 * 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmDefinitionCreateReqDTO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java similarity index 97% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmDefinitionCreateReqDTO.java rename to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java index c36725061..559832c37 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmDefinitionCreateReqDTO.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java @@ -18,7 +18,7 @@ import java.util.Objects; * 流程定义创建 Request DTO */ @Data -public class BpmDefinitionCreateReqDTO { +public class BpmProcessDefinitionCreateReqDTO { // ========== 模型相关 ========== @@ -51,7 +51,7 @@ public class BpmDefinitionCreateReqDTO { * BPMN XML */ @NotEmpty(message = "BPMN XML 不能为空") - private String bpmnXml; + private byte[] bpmnBytes; // ========== 表单相关 ========== diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmModelServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmModelServiceImpl.java index ca32a0e0c..60a313863 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmModelServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmModelServiceImpl.java @@ -10,7 +10,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFor import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum; import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService; -import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO; +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService; import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmModelService; import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmModelMetaInfoRespDTO; @@ -21,11 +21,9 @@ 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 lombok.extern.slf4j.Slf4j; -import org.activiti.bpmn.converter.BpmnXMLConverter; import org.activiti.bpmn.model.BpmnModel; import org.activiti.engine.RepositoryService; import org.activiti.engine.impl.persistence.entity.SuspensionState; -import org.activiti.engine.impl.util.io.StringStreamSource; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.Model; import org.activiti.engine.repository.ModelQuery; @@ -38,7 +36,6 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.*; -import java.util.function.Consumer; import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -175,14 +172,19 @@ public class BpmModelServiceImpl implements BpmModelService { } // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素; // 校验表单已配 - // 校验表单存在 BpmFormDO form = checkFormConfig(model); // 校验任务分配规则已配置 checkTaskAssignRuleAllConfig(id); + // 校验模型是否发生修改。如果未修改,则不允许创建 + 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); + } + } // 创建流程定义 - BpmDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form) - .setBpmnXml(StrUtil.utf8Str(bpmnBytes)); String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO); // 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java index a43e4589b..045fe2a71 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmProcessDefinitionServiceImpl.java @@ -1,24 +1,23 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionListReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageItemRespVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionPageReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.process.BpmProcessDefinitionRespVO; import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmProcessDefinitionConvert; -import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO; +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper; -import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; -import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmDefinitionCreateReqDTO; import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmFormService; +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; +import cn.iocoder.yudao.adminserver.modules.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.object.PageUtils; import lombok.extern.slf4j.Slf4j; -import org.activiti.bpmn.converter.BpmnXMLConverter; import org.activiti.bpmn.model.BpmnModel; import org.activiti.engine.RepositoryService; import org.activiti.engine.impl.persistence.entity.SuspensionState; @@ -32,8 +31,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.*; -import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH; -import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH; +import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static java.util.Collections.emptyList; @@ -139,6 +137,16 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ return repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult(); } + /** + * 获得流程定义标识对应的激活的流程定义 + * + * @param processDefinitionKey 流程定义的标识 + * @return 流程定义 + */ + private ProcessDefinition getActiveProcessDefinition(String processDefinitionKey) { + return repositoryService.createProcessDefinitionQuery().processDefinitionKey(processDefinitionKey).active().singleResult(); + } + @Override public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) { return processDefinitionMapper.selectByProcessDefinitionId(id); @@ -166,6 +174,9 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ @Override public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) { + if (StrUtil.isEmpty(deploymentId)) { + return null; + } return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult(); } @@ -177,13 +188,45 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list(); } + @Override + public boolean isProcessDefinitionEquals(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 = ActivitiUtils.buildBpmnModel(createReqDTO.getBpmnBytes()); + BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId()); + if (!ActivitiUtils.equals(oldModel, newModel)) { + return false; + } + // 最终发现都一致,则返回 true + return true; + } + @Override @Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务 - public String createProcessDefinition(BpmDefinitionCreateReqDTO createReqDTO) { + public String createProcessDefinition(BpmProcessDefinitionCreateReqDTO createReqDTO) { // 创建 Deployment 部署 Deployment deploy = repositoryService.createDeployment() .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory()) - .addString(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnXml()) + .addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes()) .deploy(); // 设置 ProcessDefinition 的 category 分类 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmTaskAssignRuleServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmTaskAssignRuleServiceImpl.java index cf01c701e..16ae1859a 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/impl/BpmTaskAssignRuleServiceImpl.java @@ -1,6 +1,9 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO; @@ -30,10 +33,7 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Set; +import java.util.*; import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; import static cn.iocoder.yudao.adminserver.modules.system.enums.SysDictTypeConstants.BPM_TASK_ASSIGN_RULE_TYPE; @@ -142,6 +142,31 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(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) { List rules = getTaskAssignRuleList(fromModelId, null); diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmActivityServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmActivityServiceImpl.java index 8d4187b3a..7c4253ec6 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmActivityServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmActivityServiceImpl.java @@ -60,10 +60,7 @@ public class BpmActivityServiceImpl implements BpmActivityService { public List getActivityListByProcessInstanceId(String processInstanceId) { List activityList = historyService.createHistoricActivityInstanceQuery() .processInstanceId(processInstanceId).list(); - // 拼接数据 - List taskExts = taskService.getTaskExtListByProcessInstanceId(processInstanceId); - Map taskExtMap = convertMap(taskExts, BpmTaskExtDO::getTaskId); - return BpmActivityConvert.INSTANCE.convertList(activityList, taskExtMap); + return BpmActivityConvert.INSTANCE.convertList(activityList); } @Override diff --git a/yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/core/util/ActivitiUtils.java b/yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/core/util/ActivitiUtils.java index eb051c0a0..89034fe85 100644 --- a/yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/core/util/ActivitiUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/core/util/ActivitiUtils.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.framework.activiti.core.util; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; @@ -13,6 +15,7 @@ import org.activiti.engine.impl.util.io.BytesStreamSource; import javax.xml.bind.Element; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.function.Consumer; @@ -88,8 +91,20 @@ public class ActivitiUtils { if (model == null) { return null; } + return StrUtil.utf8Str(getBpmnBytes(model)); + } + + public static byte[] getBpmnBytes(BpmnModel model) { + if (model == null) { + return new byte[0]; + } BpmnXMLConverter converter = new BpmnXMLConverter(); - return StrUtil.utf8Str(converter.convertToXML(model)); + return converter.convertToXML(model); + } + + public static boolean equals(BpmnModel oldModel, BpmnModel newModel) { + // 由于 BpmnModel 未提供 equals 方法,所以只能转成字节数组,进行比较 + return Arrays.equals(getBpmnBytes(oldModel), getBpmnBytes(newModel)); } }