mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2025-09-30 15:16:41 +08:00
添加模型部署,导出模型
This commit is contained in:
parent
1ce0e61aba
commit
3a5e34acc7
@ -1,4 +1,4 @@
|
||||
package org.dromara.workflow.domain.bo;
|
||||
package org.dromara.workflow.common;
|
||||
|
||||
|
||||
/**
|
@ -0,0 +1,16 @@
|
||||
package org.dromara.workflow.common.constant;
|
||||
|
||||
|
||||
/**
|
||||
* 工作流常量
|
||||
*
|
||||
* @author may
|
||||
*/
|
||||
public interface FlowConstant {
|
||||
|
||||
/**
|
||||
* 命名空间
|
||||
*/
|
||||
String NAMESPACE = "http://b3mn.org/stencilset/bpmn2.0#";
|
||||
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package org.dromara.workflow.controller;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
@ -46,8 +48,7 @@ public class ActModelController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 参考官方提供的响应数据
|
||||
* "{\"id\":\"admin\",\"firstName\":\"Test\",\"lastName\":\"Administrator\",\"email\":\"admin@flowable.org\",\"fullName\":\"Test Administrator\",\"groups\":[],\"privileges\":[\"access-idm\",\"access-rest-api\",\"access-task\",\"access-modeler\",\"access-admin\"]}";
|
||||
* 设计器登录信息
|
||||
*/
|
||||
@GetMapping("/rest/account")
|
||||
public String getAccount() {
|
||||
@ -65,6 +66,7 @@ public class ActModelController extends BaseController {
|
||||
* @param modelBo 模型请求对象
|
||||
*/
|
||||
@Log(title = "模型管理", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/rest/models")
|
||||
public R<Void> saveNewModel(@Validated(AddGroup.class) @RequestBody ModelBo modelBo) {
|
||||
return toAjax(iActModelService.saveNewModel(modelBo));
|
||||
@ -88,6 +90,7 @@ public class ActModelController extends BaseController {
|
||||
* @param values 模型数据
|
||||
*/
|
||||
@Log(title = "模型管理", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PostMapping(value = "/rest/models/{modelId}/editor/json")
|
||||
public R<Void> editModel(@PathVariable String modelId, @RequestParam MultiValueMap<String, String> values) {
|
||||
return toAjax(iActModelService.editModel(modelId, values));
|
||||
@ -109,4 +112,28 @@ public class ActModelController extends BaseController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型部署
|
||||
*
|
||||
* @param id 模型id
|
||||
*/
|
||||
@Log(title = "模型管理", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/modelDeploy/{id}")
|
||||
public R<Void> deploy(@NotBlank(message = "模型id不能为空") @PathVariable("id") String id) {
|
||||
return toAjax(iActModelService.modelDeploy(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出模型zip压缩包
|
||||
*
|
||||
* @param modelId 模型id
|
||||
* @param response 相应
|
||||
*/
|
||||
@GetMapping("/export/zip/{modelId}")
|
||||
public void exportZip(@NotEmpty(message = "模型id不能为空") @PathVariable String modelId,
|
||||
HttpServletResponse response) {
|
||||
iActModelService.exportZip(modelId, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.workflow.common.PageEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.dromara.workflow.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.workflow.domain.bo.ModelBo;
|
||||
import org.flowable.engine.repository.Model;
|
||||
@ -44,4 +45,20 @@ public interface IActModelService {
|
||||
* @return 结果
|
||||
*/
|
||||
boolean editModel(String modelId, MultiValueMap<String, String> values);
|
||||
|
||||
/**
|
||||
* 模型部署
|
||||
*
|
||||
* @param id 模型id
|
||||
* @return 结果
|
||||
*/
|
||||
boolean modelDeploy(String id);
|
||||
|
||||
/**
|
||||
* 导出模型zip压缩包
|
||||
*
|
||||
* @param modelId 模型id
|
||||
* @param response 相应
|
||||
*/
|
||||
void exportZip(String modelId, HttpServletResponse response);
|
||||
}
|
||||
|
@ -5,9 +5,11 @@ import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
@ -22,6 +24,7 @@ import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.editor.constants.ModelDataJsonConstants;
|
||||
import org.flowable.editor.language.json.converter.BpmnJsonConverter;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.repository.Deployment;
|
||||
import org.flowable.engine.repository.Model;
|
||||
import org.flowable.engine.repository.ModelQuery;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -31,11 +34,15 @@ import org.springframework.util.MultiValueMap;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import static org.dromara.workflow.common.constant.FlowConstant.NAMESPACE;
|
||||
import static org.flowable.editor.constants.ModelDataJsonConstants.*;
|
||||
|
||||
/**
|
||||
@ -118,11 +125,10 @@ public class ActModelServiceImpl implements IActModelService {
|
||||
model.setMetaInfo(objectNode.toString());
|
||||
// 保存初始化的模型基本信息数据
|
||||
repositoryService.saveModel(model);
|
||||
String namespace = "http://b3mn.org/stencilset/bpmn2.0#";
|
||||
// 封装模型对象基础数据json串
|
||||
ObjectNode editorNode = objectMapper.createObjectNode();
|
||||
ObjectNode stencilSetNode = objectMapper.createObjectNode();
|
||||
stencilSetNode.put("namespace", namespace);
|
||||
stencilSetNode.put("namespace", NAMESPACE);
|
||||
editorNode.replace("stencilset", stencilSetNode);
|
||||
// 标识key
|
||||
ObjectNode propertiesNode = objectMapper.createObjectNode();
|
||||
@ -206,10 +212,9 @@ public class ActModelServiceImpl implements IActModelService {
|
||||
// 获取唯一标识key
|
||||
String key = values.getFirst("key");
|
||||
List<Model> list = repositoryService.createModelQuery().modelKey(key).modelTenantId(LoginHelper.getTenantId()).list();
|
||||
List<Model> modelList = list.stream().filter(e -> !e.getId().equals(model.getId())).collect(Collectors.toList());
|
||||
if (CollectionUtil.isNotEmpty(modelList)) {
|
||||
list.stream().filter(e -> !e.getId().equals(model.getId())).findFirst().ifPresent(e -> {
|
||||
throw new ServiceException("模型key已存在!");
|
||||
}
|
||||
});
|
||||
model.setKey(key);
|
||||
repositoryService.saveModel(model);
|
||||
byte[] xmlBytes = WorkflowUtils.bpmnJsonToXmlBytes(Objects.requireNonNull(values.getFirst("json_xml")).getBytes(StandardCharsets.UTF_8));
|
||||
@ -217,24 +222,100 @@ public class ActModelServiceImpl implements IActModelService {
|
||||
throw new ServiceException("模型不能为空!");
|
||||
}
|
||||
repositoryService.addModelEditorSource(model.getId(), xmlBytes);
|
||||
|
||||
/*InputStream svgStream = new ByteArrayInputStream(values.getFirst("svg_xml").getBytes(StandardCharsets.UTF_8));
|
||||
TranscoderInput input = new TranscoderInput(svgStream);
|
||||
|
||||
PNGTranscoder transcoder = new PNGTranscoder();
|
||||
// Setup output
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
TranscoderOutput output = new TranscoderOutput(outStream);
|
||||
|
||||
// Do the transformation
|
||||
transcoder.transcode(input, output);
|
||||
final byte[] result = outStream.toByteArray();
|
||||
repositoryService.addModelEditorSourceExtra(model.getId(), result);
|
||||
outStream.close();*/
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型部署
|
||||
*
|
||||
* @param id 模型id
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean modelDeploy(String id) {
|
||||
try {
|
||||
//查询流程定义模型xml
|
||||
byte[] xmlBytes = repositoryService.getModelEditorSource(id);
|
||||
if (ArrayUtil.isEmpty(xmlBytes)) {
|
||||
throw new ServiceException("模型数据为空,请先设计流程定义模型,再进行部署!");
|
||||
}
|
||||
// 查询模型的基本信息
|
||||
Model model = repositoryService.getModel(id);
|
||||
// xml资源的名称 ,对应act_ge_bytearray表中的name_字段
|
||||
String processName = model.getName() + ".bpmn20.xml";
|
||||
//调用部署相关的api方法进行部署流程定义
|
||||
Deployment deployment = repositoryService.createDeployment()
|
||||
// 部署名称
|
||||
.name(model.getName())
|
||||
// 部署标识key
|
||||
.key(model.getKey())
|
||||
// 部署流程分类
|
||||
.category(model.getCategory())
|
||||
// bpmn20.xml资源
|
||||
.addBytes(processName, xmlBytes)
|
||||
// 租户id
|
||||
.tenantId(LoginHelper.getTenantId())
|
||||
.deploy();
|
||||
|
||||
// 更新 部署id 到流程定义模型数据表中
|
||||
model.setDeploymentId(deployment.getId());
|
||||
repositoryService.saveModel(model);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出模型zip压缩包
|
||||
*
|
||||
* @param modelId 模型id
|
||||
* @param response 相应
|
||||
*/
|
||||
@Override
|
||||
public void exportZip(String modelId, HttpServletResponse response) {
|
||||
ZipOutputStream zos = null;
|
||||
try {
|
||||
zos = ZipUtil.getZipOutputStream(response.getOutputStream(), StandardCharsets.UTF_8);
|
||||
// 压缩包文件名
|
||||
String zipName = "模型不存在";
|
||||
//查询模型基本信息
|
||||
Model model = repositoryService.getModel(modelId);
|
||||
if (ObjectUtil.isNotNull(model)) {
|
||||
// 查询流程定义模型的json字节码
|
||||
byte[] xmlBytes = repositoryService.getModelEditorSource(modelId);
|
||||
if (ArrayUtil.isEmpty(xmlBytes)) {
|
||||
zipName = "模型数据为空,请先设计流程定义模型,再进行部署!";
|
||||
} 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",
|
||||
"attachment; filename=" + URLEncoder.encode(zipName, StandardCharsets.UTF_8) + ".zip");
|
||||
// 刷出响应流
|
||||
response.flushBuffer();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (zos != null) {
|
||||
try {
|
||||
zos.closeEntry();
|
||||
zos.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user