查询所有流程定义模型数据
@Autowired
RepositoryService repositoryService;
@Test
public void modelList() {
// 获取模型查询对象
ModelQuery query = repositoryService.createModelQuery();
// 按模型创建时间 降序 排列
List<Model> list = query.orderByCreateTime().desc().list();
for (Model model : list) {
System.out.print("模型id:" + model.getId());
System.out.print(",模型名称:" + model.getName());
System.out.print(",模型描述:" + model.getMetaInfo());
System.out.print(",模型标识key:" + model.getKey());
System.out.print(",模型版本号:" + model.getVersion());
System.out.print(",创建时间:" + model.getCreateTime());
System.out.println("更新时间:" + model.getLastUpdateTime());
}
}
删除流程模型
通过模型ID删除模型:
@Test
public void testDeleteModel() {
String id = "c0062cd1-c794-11ec-9690-28d0ea3dce6b";
repositoryService.deleteModel(id);
System.out.println("删除成功");
}
执行后:对应的模型数据就被删除了
导出下载模型图zip压缩包
导出下载模型图zip压缩包,压缩包中有 .bpmn20.xml 流程描述和 .png 图片资源
在流程部署时,可以使用上传流程模型图zip压缩包进行部署
@Autowired
RepositoryService repositoryService;
@Autowired
ObjectMapper objectMapper;
@Test
public void export() throws IOException {
String id = "90107020-c79a-11ec-a41a-28d0ea3dce6b";
// 查询模型信息
Model model = repositoryService.getModel(id);
if (model != null) {
// 获取流程图 json 字节码
byte[] bpmnJsonBytes = repositoryService.getModelEditorSource(id);
// 流程图 json 字节码转 xml 字节码
byte[] xmlBytes = bpmnJsonToXmlBytes(bpmnJsonBytes);
if (xmlBytes == null) {
System.out.println("模型数据为空-请先设计完整流程-再导出");
} else {
// 压缩包文件名
String zipName = model.getName() + "." + model.getKey() + ".zip";
// 文件输出流
File file = new File("D:/" + zipName);
FileOutputStream outputStream = new FileOutputStream(file);
// 实例化zip压缩对象输出流
ZipOutputStream zipos = new ZipOutputStream(outputStream);
// 指定压缩包里的 name.bpmn20.xml 文件名
zipos.putNextEntry(new ZipEntry(model.getName() + ".bpmn20.xml"));
// 将xml写入压缩流
zipos.write(xmlBytes);
// 查询png图片,
byte[] pngBytes = repositoryService.getModelEditorSourceExtra(id);
if (pngBytes != null) {
// 指定压缩包里的 name.key.png 文件名
zipos.putNextEntry(new ZipEntry(model.getName() + "." + model.getKey() + ".png"));
// 图片文件写到压缩包中
zipos.write(pngBytes);
}
zipos.closeEntry();
zipos.close();
System.out.println("导出成功");
}
} else {
System.out.println("模型不存在");
}
}
/**
* 流程图保存的时候是json串,引擎认识的却是符合bpmn2.0规范的xml,
* json 字节码转 xml 字节码
*
*/
private byte[] bpmnJsonToXmlBytes(byte[] jsonBytes) throws IOException {
if (jsonBytes == null) {
return null;
}
// json转回BpmnModel对象
JsonNode modelNode = objectMapper.readTree(jsonBytes);
BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(modelNode);
if (bpmnModel.getProcesses().size() == 0) {
return null;
}
// BpmnModel对象转xml字节数组
return new BpmnXMLConverter().convertToXML(bpmnModel);
}
生成的文件:
导出下载模型 xml 文件
在流程部署时,可以只上传流程模型图 xml 文件进行部署
@Test
public void exportXml() throws Exception {
// 模型id
String id = "90107020-c79a-11ec-a41a-28d0ea3dce6b";
ByteArrayInputStream in = null;
// 获取流程图 json 字节码
byte[] bytes = repositoryService.getModelEditorSource(id);
// json转xml字节数组
String filename = null;
if(bytes != null) {
JsonNode modelNode = objectMapper.readTree(bytes);
BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(modelNode);
if(bpmnModel.getProcesses().size() != 0) {
// 转xml字节数组
byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(bpmnModel);
in = new ByteArrayInputStream(bpmnBytes);
// 如果流程名称为空,则取流程定义key
filename = StringUtils.isEmpty(bpmnModel.getMainProcess().getName()) ?
bpmnModel.getMainProcess().getId() : bpmnModel.getMainProcess().getName();
}
}
if(filename == null) {
filename = "模型数据为空,请先设计流程,再导出";
in = new ByteArrayInputStream(filename.getBytes(StandardCharsets.UTF_8));
}
// 文件输出流
FileOutputStream out = new FileOutputStream(new File("D:/" + filename + ".bpmn20.xml"));
// 输入流,输出流的转换
IOUtils.copy(in, out);
// 关闭流
out.close();
in.close();
System.out.println("下载模型 xml 文件成功");
}
通过模型数据 部署 流程定义
注意事项:
每个流程定义模型可以多次流程定义部署,activiti 通过流程定义模型中的标识 key 来判断是否为同一流程模型, 相同标识key则视为同一流程定义模型。
相同的标识key流程定义模型,每部署一次对应的新增一条流程定义数据,对应流程定义版本号会基于之前的加1。
/**
* 流程图保存的时候是json串,引擎认识的却是符合bpmn2.0规范的xml,
* 所以在首次的部署的时候要将json串转换为BpmnModel,
* 再将BpmnModel转换成xml保存进数据库,以后每次使用就直接将xml转换成BpmnModel
* @author wen.jie
* @date 2022/4/29 17:23
*/
@Test
public void deploy() throws Exception {
// 模型id
String id = "90107020-c79a-11ec-a41a-28d0ea3dce6b";
// 获取流程图 json 字节码
byte[] jsonBytes = repositoryService.getModelEditorSource(id);
if (jsonBytes == null) {
System.out.println("模型数据为空,请先设计流程并成功保存,再进行发布。");
return;
}
// 转xml字节数组
byte[] xmlBytes = bpmnJsonToXmlBytes(jsonBytes);
if(xmlBytes == null){
System.out.println("数据模型不符要求,请至少设计一条主线流程。");
return;
}
// 流程图片字节码
byte[] pngBytes = repositoryService.getModelEditorSourceExtra(id);
// 获取模型
Model model = repositoryService.getModel(id);
// 流程定义xml名称
String processName = model.getName() + ".bpmn20.xml";
// 流程定义png名称
String pngName = model.getName() +"." + model.getKey() + ".png";
// 流程部署
Deployment deployment = repositoryService.createDeployment()
.name(model.getName())
.addString(processName, new String(xmlBytes, "UTF-8")) // xml文件
.addBytes(pngName, pngBytes ) // 图片
.deploy();
// 更新 部署id 到模型对象(将模型与部署数据绑定)
model.setDeploymentId(deployment.getId());
repositoryService.saveModel(model);
System.out.println("部署完成");
}
执行效果:
部署流程定义涉及表:
ACT_RE_PROCDEF 新增数据: 流程定义数据
ACT_RE_DEPLOYMENT 新增数据: 流程部署数据
ACT_GE_BYTEARRAY 新增数据:流程定义 xml 和 png 保存下来,对应绑定到此流程定义数据上 ACT_RE_MODEL 更新部署id
部署流程报错:
-
报错:元素 'sequenceFlow' 中必须包含属性 'targetRef'
解决:流程唯一标识 不能以数字开头,以字母开头
-
报错:元素 'sequenceFlow' 中必须包含属性 'sourceRef'
解决:两个图标箭头连线,箭头来源和目标多拉一点到图标上。