六、入侵Activiti-SpringBoot使用代码动态编辑流程文件

需求总是变来变去,产品希望可以实现动态改变工作流程,从而提高系统的灵活性。这就让我有点懵逼了。

查了一些资料,有两种实现方式:

  1. 前端页面生成bpmn文件,传送给后台,但是对前端的要求比较高。
  2. 使用Java代码动态更改流程文件,达到修改流程的目的。

这里使用代码的方式来实现,接下来使用一个Demo做一个简单的示例。

一、使用Activiti Modeler画一个流程图

该流程图会保存到数据库的ACT_REP_MODEL表中。

流程图定义如下:
整体定义

六、入侵Activiti-SpringBoot使用代码动态编辑流程文件_第1张图片

开始定义

六、入侵Activiti-SpringBoot使用代码动态编辑流程文件_第2张图片

开始和userTask的箭头定义

六、入侵Activiti-SpringBoot使用代码动态编辑流程文件_第3张图片

userTask定义

六、入侵Activiti-SpringBoot使用代码动态编辑流程文件_第4张图片

userTask和结束的箭头定义

六、入侵Activiti-SpringBoot使用代码动态编辑流程文件_第5张图片

结束定义

六、入侵Activiti-SpringBoot使用代码动态编辑流程文件_第6张图片

二、项目中需要引入的依赖

//Activiti
compile('org.activiti:activiti-spring-boot-starter-basic:5.22.0')
compile('org.activiti:activiti-modeler:5.22.0'){
        //排除Security依赖,否则需要输入密码才能访问项目
        exclude group: 'org.springframework.security'
    }
//布局排版,当使用代码编辑流程图时,需要自动排版,否则会因为找不到位置信息而报错
compile group: 'org.activiti', name: 'activiti-bpmn-layout', version: '5.22.0'

三、使用代码修改流程图

只是个Demo,很多数据是硬编码,熟悉原理后,可以自己写活。注释都写清楚了,不多解释。

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.bpmn.BpmnAutoLayout;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.UserTask;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.*;

/**
 * @author [email protected]
 * @date 2017/8/31 下午2:39
 * @desc 这块是很重要的核心代码,用代码来编辑流程图.
 */
@RestController
@RequestMapping("/modify")
public class ModifyController {

    //注入Activiti的RepositoryService
    @Resource
    RepositoryService repositoryService;

    //
    @RequestMapping(value = "/modify", method = RequestMethod.GET)
    public void modifyBPMN() throws IOException {
        //读取指定ID的Model的二进制资源,是Json格式的。
        byte[] modelSource = repositoryService.getModelEditorSource("3");
        //使用jackson将Model的源信息转换为JsonNode对象
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = mapper.readTree(modelSource);
        //创建一个bpmn的json转换器
        BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
        //将jsonNode对象转换为bpmnModel的对象
        BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(jsonNode);


        //读取bpmnModel中id为process的流程定义
        Process process = bpmnModel.getProcessById("process");

        //创建一个UserTask任务,id为b3,
        UserTask userTask = new UserTask();
        userTask.setId("b3");
        userTask.setName("userTask2");
        userTask.setAssignee("小金");

        //添加到流程中
        process.addFlowElement(userTask);

        //移除开始和userTask1之间的a2箭头,
        process.removeFlowElement("a2");

        //创建一个新的箭头从b2指向b3,也就是从userTask1连接到userTask2
        SequenceFlow flow1 = new SequenceFlow();
        flow1.setSourceRef("b2");
        flow1.setTargetRef("b3");

        //创建一个新的箭头从b3指向b4,也就是从userTask2连接到结束事件
        SequenceFlow flow2 = new SequenceFlow();
        flow2.setSourceRef("b3");
        flow2.setTargetRef("b4");
        //将两个箭头添加到流程定义中
        process.addFlowElement(flow1);
        process.addFlowElement(flow2);

        //对文件进行重新排版,生成位置信息,否则会报错
        new BpmnAutoLayout(bpmnModel).execute();

        //创建一个bpmn的xml转换器,
        BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
        //这里将结果输出到一个文件中,查看是否成功,(必需成功)
        byte[] bytes = xmlConverter.convertToXML(bpmnModel);
        FileOutputStream fileOutputStream = new FileOutputStream("/Users/kingboy/Desktop/MyDIY.bpmn");
        fileOutputStream.write(bytes);
        fileOutputStream.close();
    }
}

最终生成的流程图如下:

六、入侵Activiti-SpringBoot使用代码动态编辑流程文件_第7张图片

虽然只是个Demo,但是其中可以演化出很多技能。比如说,我们拿到了bpmn的xml流了,那么肯定就可以直接部署到引擎中了。

这个Demo是修改已有的流程,那么我们可不可以用代码直接新建一个流程图呢?当然是可以的,只要认真看下涉及到的几个类的API,就很容易了。

学的是思想而不能仅仅局限于技术。

你可能感兴趣的:(☀Java,-------【三方类库】)