mirror of
				https://github.com/dromara/RuoYi-Vue-Plus.git
				synced 2025-11-04 08:13:44 +08:00 
			
		
		
		
	update 调整模型部署,模型导出批量导出,上传
This commit is contained in:
		@@ -115,7 +115,7 @@ public class ActProcessDefinitionController extends BaseController {
 | 
			
		||||
    @RepeatSubmit()
 | 
			
		||||
    @PutMapping("/migrationDefinition/{currentProcessDefinitionId}/{fromProcessDefinitionId}")
 | 
			
		||||
    public R<Void> migrationDefinition(@NotBlank(message = "当前流程定义id") @PathVariable String currentProcessDefinitionId,
 | 
			
		||||
                                              @NotBlank(message = "需要迁移到的流程定义id") @PathVariable String fromProcessDefinitionId) {
 | 
			
		||||
                                       @NotBlank(message = "需要迁移到的流程定义id") @PathVariable String fromProcessDefinitionId) {
 | 
			
		||||
        return toAjax(actProcessDefinitionService.migrationDefinition(currentProcessDefinitionId, fromProcessDefinitionId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -139,8 +139,8 @@ public class ActProcessDefinitionController extends BaseController {
 | 
			
		||||
     */
 | 
			
		||||
    @Log(title = "流程定义管理", businessType = BusinessType.INSERT)
 | 
			
		||||
    @PostMapping("/deployByFile")
 | 
			
		||||
    public R<Void> deployByFile(@RequestParam("file") MultipartFile file, @RequestParam("categoryCode") String categoryCode) {
 | 
			
		||||
        return toAjax(actProcessDefinitionService.deployByFile(file, categoryCode));
 | 
			
		||||
    public void deployByFile(@RequestParam("file") MultipartFile file, @RequestParam("categoryCode") String categoryCode) {
 | 
			
		||||
        actProcessDefinitionService.deployByFile(file, categoryCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,8 @@ import org.dromara.workflow.domain.bo.ModelBo;
 | 
			
		||||
import org.dromara.workflow.domain.vo.ModelVo;
 | 
			
		||||
import org.flowable.engine.repository.Model;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 模型管理 服务层
 | 
			
		||||
@@ -66,8 +68,8 @@ public interface IActModelService {
 | 
			
		||||
    /**
 | 
			
		||||
     * 导出模型zip压缩包
 | 
			
		||||
     *
 | 
			
		||||
     * @param modelId  模型id
 | 
			
		||||
     * @param modelIds  模型id
 | 
			
		||||
     * @param response 相应
 | 
			
		||||
     */
 | 
			
		||||
    void exportZip(String modelId, HttpServletResponse response);
 | 
			
		||||
    void exportZip(List<String> modelIds, HttpServletResponse response);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -86,7 +86,6 @@ public interface IActProcessDefinitionService {
 | 
			
		||||
     *
 | 
			
		||||
     * @param file         文件
 | 
			
		||||
     * @param categoryCode 分类
 | 
			
		||||
     * @return 结果
 | 
			
		||||
     */
 | 
			
		||||
    boolean deployByFile(MultipartFile file, String categoryCode);
 | 
			
		||||
    void deployByFile(MultipartFile file, String categoryCode);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -281,35 +281,37 @@ public class ActModelServiceImpl implements IActModelService {
 | 
			
		||||
    /**
 | 
			
		||||
     * 导出模型zip压缩包
 | 
			
		||||
     *
 | 
			
		||||
     * @param modelId  模型id
 | 
			
		||||
     * @param modelIds  模型id
 | 
			
		||||
     * @param response 相应
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void exportZip(String modelId, HttpServletResponse response) {
 | 
			
		||||
    public void exportZip(List<String> modelIds, HttpServletResponse response) {
 | 
			
		||||
        ZipOutputStream zos = null;
 | 
			
		||||
        try {
 | 
			
		||||
            zos = ZipUtil.getZipOutputStream(response.getOutputStream(), StandardCharsets.UTF_8);
 | 
			
		||||
            // 压缩包文件名
 | 
			
		||||
            String zipName = "模型不存在";
 | 
			
		||||
            // 查询模型基本信息
 | 
			
		||||
            Model model = repositoryService.getModel(modelId);
 | 
			
		||||
            byte[] xmlBytes = repositoryService.getModelEditorSource(modelId);
 | 
			
		||||
            if (ObjectUtil.isNotNull(model)) {
 | 
			
		||||
                if (JSONUtil.isTypeJSON(IOUtils.toString(xmlBytes, StandardCharsets.UTF_8.toString())) && ArrayUtil.isEmpty(ModelUtils.bpmnJsonToXmlBytes(xmlBytes))) {
 | 
			
		||||
                    zipName = "模型不能为空,请至少设计一条主线流程!";
 | 
			
		||||
                    zos.putNextEntry(new ZipEntry(zipName + ".txt"));
 | 
			
		||||
                    zos.write(zipName.getBytes(StandardCharsets.UTF_8));
 | 
			
		||||
                } else if (ArrayUtil.isEmpty(xmlBytes)) {
 | 
			
		||||
                    zipName = "模型数据为空,请先设计流程定义模型,再进行部署!";
 | 
			
		||||
                    zos.putNextEntry(new ZipEntry(zipName + ".txt"));
 | 
			
		||||
                    zos.write(zipName.getBytes(StandardCharsets.UTF_8));
 | 
			
		||||
                } else {
 | 
			
		||||
                    String fileName = model.getName() + "-" + model.getKey();
 | 
			
		||||
                    // 压缩包文件名
 | 
			
		||||
                    zipName = fileName + ".zip";
 | 
			
		||||
                    // 将xml添加到压缩包中(指定xml文件名:请假流程.bpmn20.xml
 | 
			
		||||
                    zos.putNextEntry(new ZipEntry(fileName + ".bpmn20.xml"));
 | 
			
		||||
                    zos.write(xmlBytes);
 | 
			
		||||
            for (String modelId : modelIds) {
 | 
			
		||||
                Model model = repositoryService.getModel(modelId);
 | 
			
		||||
                byte[] xmlBytes = repositoryService.getModelEditorSource(modelId);
 | 
			
		||||
                if (ObjectUtil.isNotNull(model)) {
 | 
			
		||||
                    if (JSONUtil.isTypeJSON(IOUtils.toString(xmlBytes, StandardCharsets.UTF_8.toString())) && ArrayUtil.isEmpty(ModelUtils.bpmnJsonToXmlBytes(xmlBytes))) {
 | 
			
		||||
                        zipName = "模型不能为空,请至少设计一条主线流程!";
 | 
			
		||||
                        zos.putNextEntry(new ZipEntry(zipName + ".txt"));
 | 
			
		||||
                        zos.write(zipName.getBytes(StandardCharsets.UTF_8));
 | 
			
		||||
                    } else if (ArrayUtil.isEmpty(xmlBytes)) {
 | 
			
		||||
                        zipName = "模型数据为空,请先设计流程定义模型,再进行部署!";
 | 
			
		||||
                        zos.putNextEntry(new ZipEntry(zipName + ".txt"));
 | 
			
		||||
                        zos.write(zipName.getBytes(StandardCharsets.UTF_8));
 | 
			
		||||
                    } else {
 | 
			
		||||
                        String fileName = model.getName() + "-" + model.getKey();
 | 
			
		||||
                        // 压缩包文件名
 | 
			
		||||
                        zipName = fileName + ".zip";
 | 
			
		||||
                        // 将xml添加到压缩包中(指定xml文件名:请假流程.bpmn20.xml
 | 
			
		||||
                        zos.putNextEntry(new ZipEntry(fileName + ".bpmn20.xml"));
 | 
			
		||||
                        zos.write(xmlBytes);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            response.setHeader("Content-Disposition",
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ 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 lombok.RequiredArgsConstructor;
 | 
			
		||||
@@ -28,6 +29,7 @@ import org.flowable.engine.impl.bpmn.deployer.ResourceNameUtil;
 | 
			
		||||
import org.flowable.engine.repository.*;
 | 
			
		||||
import org.flowable.task.api.history.HistoricTaskInstance;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
import org.springframework.web.multipart.MultipartFile;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
@@ -36,6 +38,7 @@ import java.nio.charset.StandardCharsets;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.zip.ZipEntry;
 | 
			
		||||
import java.util.zip.ZipInputStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -265,59 +268,69 @@ public class ActProcessDefinitionServiceImpl implements IActProcessDefinitionSer
 | 
			
		||||
     * @param file         文件
 | 
			
		||||
     * @param categoryCode 分类
 | 
			
		||||
     */
 | 
			
		||||
    @SneakyThrows
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean deployByFile(MultipartFile file, String categoryCode) {
 | 
			
		||||
        try {
 | 
			
		||||
            WfCategory wfCategory = wfCategoryService.queryByCategoryCode(categoryCode);
 | 
			
		||||
            if (wfCategory == null) {
 | 
			
		||||
                throw new ServiceException("流程分类不存在");
 | 
			
		||||
            }
 | 
			
		||||
            // 文件名 = 流程名称-流程key
 | 
			
		||||
            String filename = file.getOriginalFilename();
 | 
			
		||||
            assert filename != null;
 | 
			
		||||
            String[] splitFilename = filename.substring(0, filename.lastIndexOf(".")).split("-");
 | 
			
		||||
            if (splitFilename.length < 2) {
 | 
			
		||||
                throw new ServiceException("流程分类不能为空(文件名 = 流程名称-流程key)");
 | 
			
		||||
            }
 | 
			
		||||
            //流程名称
 | 
			
		||||
            String processName = splitFilename[0];
 | 
			
		||||
            //流程key
 | 
			
		||||
            String processKey = splitFilename[1];
 | 
			
		||||
            // 文件后缀名
 | 
			
		||||
            String suffix = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
 | 
			
		||||
            InputStream inputStream = file.getInputStream();
 | 
			
		||||
            Deployment deployment;
 | 
			
		||||
            if (FlowConstant.ZIP.equals(suffix)) {
 | 
			
		||||
                DeploymentBuilder builder = repositoryService.createDeployment();
 | 
			
		||||
                deployment = builder.addZipInputStream(new ZipInputStream(inputStream))
 | 
			
		||||
                    .tenantId(TenantHelper.getTenantId())
 | 
			
		||||
                    .name(processName).key(processKey).category(categoryCode).deploy();
 | 
			
		||||
            } else {
 | 
			
		||||
                String[] list = ResourceNameUtil.BPMN_RESOURCE_SUFFIXES;
 | 
			
		||||
                boolean flag = false;
 | 
			
		||||
                for (String str : list) {
 | 
			
		||||
                    if (filename.contains(str)) {
 | 
			
		||||
                        flag = true;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (flag) {
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void deployByFile(MultipartFile file, String categoryCode) {
 | 
			
		||||
 | 
			
		||||
        WfCategory wfCategory = wfCategoryService.queryByCategoryCode(categoryCode);
 | 
			
		||||
        if (wfCategory == null) {
 | 
			
		||||
            throw new ServiceException("流程分类不存在");
 | 
			
		||||
        }
 | 
			
		||||
        // 文件后缀名
 | 
			
		||||
        String suffix = FileUtil.extName(file.getOriginalFilename());
 | 
			
		||||
        InputStream inputStream = file.getInputStream();
 | 
			
		||||
        if (FlowConstant.ZIP.equalsIgnoreCase(suffix)) {
 | 
			
		||||
            ZipInputStream zipInputStream = null;
 | 
			
		||||
            try {
 | 
			
		||||
                zipInputStream = new ZipInputStream(inputStream);
 | 
			
		||||
                ZipEntry zipEntry;
 | 
			
		||||
                while ((zipEntry = zipInputStream.getNextEntry()) != null) {
 | 
			
		||||
                    String filename = zipEntry.getName();
 | 
			
		||||
                    String[] splitFilename = filename.substring(0, filename.lastIndexOf(".")).split("-");
 | 
			
		||||
                    //流程名称
 | 
			
		||||
                    String processName = splitFilename[0];
 | 
			
		||||
                    //流程key
 | 
			
		||||
                    String processKey = splitFilename[1];
 | 
			
		||||
                    DeploymentBuilder builder = repositoryService.createDeployment();
 | 
			
		||||
                    deployment = builder.addInputStream(filename, inputStream)
 | 
			
		||||
                    Deployment deployment = builder.addInputStream(filename, zipInputStream)
 | 
			
		||||
                        .tenantId(TenantHelper.getTenantId())
 | 
			
		||||
                        .name(processName).key(processKey).category(categoryCode).deploy();
 | 
			
		||||
                } else {
 | 
			
		||||
                    throw new ServiceException("文件类型上传错误!");
 | 
			
		||||
                    ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult();
 | 
			
		||||
                    repositoryService.setProcessDefinitionCategory(definition.getId(), categoryCode);
 | 
			
		||||
                    zipInputStream.closeEntry();
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                throw new RuntimeException(e);
 | 
			
		||||
            } finally {
 | 
			
		||||
                if (zipInputStream != null) {
 | 
			
		||||
                    zipInputStream.close();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // 更新分类
 | 
			
		||||
            ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult();
 | 
			
		||||
            repositoryService.setProcessDefinitionCategory(definition.getId(), categoryCode);
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            throw new ServiceException("部署失败" + e.getMessage());
 | 
			
		||||
        } else {
 | 
			
		||||
            String originalFilename = file.getOriginalFilename();
 | 
			
		||||
            String bpmnResourceSuffix = ResourceNameUtil.BPMN_RESOURCE_SUFFIXES[0];
 | 
			
		||||
            if (originalFilename.contains(bpmnResourceSuffix)) {
 | 
			
		||||
                // 文件名 = 流程名称-流程key
 | 
			
		||||
                String[] splitFilename = originalFilename.substring(0, originalFilename.lastIndexOf(".")).split("-");
 | 
			
		||||
                if (splitFilename.length < 2) {
 | 
			
		||||
                    throw new ServiceException("文件名 = 流程名称-流程KEY");
 | 
			
		||||
                }
 | 
			
		||||
                //流程名称
 | 
			
		||||
                String processName = splitFilename[0];
 | 
			
		||||
                //流程key
 | 
			
		||||
                String processKey = splitFilename[1];
 | 
			
		||||
                DeploymentBuilder builder = repositoryService.createDeployment();
 | 
			
		||||
                Deployment deployment = builder.addInputStream(originalFilename, inputStream)
 | 
			
		||||
                    .tenantId(TenantHelper.getTenantId())
 | 
			
		||||
                    .name(processName).key(processKey).category(categoryCode).deploy();
 | 
			
		||||
                // 更新分类
 | 
			
		||||
                ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult();
 | 
			
		||||
                repositoryService.setProcessDefinitionCategory(definition.getId(), categoryCode);
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new ServiceException("文件类型上传错误!");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -195,7 +195,7 @@ public class ModelUtils {
 | 
			
		||||
     *
 | 
			
		||||
     * @param processDefinitionId 流程定义id
 | 
			
		||||
     */
 | 
			
		||||
    public Map<String, List<ExtensionElement>> getExtensionElements(String processDefinitionId) {
 | 
			
		||||
    public static Map<String, List<ExtensionElement>> getExtensionElements(String processDefinitionId) {
 | 
			
		||||
        Map<String, List<ExtensionElement>> map = new HashMap<>();
 | 
			
		||||
        List<FlowElement> flowElements = getFlowElements(processDefinitionId);
 | 
			
		||||
        for (FlowElement flowElement : flowElements) {
 | 
			
		||||
@@ -212,7 +212,7 @@ public class ModelUtils {
 | 
			
		||||
     * @param processDefinitionId 流程定义id
 | 
			
		||||
     * @param flowElementId       节点id
 | 
			
		||||
     */
 | 
			
		||||
    public Map<String, List<ExtensionElement>> getExtensionElement(String processDefinitionId, String flowElementId) {
 | 
			
		||||
    public static Map<String, List<ExtensionElement>> getExtensionElement(String processDefinitionId, String flowElementId) {
 | 
			
		||||
        BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(processDefinitionId);
 | 
			
		||||
        Process process = bpmnModel.getMainProcess();
 | 
			
		||||
        FlowElement flowElement = process.getFlowElement(flowElementId);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" ?>
 | 
			
		||||
<!DOCTYPE mapper
 | 
			
		||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
<mapper namespace="org.dromara.workflow.mapper.ActHiProcinstMapper">
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" ?>
 | 
			
		||||
<!DOCTYPE mapper
 | 
			
		||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
<mapper namespace="org.dromara.workflow.mapper.ActHiTaskinstMapper">
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" ?>
 | 
			
		||||
<!DOCTYPE mapper
 | 
			
		||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
<mapper namespace="org.dromara.workflow.mapper.TestLeaveMapper">
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" ?>
 | 
			
		||||
<!DOCTYPE mapper
 | 
			
		||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
<mapper namespace="org.dromara.workflow.mapper.WfCategoryMapper">
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user