From 098d3347a0df808908aab8c554cd7c4febc5e6d9 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子Li <15040126243@163.com>
Date: 星期一, 26 八月 2024 11:43:59 +0800
Subject: [PATCH] !577 发布 5.2.2 正式版 安全性提升 Merge pull request !577 from 疯狂的狮子Li/dev

---
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java |  202 ++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 155 insertions(+), 47 deletions(-)

diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java
index cc82e00..77fb257 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java
@@ -3,13 +3,13 @@
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.codec.Base64;
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.SneakyThrows;
-import org.apache.commons.io.IOUtils;
+import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
@@ -18,16 +18,26 @@
 import org.dromara.common.tenant.helper.TenantHelper;
 import org.dromara.workflow.common.constant.FlowConstant;
 import org.dromara.workflow.domain.WfCategory;
+import org.dromara.workflow.domain.WfDefinitionConfig;
+import org.dromara.workflow.domain.WfNodeConfig;
 import org.dromara.workflow.domain.bo.ProcessDefinitionBo;
+import org.dromara.workflow.domain.bo.WfDefinitionConfigBo;
 import org.dromara.workflow.domain.vo.ProcessDefinitionVo;
+import org.dromara.workflow.domain.vo.WfDefinitionConfigVo;
+import org.dromara.workflow.mapper.WfDefinitionConfigMapper;
 import org.dromara.workflow.service.IActProcessDefinitionService;
 import org.dromara.workflow.service.IWfCategoryService;
+import org.dromara.workflow.service.IWfDefinitionConfigService;
+import org.dromara.workflow.service.IWfNodeConfigService;
+import org.dromara.workflow.utils.ModelUtils;
 import org.dromara.workflow.utils.QueryUtils;
+import org.flowable.bpmn.model.UserTask;
 import org.flowable.engine.ProcessMigrationService;
 import org.flowable.engine.RepositoryService;
+import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.impl.bpmn.deployer.ResourceNameUtil;
 import org.flowable.engine.repository.*;
-import org.flowable.task.api.history.HistoricTaskInstance;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
@@ -36,8 +46,9 @@
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
-import java.util.stream.Collectors;
+import java.util.Set;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
@@ -46,13 +57,19 @@
  *
  * @author may
  */
+@Slf4j
 @RequiredArgsConstructor
 @Service
 public class ActProcessDefinitionServiceImpl implements IActProcessDefinitionService {
 
-    private final RepositoryService repositoryService;
-    private final ProcessMigrationService processMigrationService;
+    @Autowired(required = false)
+    private RepositoryService repositoryService;
+    @Autowired(required = false)
+    private ProcessMigrationService processMigrationService;
     private final IWfCategoryService wfCategoryService;
+    private final IWfDefinitionConfigService wfDefinitionConfigService;
+    private final WfDefinitionConfigMapper wfDefinitionConfigMapper;
+    private final IWfNodeConfigService wfNodeConfigService;
 
     /**
      * 鍒嗛〉鏌ヨ
@@ -81,20 +98,29 @@
             List<String> deploymentIds = StreamUtils.toList(definitionList, ProcessDefinition::getDeploymentId);
             deploymentList = QueryUtils.deploymentQuery(deploymentIds).list();
         }
-        for (ProcessDefinition processDefinition : definitionList) {
-            ProcessDefinitionVo processDefinitionVo = BeanUtil.toBean(processDefinition, ProcessDefinitionVo.class);
-            if (CollUtil.isNotEmpty(deploymentList)) {
-                // 閮ㄧ讲鏃堕棿
-                deploymentList.stream().filter(e -> e.getId().equals(processDefinition.getDeploymentId())).findFirst().ifPresent(e -> {
-                    processDefinitionVo.setDeploymentTime(e.getDeploymentTime());
-                });
+        if (CollUtil.isNotEmpty(definitionList)) {
+            List<String> ids = StreamUtils.toList(definitionList, ProcessDefinition::getId);
+            List<WfDefinitionConfigVo> wfDefinitionConfigVos = wfDefinitionConfigService.queryList(ids);
+            for (ProcessDefinition processDefinition : definitionList) {
+                ProcessDefinitionVo processDefinitionVo = BeanUtil.toBean(processDefinition, ProcessDefinitionVo.class);
+                if (CollUtil.isNotEmpty(deploymentList)) {
+                    // 閮ㄧ讲鏃堕棿
+                    deploymentList.stream().filter(e -> e.getId().equals(processDefinition.getDeploymentId())).findFirst().ifPresent(e -> {
+                        processDefinitionVo.setDeploymentTime(e.getDeploymentTime());
+                    });
+                }
+                if (CollUtil.isNotEmpty(wfDefinitionConfigVos)) {
+                    wfDefinitionConfigVos.stream().filter(e -> e.getDefinitionId().equals(processDefinition.getId())).findFirst().ifPresent(processDefinitionVo::setWfDefinitionConfigVo);
+                }
+                processDefinitionVoList.add(processDefinitionVo);
             }
-            processDefinitionVoList.add(processDefinitionVo);
         }
         // 鎬昏褰曟暟
         long total = query.count();
-
-        return new TableDataInfo<>(processDefinitionVoList, total);
+        TableDataInfo<ProcessDefinitionVo> build = TableDataInfo.build();
+        build.setRows(processDefinitionVoList);
+        build.setTotal(total);
+        return build;
     }
 
     /**
@@ -109,20 +135,27 @@
         List<ProcessDefinition> definitionList = query.processDefinitionKey(key).list();
         List<Deployment> deploymentList = null;
         if (CollUtil.isNotEmpty(definitionList)) {
-            List<String> deploymentIds = definitionList.stream().map(ProcessDefinition::getDeploymentId).collect(Collectors.toList());
+            List<String> deploymentIds = StreamUtils.toList(definitionList, ProcessDefinition::getDeploymentId);
             deploymentList = QueryUtils.deploymentQuery(deploymentIds).list();
         }
-        for (ProcessDefinition processDefinition : definitionList) {
-            ProcessDefinitionVo processDefinitionVo = BeanUtil.toBean(processDefinition, ProcessDefinitionVo.class);
-            if (CollUtil.isNotEmpty(deploymentList)) {
-                // 閮ㄧ讲鏃堕棿
-                deploymentList.stream().filter(e -> e.getId().equals(processDefinition.getDeploymentId())).findFirst().ifPresent(e -> {
-                    processDefinitionVo.setDeploymentTime(e.getDeploymentTime());
-                });
+        if (CollUtil.isNotEmpty(definitionList)) {
+            List<String> ids = StreamUtils.toList(definitionList, ProcessDefinition::getId);
+            List<WfDefinitionConfigVo> wfDefinitionConfigVos = wfDefinitionConfigService.queryList(ids);
+            for (ProcessDefinition processDefinition : definitionList) {
+                ProcessDefinitionVo processDefinitionVo = BeanUtil.toBean(processDefinition, ProcessDefinitionVo.class);
+                if (CollUtil.isNotEmpty(deploymentList)) {
+                    // 閮ㄧ讲鏃堕棿
+                    deploymentList.stream().filter(e -> e.getId().equals(processDefinition.getDeploymentId())).findFirst().ifPresent(e -> {
+                        processDefinitionVo.setDeploymentTime(e.getDeploymentTime());
+                    });
+                    if (CollUtil.isNotEmpty(wfDefinitionConfigVos)) {
+                        wfDefinitionConfigVos.stream().filter(e -> e.getDefinitionId().equals(processDefinition.getId())).findFirst().ifPresent(processDefinitionVo::setWfDefinitionConfigVo);
+                    }
+                }
+                processDefinitionVoList.add(processDefinitionVo);
             }
-            processDefinitionVoList.add(processDefinitionVo);
         }
-        return CollectionUtil.reverse(processDefinitionVoList);
+        return CollUtil.reverse(processDefinitionVoList);
     }
 
     /**
@@ -134,7 +167,7 @@
     @Override
     public String definitionImage(String processDefinitionId) {
         InputStream inputStream = repositoryService.getProcessDiagram(processDefinitionId);
-        return Base64.encode(IOUtils.toByteArray(inputStream));
+        return Base64.encode(IoUtil.readBytes(inputStream));
     }
 
     /**
@@ -146,35 +179,41 @@
     public String definitionXml(String processDefinitionId) {
         StringBuilder xml = new StringBuilder();
         ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId);
-        InputStream inputStream;
-        try {
-            inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
-            xml.append(IOUtils.toString(inputStream, StandardCharsets.UTF_8));
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
+        InputStream inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
+        xml.append(IoUtil.read(inputStream, StandardCharsets.UTF_8));
         return xml.toString();
     }
 
     /**
      * 鍒犻櫎娴佺▼瀹氫箟
      *
-     * @param deploymentId        閮ㄧ讲id
-     * @param processDefinitionId 娴佺▼瀹氫箟id
+     * @param deploymentIds        閮ㄧ讲id
+     * @param processDefinitionIds 娴佺▼瀹氫箟id
      */
     @Override
-    public boolean deleteDeployment(String deploymentId, String processDefinitionId) {
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteDeployment(List<String> deploymentIds, List<String> processDefinitionIds) {
         try {
-            List<HistoricTaskInstance> taskInstanceList = QueryUtils.hisTaskInstanceQuery()
-                .processDefinitionId(processDefinitionId).list();
-            if (CollectionUtil.isNotEmpty(taskInstanceList)) {
-                throw new ServiceException("褰撳墠娴佺▼瀹氫箟宸茶浣跨敤涓嶅彲鍒犻櫎锛�");
+            List<HistoricProcessInstance> historicProcessInstances = QueryUtils.hisInstanceQuery().deploymentIdIn(deploymentIds).list();
+            if (CollUtil.isNotEmpty(historicProcessInstances)) {
+                Set<String> defIds = StreamUtils.toSet(historicProcessInstances, HistoricProcessInstance::getProcessDefinitionId);
+                List<ProcessDefinition> processDefinitions = QueryUtils.definitionQuery().processDefinitionIds(defIds).list();
+                if (CollUtil.isNotEmpty(processDefinitions)) {
+                    Set<String> keys = StreamUtils.toSet(processDefinitions, ProcessDefinition::getKey);
+                    throw new ServiceException("褰撳墠銆�" + String.join(",", keys) + "銆戞祦绋嬪畾涔夊凡琚娇鐢ㄤ笉鍙垹闄わ紒");
+                }
             }
             //鍒犻櫎娴佺▼瀹氫箟
-            repositoryService.deleteDeployment(deploymentId);
+            for (String deploymentId : deploymentIds) {
+                repositoryService.deleteDeployment(deploymentId);
+            }
+            //鍒犻櫎娴佺▼瀹氫箟閰嶇疆
+            wfDefinitionConfigService.deleteByDefIds(processDefinitionIds);
+            //鍒犻櫎鑺傜偣閰嶇疆
+            wfNodeConfigService.deleteByDefIds(processDefinitionIds);
             return true;
         } catch (Exception e) {
-            e.printStackTrace();
+            log.error(e.getMessage(), e);
             throw new ServiceException(e.getMessage());
         }
     }
@@ -199,7 +238,7 @@
             }
             return true;
         } catch (Exception e) {
-            e.printStackTrace();
+            log.error(e.getMessage(), e);
             throw new ServiceException("鎿嶄綔澶辫触:" + e.getMessage());
         }
     }
@@ -228,6 +267,7 @@
                 .migrateProcessInstances(fromProcessDefinitionId);
             return true;
         } catch (Exception e) {
+            log.error(e.getMessage(), e);
             throw new ServiceException(e.getMessage());
         }
     }
@@ -251,13 +291,14 @@
                 Model modelData = repositoryService.newModel();
                 modelData.setKey(pd.getKey());
                 modelData.setName(pd.getName());
+                modelData.setCategory(pd.getCategory());
                 modelData.setTenantId(pd.getTenantId());
                 repositoryService.saveModel(modelData);
                 repositoryService.addModelEditorSource(modelData.getId(), IoUtil.readBytes(inputStream));
             }
             return true;
         } catch (Exception e) {
-            e.printStackTrace();
+            log.error(e.getMessage(), e);
             throw new ServiceException(e.getMessage());
         }
     }
@@ -292,12 +333,14 @@
                     String processName = splitFilename[0];
                     //娴佺▼key
                     String processKey = splitFilename[1];
+                    ProcessDefinition oldProcessDefinition = QueryUtils.definitionQuery().processDefinitionKey(processKey).latestVersion().singleResult();
                     DeploymentBuilder builder = repositoryService.createDeployment();
                     Deployment deployment = builder.addInputStream(filename, zipInputStream)
                         .tenantId(TenantHelper.getTenantId())
                         .name(processName).key(processKey).category(categoryCode).deploy();
                     ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult();
                     repositoryService.setProcessDefinitionCategory(definition.getId(), categoryCode);
+                    setWfConfig(oldProcessDefinition, definition);
                     zipInputStream.closeEntry();
                 }
             } catch (IOException e) {
@@ -307,10 +350,11 @@
                     zipInputStream.close();
                 }
             }
+            //鍒濆鍖栭厤缃暟鎹紙demo浣跨敤锛屼笉鐢ㄥ彲鍒犻櫎锛�
+            initWfDefConfig();
         } else {
             String originalFilename = file.getOriginalFilename();
-            String bpmnResourceSuffix = ResourceNameUtil.BPMN_RESOURCE_SUFFIXES[0];
-            if (originalFilename.contains(bpmnResourceSuffix)) {
+            if (StringUtils.containsAny(originalFilename, ResourceNameUtil.BPMN_RESOURCE_SUFFIXES)) {
                 // 鏂囦欢鍚� = 娴佺▼鍚嶇О-娴佺▼key
                 String[] splitFilename = originalFilename.substring(0, originalFilename.lastIndexOf(".")).split("-");
                 if (splitFilename.length < 2) {
@@ -320,6 +364,7 @@
                 String processName = splitFilename[0];
                 //娴佺▼key
                 String processKey = splitFilename[1];
+                ProcessDefinition oldProcessDefinition = QueryUtils.definitionQuery().processDefinitionKey(processKey).latestVersion().singleResult();
                 DeploymentBuilder builder = repositoryService.createDeployment();
                 Deployment deployment = builder.addInputStream(originalFilename, inputStream)
                     .tenantId(TenantHelper.getTenantId())
@@ -327,10 +372,73 @@
                 // 鏇存柊鍒嗙被
                 ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult();
                 repositoryService.setProcessDefinitionCategory(definition.getId(), categoryCode);
+                setWfConfig(oldProcessDefinition, definition);
             } else {
                 throw new ServiceException("鏂囦欢绫诲瀷涓婁紶閿欒锛�");
             }
         }
 
     }
+
+    /**
+     * 鍒濆鍖栭厤缃暟鎹紙demo浣跨敤锛屼笉鐢ㄥ彲鍒犻櫎锛�
+     */
+    private void initWfDefConfig() {
+        List<WfDefinitionConfig> wfDefinitionConfigs = wfDefinitionConfigMapper.selectList();
+        if (CollUtil.isEmpty(wfDefinitionConfigs)) {
+            ProcessDefinition processDefinition = QueryUtils.definitionQuery().processDefinitionKey("leave1").latestVersion().singleResult();
+            if (processDefinition != null) {
+                WfDefinitionConfigBo wfDefinitionConfigBo = new WfDefinitionConfigBo();
+                wfDefinitionConfigBo.setDefinitionId(processDefinition.getId());
+                wfDefinitionConfigBo.setProcessKey(processDefinition.getKey());
+                wfDefinitionConfigBo.setTableName("test_leave");
+                wfDefinitionConfigBo.setVersion(processDefinition.getVersion());
+                wfDefinitionConfigService.saveOrUpdate(wfDefinitionConfigBo);
+            }
+        }
+
+    }
+
+    /**
+     * 璁剧疆琛ㄥ崟鍐呭
+     *
+     * @param oldProcessDefinition 閮ㄧ讲鍓嶆渶鏂版祦绋嬪畾涔�
+     * @param definition           閮ㄧ讲鍚庢渶鏂版祦绋嬪畾涔�
+     */
+    private void setWfConfig(ProcessDefinition oldProcessDefinition, ProcessDefinition definition) {
+        //鏇存柊娴佺▼瀹氫箟琛ㄥ崟
+        if (oldProcessDefinition != null) {
+            WfDefinitionConfigVo definitionVo = wfDefinitionConfigService.getByDefId(oldProcessDefinition.getId());
+            if (definitionVo != null) {
+                wfDefinitionConfigService.deleteByDefIds(Collections.singletonList(oldProcessDefinition.getId()));
+                WfDefinitionConfigBo wfDefinitionConfigBo = new WfDefinitionConfigBo();
+                wfDefinitionConfigBo.setDefinitionId(definition.getId());
+                wfDefinitionConfigBo.setProcessKey(definition.getKey());
+                wfDefinitionConfigBo.setTableName(definitionVo.getTableName());
+                wfDefinitionConfigBo.setVersion(definition.getVersion());
+                wfDefinitionConfigBo.setRemark(definitionVo.getRemark());
+                wfDefinitionConfigService.saveOrUpdate(wfDefinitionConfigBo);
+            }
+        }
+        //鏇存柊娴佺▼鑺傜偣閰嶇疆琛ㄥ崟
+        List<UserTask> userTasks = ModelUtils.getUserTaskFlowElements(definition.getId());
+        UserTask applyUserTask = ModelUtils.getApplyUserTask(definition.getId());
+        List<WfNodeConfig> wfNodeConfigList = new ArrayList<>();
+        for (UserTask userTask : userTasks) {
+            if (StringUtils.isNotBlank(userTask.getFormKey()) && userTask.getFormKey().contains(StrUtil.COLON)) {
+                WfNodeConfig wfNodeConfig = new WfNodeConfig();
+                wfNodeConfig.setNodeId(userTask.getId());
+                wfNodeConfig.setNodeName(userTask.getName());
+                wfNodeConfig.setDefinitionId(definition.getId());
+                String[] split = userTask.getFormKey().split(StrUtil.COLON);
+                wfNodeConfig.setFormType(split[0]);
+                wfNodeConfig.setFormId(Long.valueOf(split[1]));
+                wfNodeConfig.setApplyUserTask(applyUserTask.getId().equals(userTask.getId()) ? FlowConstant.TRUE : FlowConstant.FALSE);
+                wfNodeConfigList.add(wfNodeConfig);
+            }
+        }
+        if (CollUtil.isNotEmpty(wfNodeConfigList)) {
+            wfNodeConfigService.saveOrUpdate(wfNodeConfigList);
+        }
+    }
 }

--
Gitblit v1.9.3