update 调整模型部署,模型导出批量导出,上传

This commit is contained in:
gssong 2024-03-16 21:59:53 +08:00
parent 6086db3b0b
commit f3207649ff
10 changed files with 100 additions and 84 deletions

View File

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

View File

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

View File

@ -86,7 +86,6 @@ public interface IActProcessDefinitionService {
*
* @param file 文件
* @param categoryCode 分类
* @return 结果
*/
boolean deployByFile(MultipartFile file, String categoryCode);
void deployByFile(MultipartFile file, String categoryCode);
}

View File

@ -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",

View File

@ -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("文件类型上传错误!");
}
}
}
}

View File

@ -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);

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>