From ed8fc5f674544d3af63c6f68093ffc038385c493 Mon Sep 17 00:00:00 2001
From: dongyukun <1208714201@qq.com>
Date: 星期一, 16 十二月 2024 09:30:04 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 iailab-module-bpm/iailab-module-bpm-biz/src/main/java/com/iailab/module/bpm/service/definition/BpmModelServiceImpl.java |  200 +++++++++++++++++++++++++++++++++-----------------
 1 files changed, 132 insertions(+), 68 deletions(-)

diff --git a/iailab-module-bpm/iailab-module-bpm-biz/src/main/java/com/iailab/module/bpm/service/definition/BpmModelServiceImpl.java b/iailab-module-bpm/iailab-module-bpm-biz/src/main/java/com/iailab/module/bpm/service/definition/BpmModelServiceImpl.java
index d611acd..49bd31f 100644
--- a/iailab-module-bpm/iailab-module-bpm-biz/src/main/java/com/iailab/module/bpm/service/definition/BpmModelServiceImpl.java
+++ b/iailab-module-bpm/iailab-module-bpm-biz/src/main/java/com/iailab/module/bpm/service/definition/BpmModelServiceImpl.java
@@ -1,19 +1,21 @@
 package com.iailab.module.bpm.service.definition;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.StrUtil;
-import com.iailab.framework.common.pojo.PageResult;
 import com.iailab.framework.common.util.json.JsonUtils;
-import com.iailab.framework.common.util.object.PageUtils;
 import com.iailab.framework.common.util.validation.ValidationUtils;
-import com.iailab.module.bpm.controller.admin.definition.vo.model.BpmModelCreateReqVO;
-import com.iailab.module.bpm.controller.admin.definition.vo.model.BpmModelPageReqVO;
-import com.iailab.module.bpm.controller.admin.definition.vo.model.BpmModelUpdateReqVO;
+import com.iailab.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
+import com.iailab.module.bpm.controller.admin.definition.vo.model.BpmModelSaveReqVO;
+import com.iailab.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
+import com.iailab.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelUpdateReqVO;
 import com.iailab.module.bpm.convert.definition.BpmModelConvert;
 import com.iailab.module.bpm.dal.dataobject.definition.BpmFormDO;
 import com.iailab.module.bpm.enums.definition.BpmModelFormTypeEnum;
 import com.iailab.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
 import com.iailab.module.bpm.framework.flowable.core.util.BpmnModelUtils;
 import com.iailab.module.bpm.framework.flowable.core.util.FlowableUtils;
+import com.iailab.module.bpm.framework.flowable.core.util.SimpleModelUtils;
 import com.iailab.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
 import lombok.extern.slf4j.Slf4j;
 import org.flowable.bpmn.model.BpmnModel;
@@ -32,18 +34,18 @@
 import javax.annotation.Resource;
 import javax.validation.Valid;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.iailab.framework.common.util.collection.CollectionUtils.convertMap;
 import static com.iailab.module.bpm.enums.ErrorCodeConstants.*;
 
 /**
  * Flowable流程模型实现
  * 主要进行 Flowable {@link Model} 的维护
  *
- * @author yunlongn
  * @author iailab
- * @author jason
  */
 @Service
 @Validated
@@ -61,91 +63,118 @@
     private BpmTaskCandidateInvoker taskCandidateInvoker;
 
     @Override
-    public PageResult<Model> getModelPage(BpmModelPageReqVO pageVO) {
+    public List<Model> getModelList(String name) {
         ModelQuery modelQuery = repositoryService.createModelQuery();
-        if (StrUtil.isNotBlank(pageVO.getKey())) {
-            modelQuery.modelKey(pageVO.getKey());
+        if (StrUtil.isNotEmpty(name)) {
+            modelQuery.modelNameLike(name);
         }
-        if (StrUtil.isNotBlank(pageVO.getName())) {
-            modelQuery.modelNameLike("%" + pageVO.getName() + "%"); // 模糊匹配
-        }
-        if (StrUtil.isNotBlank(pageVO.getCategory())) {
-            modelQuery.modelCategory(pageVO.getCategory());
-        }
-        // 执行查询
-        long count = modelQuery.count();
-        if (count == 0) {
-            return PageResult.empty(count);
-        }
-        // 关闭多租户查询,不添加tenantId条件
-        if (StrUtil.isNotBlank(FlowableUtils.getTenantId())) {
-            modelQuery.modelTenantId(FlowableUtils.getTenantId());
-        }
-        List<Model> models = modelQuery
-                .orderByCreateTime().desc()
-                .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
-        return new PageResult<>(models, count);
+        return modelQuery.list();
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public String createModel(@Valid BpmModelCreateReqVO createReqVO, String bpmnXml) {
+    public String createModel(@Valid BpmModelSaveReqVO createReqVO) {
         if (!ValidationUtils.isXmlNCName(createReqVO.getKey())) {
             throw exception(MODEL_KEY_VALID);
         }
-        // 校验流程标识已经存在
+        // 1. 校验流程标识已经存在
         Model keyModel = getModelByKey(createReqVO.getKey());
         if (keyModel != null) {
             throw exception(MODEL_KEY_EXISTS, createReqVO.getKey());
         }
 
-        // 创建流程定义
+        // 2.1 创建流程定义
+        createReqVO.setSort(System.currentTimeMillis()); // 使用当前时间,作为排序
         Model model = repositoryService.newModel();
-        BpmModelConvert.INSTANCE.copyToCreateModel(model, createReqVO);
+        BpmModelConvert.INSTANCE.copyToModel(model, createReqVO);
         model.setTenantId(FlowableUtils.getTenantId());
-        // 保存流程定义
+        // 2.2 保存流程定义
         repositoryService.saveModel(model);
-        // 保存 BPMN XML
-        saveModelBpmnXml(model, bpmnXml);
         return model.getId();
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务
-    public void updateModel(@Valid BpmModelUpdateReqVO updateReqVO) {
-        // 校验流程模型存在
-        Model model = getModel(updateReqVO.getId());
+    public void updateModel(Long userId, @Valid BpmModelSaveReqVO updateReqVO) {
+        // 1. 校验流程模型存在
+        Model model = validateModelManager(updateReqVO.getId(), userId);
+
+        // 修改流程定义
+        BpmModelConvert.INSTANCE.copyToModel(model, updateReqVO);
+        // 更新模型
+        repositoryService.saveModel(model);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateModelSortBatch(Long userId, List<String> ids) {
+        // 1.1 校验流程模型存在
+        List<Model> models = repositoryService.createModelQuery()
+                .modelTenantId(FlowableUtils.getTenantId()).list();
+        models.removeIf(model ->!ids.contains(model.getId()));
+        if (ids.size() != models.size()) {
+            throw exception(MODEL_NOT_EXISTS);
+        }
+        Map<String, Model> modelMap = convertMap(models, Model::getId);
+        // 1.2 校验是否为管理员
+        ids.forEach(id -> validateModelManager(id, userId));
+
+        // 保存排序
+        long sort = System.currentTimeMillis(); // 使用时间戳 - i 作为排序
+        for (int i = ids.size() - 1; i > 0; i--) {
+            Model model = modelMap.get(ids.get(i));
+            // 更新模型
+            BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model).setSort(sort);
+            model.setMetaInfo(JsonUtils.toJsonString(metaInfo));
+            repositoryService.saveModel(model);
+            // 更新排序
+            processDefinitionService.updateProcessDefinitionSortByModelId(model.getId(), sort);
+            sort--;
+        }
+    }
+
+    private Model validateModelExists(String id) {
+        Model model = repositoryService.getModel(id);
         if (model == null) {
             throw exception(MODEL_NOT_EXISTS);
         }
+        return model;
+    }
 
-        // 修改流程定义
-        BpmModelConvert.INSTANCE.copyToUpdateModel(model, updateReqVO);
-        // 更新模型
-        repositoryService.saveModel(model);
-        // 更新 BPMN XML
-        saveModelBpmnXml(model, updateReqVO.getBpmnXml());
+    /**
+     * 校验是否有流程模型的管理权限
+     *
+     * @param id     流程模型编号
+     * @param userId 用户编号
+     * @return 流程模型
+     */
+    private Model validateModelManager(String id, Long userId) {
+        Model model = validateModelExists(id);
+        BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model);
+        if (metaInfo == null || !CollUtil.contains(metaInfo.getManagerUserIds(), userId)) {
+            throw exception(MODEL_UPDATE_FAIL_NOT_MANAGER, model.getName());
+        }
+        return model;
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务
-    public void deployModel(String id) {
+    public void deployModel(Long userId, String id) {
         // 1.1 校验流程模型存在
-        Model model = getModel(id);
-        if (ObjectUtils.isEmpty(model)) {
-            throw exception(MODEL_NOT_EXISTS);
-        }
+        Model model = validateModelManager(id, userId);
         // 1.2 校验流程图
         byte[] bpmnBytes = getModelBpmnXML(model.getId());
         validateBpmnXml(bpmnBytes);
         // 1.3 校验表单已配
-        BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
+        BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model);
         BpmFormDO form = validateFormConfig(metaInfo);
         // 1.4 校验任务分配规则已配置
         taskCandidateInvoker.validateBpmnConfig(bpmnBytes);
+        // 1.5 获取仿钉钉流程设计器模型数据
+        String simpleJson = getModelSimpleJson(model.getId());
 
         // 2.1 创建流程定义
-        String definitionId = processDefinitionService.createProcessDefinition(model, metaInfo, bpmnBytes, form);
+        String definitionId = processDefinitionService.createProcessDefinition(model, metaInfo, bpmnBytes, simpleJson, form);
 
         // 2.2 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。
         updateProcessDefinitionSuspended(model.getDeploymentId());
@@ -177,12 +206,10 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void deleteModel(String id) {
+    public void deleteModel(Long userId, String id) {
         // 校验流程模型存在
-        Model model = getModel(id);
-        if (model == null) {
-            throw exception(MODEL_NOT_EXISTS);
-        }
+        Model model = validateModelManager(id, userId);
+
         // 执行删除
         repositoryService.deleteModel(id);
         // 禁用流程定义
@@ -190,12 +217,9 @@
     }
 
     @Override
-    public void updateModelState(String id, Integer state) {
+    public void updateModelState(Long userId, String id, Integer state) {
         // 1.1 校验流程模型存在
-        Model model = getModel(id);
-        if (model == null) {
-            throw exception(MODEL_NOT_EXISTS);
-        }
+        Model model = validateModelManager(id, userId);
         // 1.2 校验流程定义存在
         ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
         if (definition == null) {
@@ -211,13 +235,34 @@
         return repositoryService.getBpmnModel(processDefinitionId);
     }
 
+    @Override
+    public BpmSimpleModelNodeVO getSimpleModel(String modelId) {
+        Model model = validateModelExists(modelId);
+        // 通过 ACT_RE_MODEL 表 EDITOR_SOURCE_EXTRA_VALUE_ID_ ,获取仿钉钉快搭模型的 JSON 数据
+        String json = getModelSimpleJson(model.getId());
+        return JsonUtils.parseObject(json, BpmSimpleModelNodeVO.class);
+    }
+
+    @Override
+    public void updateSimpleModel(Long userId, BpmSimpleModelUpdateReqVO reqVO) {
+        // 1. 校验流程模型存在
+        Model model = validateModelManager(reqVO.getId(), userId);
+
+        // 2.1 JSON 转换成 bpmnModel
+        BpmnModel bpmnModel = SimpleModelUtils.buildBpmnModel(model.getKey(), model.getName(), reqVO.getSimpleModel());
+        // 2.2 保存 Bpmn XML
+        updateModelBpmnXml(model.getId(), BpmnModelUtils.getBpmnXml(bpmnModel));
+        // 2.3 保存 JSON 数据
+        updateModelSimpleJson(model.getId(), reqVO.getSimpleModel());
+    }
+
     /**
      * 校验流程表单已配置
      *
      * @param metaInfo 流程模型元数据
      * @return 表单配置
      */
-    private BpmFormDO validateFormConfig(BpmModelMetaInfoRespDTO  metaInfo) {
+    private BpmFormDO validateFormConfig(BpmModelMetaInfoVO metaInfo) {
         if (metaInfo == null || metaInfo.getFormType() == null) {
             throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
         }
@@ -239,16 +284,34 @@
         }
     }
 
-    private void saveModelBpmnXml(Model model, String bpmnXml) {
+    @Override
+    public void updateModelBpmnXml(String id, String bpmnXml) {
         if (StrUtil.isEmpty(bpmnXml)) {
             return;
         }
-        repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml));
+        repositoryService.addModelEditorSource(id, StrUtil.utf8Bytes(bpmnXml));
+    }
+
+    @SuppressWarnings("JavaExistingMethodCanBeUsed")
+    private String getModelSimpleJson(String id) {
+        byte[] bytes = repositoryService.getModelEditorSourceExtra(id);
+        if (ArrayUtil.isEmpty(bytes)) {
+            return null;
+        }
+        return StrUtil.utf8Str(bytes);
+    }
+
+    private void updateModelSimpleJson(String id, BpmSimpleModelNodeVO node) {
+        if (node == null) {
+            return;
+        }
+        byte[] bytes = JsonUtils.toJsonByte(node);
+        repositoryService.addModelEditorSourceExtra(id, bytes);
     }
 
     /**
      * 挂起 deploymentId 对应的流程定义
-     *
+     * <p>
      * 注意:这里一个 deploymentId 只关联一个流程定义
      *
      * @param deploymentId 流程发布Id
@@ -265,7 +328,9 @@
     }
 
     private Model getModelByKey(String key) {
-        return repositoryService.createModelQuery().modelKey(key).singleResult();
+        return repositoryService.createModelQuery()
+                .modelTenantId(FlowableUtils.getTenantId())
+                .modelKey(key).singleResult();
     }
 
     @Override
@@ -277,5 +342,4 @@
     public byte[] getModelBpmnXML(String id) {
         return repositoryService.getModelEditorSource(id);
     }
-
 }

--
Gitblit v1.9.3