|
@@ -1,26 +1,35 @@
|
|
|
-package cn.iocoder.yudao.adminserver.modules.bpm.service.model.impl;
|
|
|
+package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
|
|
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.util.ArrayUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
-import cn.iocoder.yudao.adminserver.modules.bpm.controller.model.vo.*;
|
|
|
-import cn.iocoder.yudao.adminserver.modules.bpm.convert.model.BpmModelConvert;
|
|
|
-import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
|
|
|
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.model.*;
|
|
|
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.rule.BpmTaskAssignRuleRespVO;
|
|
|
+import cn.iocoder.yudao.adminserver.modules.bpm.convert.definition.BpmModelConvert;
|
|
|
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
|
|
|
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.form.BpmFormService;
|
|
|
-import cn.iocoder.yudao.adminserver.modules.bpm.service.model.BpmModelService;
|
|
|
-import cn.iocoder.yudao.adminserver.modules.bpm.service.model.dto.BpmModelMetaInfoRespDTO;
|
|
|
+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;
|
|
|
+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 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;
|
|
|
import org.activiti.engine.repository.ProcessDefinition;
|
|
|
+import org.springframework.context.annotation.Lazy;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.util.ObjectUtils;
|
|
@@ -31,9 +40,11 @@ import java.util.HashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
+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;
|
|
|
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
|
|
|
|
|
/**
|
|
@@ -50,9 +61,12 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|
|
@Resource
|
|
|
private RepositoryService repositoryService;
|
|
|
@Resource
|
|
|
- private BpmFormService bpmFormService;
|
|
|
+ private BpmFormService formService;
|
|
|
@Resource
|
|
|
- private BpmProcessDefinitionService bpmProcessDefinitionService;
|
|
|
+ private BpmProcessDefinitionService processDefinitionService;
|
|
|
+ @Resource
|
|
|
+ @Lazy // 解决循环依赖
|
|
|
+ private BpmTaskAssignRuleService taskAssignRuleService;
|
|
|
|
|
|
@Override
|
|
|
public PageResult<BpmModelPageItemRespVO> getModelPage(ModelPageReqVO pageVO) {
|
|
@@ -75,14 +89,14 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|
|
BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
|
|
return metaInfo != null ? metaInfo.getFormId() : null;
|
|
|
});
|
|
|
- Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds);
|
|
|
+ Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
|
|
|
|
|
|
// 获得 Deployment Map
|
|
|
Set<String> deploymentIds = new HashSet<>();
|
|
|
models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
|
|
|
- Map<String, Deployment> deploymentMap = bpmProcessDefinitionService.getDeploymentMap(deploymentIds);
|
|
|
+ Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);
|
|
|
// 获得 ProcessDefinition Map
|
|
|
- List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
|
|
|
+ List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
|
|
|
Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
|
|
|
|
|
|
// 拼接结果
|
|
@@ -105,7 +119,7 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
|
|
|
- public String createModel(BpmModelCreateReqVO createReqVO) {
|
|
|
+ public String createModel(BpmModelCreateReqVO createReqVO, String bpmnXml) {
|
|
|
checkKeyNCName(createReqVO.getKey());
|
|
|
// 校验流程标识已经存在
|
|
|
Model keyModel = this.getModelByKey(createReqVO.getKey());
|
|
@@ -118,15 +132,14 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|
|
BpmModelConvert.INSTANCE.copy(model, createReqVO);
|
|
|
// 保存流程定义
|
|
|
repositoryService.saveModel(model);
|
|
|
- // 添加 BPMN XML
|
|
|
- repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(createReqVO.getBpmnXml()));
|
|
|
+ // 保存 BPMN XML
|
|
|
+ saveModelBpmnXml(model, bpmnXml);
|
|
|
return model.getId();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务
|
|
|
public void updateModel(BpmModelUpdateReqVO updateReqVO) {
|
|
|
- checkKeyNCName(updateReqVO.getKey());
|
|
|
// 校验流程模型存在
|
|
|
Model model = repositoryService.getModel(updateReqVO.getId());
|
|
|
if (model == null) {
|
|
@@ -138,7 +151,14 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|
|
// 更新模型
|
|
|
repositoryService.saveModel(model);
|
|
|
// 更新 BPMN XML
|
|
|
- repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(updateReqVO.getBpmnXml()));
|
|
|
+ saveModelBpmnXml(model, updateReqVO.getBpmnXml());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveModelBpmnXml(Model model, String bpmnXml) {
|
|
|
+ if (StrUtil.isEmpty(bpmnXml)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml));
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -149,28 +169,60 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|
|
if (ObjectUtils.isEmpty(model)) {
|
|
|
throw exception(MODEL_NOT_EXISTS);
|
|
|
}
|
|
|
+ // 校验流程图
|
|
|
byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId());
|
|
|
if (bpmnBytes == null) {
|
|
|
throw exception(MODEL_NOT_EXISTS);
|
|
|
}
|
|
|
+ // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素;
|
|
|
+ // 校验表单已配
|
|
|
+ BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
|
|
|
+ if (metaInfo == null || metaInfo.getFormType() == null) {
|
|
|
+ throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
|
|
|
+ }
|
|
|
+ // 校验任务分配规则已配置
|
|
|
+ checkTaskAssignRuleAllConfig(id);
|
|
|
|
|
|
// 创建流程定义
|
|
|
BpmDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model)
|
|
|
.setBpmnXml(StrUtil.utf8Str(bpmnBytes));
|
|
|
- String definitionId = bpmProcessDefinitionService.createProcessDefinition(definitionCreateReqDTO);
|
|
|
+ String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
|
|
|
|
|
|
// 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。
|
|
|
if (StrUtil.isNotEmpty(model.getDeploymentId())) {
|
|
|
- ProcessDefinition oldDefinition = bpmProcessDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
|
|
|
+ ProcessDefinition oldDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
|
|
|
if (oldDefinition != null) {
|
|
|
- bpmProcessDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
|
|
|
+ processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 更新 model 的 deploymentId,进行关联
|
|
|
- ProcessDefinition definition = bpmProcessDefinitionService.getProcessDefinition(definitionId);
|
|
|
+ ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId);
|
|
|
model.setDeploymentId(definition.getDeploymentId());
|
|
|
repositoryService.saveModel(model);
|
|
|
+
|
|
|
+ // 复制任务分配规则
|
|
|
+ taskAssignRuleService.copyTaskAssignRules(id, definition.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验流程模型的任务分配规则全部都配置了
|
|
|
+ * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
|
|
|
+ *
|
|
|
+ * @param id 流程模型编号
|
|
|
+ */
|
|
|
+ private void checkTaskAssignRuleAllConfig(String id) {
|
|
|
+ // 一个用户任务都没配置,所以无需配置规则
|
|
|
+ List<BpmTaskAssignRuleRespVO> 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
|
|
@@ -192,13 +244,22 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|
|
throw exception(MODEL_NOT_EXISTS);
|
|
|
}
|
|
|
// 校验流程定义存在
|
|
|
- ProcessDefinition definition = bpmProcessDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
|
|
|
+ ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
|
|
|
if (definition == null) {
|
|
|
throw exception(PROCESS_DEFINITION_NOT_EXISTS);
|
|
|
}
|
|
|
|
|
|
// 更新状态
|
|
|
- bpmProcessDefinitionService.updateProcessDefinitionState(definition.getId(), state);
|
|
|
+ processDefinitionService.updateProcessDefinitionState(definition.getId(), state);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public BpmnModel getBpmnModel(String id) {
|
|
|
+ byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
|
|
|
+ if (ArrayUtil.isEmpty(bpmnBytes)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return ActivitiUtils.buildBpmnModel(bpmnBytes);
|
|
|
}
|
|
|
|
|
|
private Model getModelByKey(String key) {
|
|
@@ -211,4 +272,10 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public static void main(String[] args) {
|
|
|
+ // 创建转换对象
|
|
|
+ BpmnXMLConverter converter = new BpmnXMLConverter();
|
|
|
+ BpmnModel bpmnModel = converter.convertToBpmnModel(new StringStreamSource(""), true, true);
|
|
|
+ }
|
|
|
+
|
|
|
}
|