Activiti6.0(九)整合自定义在线流程设计器(BpmnModel使用)

目录前端

1、前言java

2、整合spring


1、前言

前面全部的例子都是先基于Activiti-app在线绘制流程图,而后导出为xml文件,最后做为外部资源被部署到数据库的,虽然该种方式功能很强大可是不太好集成,有些现有的在线流程编辑器也实在是过于复杂和丑陋,用户并不须要配置那么多东西。docker

所以将流程的设计过程交给用户时,用户确定须要一个美观、简洁的流程设计器,那这玩意就由各公司本身寻找合适的开源工具或者本身开发一个前端流程图组件,咱们公司以前便本身开发了一个简便的流程图组件,那么整个流程图的数据格式该怎么定义呢?定义好后该怎么部署到Activiti呢?数据库

 

2、整合

在整合以前咱们确定须要先拿到json数据,而前端透传过来的流程图数据结构能够是自定义的带上各类各样的业务信息的,只是在转换到Activiti这一层时须要将咱们自定义的json数据转化成Activiti所认识的数据,Activiti的流程图保存数据格式咱们其实能够拿到,就是在Activiti-app保存时按下f12查看保存请求便可,哈哈哈哈哈是否是很简单?大致思路是否是有了?下面给出一个超级简单流程图以及对应的json数据(为了省空间json数据可自行格式):json

{"resourceId":"5c5040fe-b196-433d-b34e-3d01cd6c85dc","properties":{"process_id":"simpleModel","name":"简单流程","documentation":"","process_author":"","process_version":"","process_namespace":"http://www.activiti.org/processdef","executionlisteners":"","eventlisteners":"","signaldefinitions":"","messagedefinitions":""},"stencil":{"id":"BPMNDiagram"},"childShapes":[{"resourceId":"startEvent1","properties":{"overrideid":"","name":"","documentation":"","executionlisteners":"","initiator":"","formkeydefinition":"","formreference":"","formproperties":""},"stencil":{"id":"StartNoneEvent"},"childShapes":[],"outgoing":[{"resourceId":"sid-1007C45C-AB28-4EA8-87C9-0E35B6FFA141"}],"bounds":{"lowerRight":{"x":130,"y":193},"upperLeft":{"x":100,"y":163}},"dockers":[]},{"resourceId":"sid-584C69B4-A76F-4396-8FE1-1FC77C0385CC","properties":{"overrideid":"","name":"组长审批","documentation":"","asynchronousdefinition":"false","exclusivedefinition":"false","executionlisteners":"","multiinstance_type":"None","multiinstance_cardinality":"","multiinstance_collection":"","multiinstance_variable":"","multiinstance_condition":"","isforcompensation":"false","usertaskassignment":{"assignment":{"type":"idm","idm":{"type":"users","candidateUsers":[{"id":"test","firstName":"test","lastName":null,"email":null,"fullName":"test ","groups":[],"$$hashKey":"object:6687"}]}}},"formkeydefinition":"","formreference":"","duedatedefinition":"","prioritydefinition":"","formproperties":"","tasklisteners":""},"stencil":{"id":"UserTask"},"childShapes":[],"outgoing":[{"resourceId":"sid-CD98690F-4EA7-4F5F-9A04-FC604815AD2B"}],"bounds":{"lowerRight":{"x":332,"y":216},"upperLeft":{"x":232,"y":136}},"dockers":[]},{"resourceId":"sid-5D1AABEF-2AB6-46E9-9AD5-0CD36AD6251C","properties":{"overrideid":"","name":"","documentation":"","executionlisteners":""},"stencil":{"id":"EndNoneEvent"},"childShapes":[],"outgoing":[],"bounds":{"lowerRight":{"x":493,"y":193},"upperLeft":{"x":465,"y":165}},"dockers":[]},{"resourceId":"sid-1007C45C-AB28-4EA8-87C9-0E35B6FFA141","properties":{"overrideid":"","name":"","documentation":"","conditionsequenceflow":"","executionlisteners":"","defaultflow":"false"},"stencil":{"id":"SequenceFlow"},"childShapes":[],"outgoing":[{"resourceId":"sid-584C69B4-A76F-4396-8FE1-1FC77C0385CC"}],"bounds":{"lowerRight":{"x":231.4219467051485,"y":177.8161498108401},"upperLeft":{"x":130.3514907948515,"y":176.6057251891599}},"dockers":[{"x":15,"y":15},{"x":50,"y":40}],"target":{"resourceId":"sid-584C69B4-A76F-4396-8FE1-1FC77C0385CC"}},{"resourceId":"sid-CD98690F-4EA7-4F5F-9A04-FC604815AD2B","properties":{"overrideid":"","name":"","documentation":"","conditionsequenceflow":"","executionlisteners":"","defaultflow":"false"},"stencil":{"id":"SequenceFlow"},"childShapes":[],"outgoing":[{"resourceId":"sid-5D1AABEF-2AB6-46E9-9AD5-0CD36AD6251C"}],"bounds":{"lowerRight":{"x":464.14855343232165,"y":178.7738358390709},"upperLeft":{"x":332.24988406767835,"y":176.7652266609291}},"dockers":[{"x":50,"y":40},{"x":14,"y":14}],"target":{"resourceId":"sid-5D1AABEF-2AB6-46E9-9AD5-0CD36AD6251C"}}],"bounds":{"lowerRight":{"x":1200,"y":1050},"upperLeft":{"x":0,"y":0}},"stencilset":{"url":"stencilsets/bpmn2.0/bpmn2.0.json","namespace":"http://b3mn.org/stencilset/bpmn2.0#"},"ssextensions":[]}

既然数据格式有了,剩下的就是将咱们自定义的流程图数据取出一部分非业务数据转化成Activiti的数据,以保证引擎能正常流转,对应上面的数据咱们抽象出对应的实体类:微信

public class ChartElement {

    /**
     * 资源ID
     */
    private String resourceId = "";
    /**
     * 属性,这是最关键的,每个元素都拥有不一样的属性项,如线对象、用户任务对象、网关对象等等,以继承方式实现便可
     */
    private BaseProperty properties;
    /**
     * 流程环节的activiti类型
     * key为id
     */
    private Map<String, String> stencil = new HashMap<>();
    /**
     * 子组件
     */
    private List<ChartElement> childShapes = new ArrayList<>();
    /**
     * 组件外连的其余组件Id
     */
    private List<Map<String, String>> outgoing = new ArrayList<>();
    /**
     * 组件所在位置。
     */
    private Map<String, Coordinate> bounds = new HashMap<>();
    /**
     * 链接线上的拐点坐标
     */
    private List<Coordinate> dockers = new ArrayList<>();
    /**
     * 链接线的目标组件ID
     */
    private Map<String, String> target = new HashMap<>();

}

在封装时针对不一样的元素对象须要赋予不一样的属性,具体能够参考Activiti-app的保持格式数据结构

这里假设你已经转换好了,已经获得一个完整的流程图对象ChartElement,剩下的步骤就是须要将该对象转换成BpmnModel了,咱们无需手动转换,已经有工具帮咱们实现,可直接使用,首先引入对应依赖:app

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.5</version>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
            <version>6.0.0</version>
        </dependency>

而后使用以下代码便可:async

@Test
    public void transformChartTest() throws Exception {
        // 假设这是你已经转换好后的整个流程图对象
        ChartElement chartElement = new ChartElement();
        // 这里借助jackson库来转换
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = mapper.readTree(mapper.writeValueAsString(chartElement));
        // 而后借助工具将jsonNod转换成BpmnModel
        BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(jsonNode);
        // 最后直接部署便可,注意流程id不能以数字开头
        repositoryService.createDeployment().addBpmnModel("sid-123.bpmn20.xml", bpmnModel).deploy();
    }

针对某些特殊节点,若是须要增长监听器,转换方式与界面保持一致便可,可使用委托表达式来实现,形如:${监听器服务类},该服务类只需交给spring注入便可。

到这里就结束了,能够直接启动流程实例了~网上资料稀叭烂当时找的时候仍是很痛苦的,这边特意分享出来,系列到这一步已经能使用Activiti实现绝大多数功能包括整合本身公司的流程图编辑器。

 

若是该系列对你有帮助的,能够请博主喝杯咖啡嘻嘻嘻

(左支付宝右微信)