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; - -}