您的位置:首页 > 其它

Flowable工作流

2020-07-21 04:15 2171 查看

Flowable工作流

Flowable工作流

  • 二.flowable实例
  • 三.flowable数据库表的介绍
  • 四.flowable中的五个引擎
  • 一.认识flowable

    Flowable是一个使用Java编写的轻量级业务流程引擎。Flowable流程引擎让你可以部署BPMN 2.0流程定义(用于定义流程的行业XML标准)、创建这些流程定义的流程实例、进行查询、访问运行中或历史的流程实例与相关数据,等等。

    1.flowable发展史

    三个框架诞生的先后顺序是 JBPM>Activiti>Flowable
    2010年,JBPM4发布之后, Joram Barrez(JBPM的创始人)与合作伙伴在JBPM的未来架构上产生了重大的分歧,于是乎Tom Baeyens离开了JBoss公司并加入到Alfresco公司,真是一言不合就“分手”。
    2010年6月18日,Alfresco公司发布了第一个Activiti版本(5.0.alpha1)。Activiti直接将第一个版本号定义为5.0可谓意味深远,表明Activiti框架才是JBPM4的延续。从上面的图可以看出来,activiti从12年底的时候,才开始大量的重构和开发。
    2010年10月6日,JBoss完全抛弃了JBPM4的架构设计,使用了规则引擎(Drools Flow)进行项目的彻底重构,并推出了JBPM5。
    2016年10月13日,Tijs Rademarkers (原Activiti Project Lead)发布了Flowable 5.22.0版本的上线公告,该版本基于上Activiti5.22版本拉取的新分支,并没有从本质上增加更多的新特性。
    2016年11月1日,Flowable团队开放了Flowable Eclipse Designer(该插件用于在Eclipse开发工具中绘制流程文档)。
    2016年12月15日,Flowable团队发布了Flowable 6.0.0.RC1版本的上线公告。
    2017年3月27日,Flowable团队发布了Flowable 5.23.0版本的上线公告。
    2017年4月28日,Flowable团队发布了Flowable 6.0.1版本的上线公告。
    2017年5月29日,大名鼎鼎的Joram Barrez(原JBPM的创始人)加入了Flowable团队,专心于Flowable的研发。
    2017年7月21日,Flowable团队发布了Flowable 6.1.1版本的上线公告。
    2017年10月13日,Flowable团队发布了flowable-6.2.0-release版本的上线公告。
    2017年12月11日,Flowable团队发布了flowable-6.2.1-release版本的上线公告。
    2018年04月04日,Flowable团队发布了flowable-6.3.0-release版本的上线公告。
    2018年05月22日,Flowable团队发布了flowable-6.3.1-release版本的上线公告。
    2018年10月02日,Flowable团队发布了flowable-6.4.0-release版本的上线公告。

    官网:https://www.flowable.org/

    中文文档:https://tkjohn.github.io/flowable-userguide/#_configuration

    2.BPMN


    BPMN 标准发展版本历史如下。BPMN2.0在1.x基础上新增了元模型、存储、交互、执行。

    BPMN2.0概述:

    1、是一套业务流程模型与符号建模标准;

    2、精准的执行语义来描述元素的操作,可以将元素的操作描述的很清楚,没有二义性;

    3、以XML为载体,以符号可视化业务,每个xml模块都可以对应符号,流程图与xml有一个相互转换的过程。

    BPMN2.0所包含的元素:

    1、流对象(FlowObjects):包括其中的活动、事件与网关。

    活动(Activities)  [User Task 、Service Task ......]
    
    事件(Events)  [Start Event、End Event......]
    
    网关(Gateways)  [Exclusive Gateway ......]

    2、连接对象(ConnectingObject):流对象通过连接对象连接起来表示数据的流转;

    3、数据(Data):包括一些数据对象、数据输入\输出对象等。

    数据对象(Data Objects)
    
    数据输入(Data Inputs )
    
    数据输出(Data OutPuts)
    
    数据存储(Data Stores)

    4、泳道(Swimlanes):对业务做范围维度的区分,一般通过不同的职能进行区分。

    ​ 池(Pools ): 池描述流程中的一个参与者。可以看做是将一系列活动区别于其他池的一个图形容器

    ​ 道(Lanes ):道就是在池里面再细分,可以是垂直的也可以是水平的。道也是用于组织和分类活动。

    5、描述对象(Artifacts):不影响流程运行,为流程图可读性进行补充性描述。

    一个简单的流程图

    二.flowable实例

    项目结构如下:

    1.导入依赖

    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
    <relativePath />
    </parent>
    <dependencies>
    <!--flowable-->
    <dependency>
    <groupId>org.flowable</groupId>
    <artifactId>flowable-spring-boot-starter</artifactId>
    <version>6.4.0</version>
    </dependency>
    <!--数据库-->
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.45</version>
    </dependency>
    <!--rest支持-->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    </dependencies>

    2.编写启动类

    @SpringBootApplication
    public class RepairApp {
    /**
    *日志信息
    */
    private static final Logger log = LoggerFactory.getLogger(RepairApp.class);
    
    public static void main(String[] args) {
    log.info("项目开始启动");
    SpringApplication.run(RepairApp.class,args);
    log.info("项目启动完成");
    }
    }

    3.配置文件

    #数据源配置
    spring:
    datasource:
    url: jdbc:mysql://106.13.61.208/repair?characterEncoding=UTF-8
    username: root
    password: 123456
    
    #flowable配置
    #自动部署验证设置:true-开启(默认)、false-关闭
    flowable:
    check-process-definitions: false

    4.导入BPMN文件

    <?xml version="1.0" encoding="UTF-8"?>
    <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
    <process id="mydemo" name="demo" isExecutable="true">
    <documentation>111</documentation>
    <startEvent id="startEvent1"></startEvent>
    <userTask id="sid-7C91C99C-1D01-4AC6-88FB-03CAA1603477" name="出差报销" flowable:assignee="${user}">
    <extensionElements>
    <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
    </extensionElements>
    </userTask>
    <exclusiveGateway id="sid-49E6AEBB-D5B9-4B9E-A99E-2E2454642891"></exclusiveGateway>
    <sequenceFlow id="sid-5B89E7D6-7B3A-439A-9F15-D3B985515C7E" sourceRef="sid-7C91C99C-1D01-4AC6-88FB-03CAA1603477" targetRef="sid-49E6AEBB-D5B9-4B9E-A99E-2E2454642891"></sequenceFlow>
    <userTask id="sid-457C6876-FE69-47E8-B9B1-5F1AEC979758" name="经理审批" flowable:assignee="manage">
    <extensionElements>
    <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
    </extensionElements>
    </userTask>
    <userTask id="sid-05C7AEC3-C967-4056-9AAA-B21C57E214F4" name="老板审批" flowable:assignee="boss">
    <extensionElements>
    <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
    </extensionElements>
    </userTask>
    <endEvent id="sid-27C7BF58-F8CF-4B3A-868C-F2158DF03AD8"></endEvent>
    <sequenceFlow id="sid-1A2DAF03-7BA0-4531-A02D-09F6AF31C33B" sourceRef="startEvent1" targetRef="sid-7C91C99C-1D01-4AC6-88FB-03CAA1603477"></sequenceFlow>
    <sequenceFlow id="sid-C2FEB1B6-B383-41AF-BBA8-CC9CCB4FD2FA" name="驳回" sourceRef="sid-457C6876-FE69-47E8-B9B1-5F1AEC979758" targetRef="sid-7C91C99C-1D01-4AC6-88FB-03CAA1603477">
    <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=="驳回"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-5D877DFD-FD4F-4686-AD25-162AF7265D28" name="驳回" sourceRef="sid-05C7AEC3-C967-4056-9AAA-B21C57E214F4" targetRef="sid-7C91C99C-1D01-4AC6-88FB-03CAA1603477">
    <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=="驳回"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-A4FA12EE-2B6E-40E1-8324-7C3D08C59D19" name="money&lt;=500" sourceRef="sid-49E6AEBB-D5B9-4B9E-A99E-2E2454642891" targetRef="sid-457C6876-FE69-47E8-B9B1-5F1AEC979758">
    <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money<=500}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-0EFF9C10-9F5B-45C8-B0D5-DF9C6FA3466C" name="通过" sourceRef="sid-05C7AEC3-C967-4056-9AAA-B21C57E214F4" targetRef="sid-27C7BF58-F8CF-4B3A-868C-F2158DF03AD8">
    <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=="通过"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-73F869E4-1EEF-4218-B568-E431EC21D1DA" name="通过" sourceRef="sid-457C6876-FE69-47E8-B9B1-5F1AEC979758" targetRef="sid-27C7BF58-F8CF-4B3A-868C-F2158DF03AD8">
    <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=="通过"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-218819A2-D9B3-4EAC-858D-A1F12D9DDBFF" name="money&gt;500" sourceRef="sid-49E6AEBB-D5B9-4B9E-A99E-2E2454642891" targetRef="sid-05C7AEC3-C967-4056-9AAA-B21C57E214F4">
    <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money>500}]]></conditionExpression>
    </sequenceFlow>
    </process>
    <bpmndi:BPMNDiagram id="BPMNDiagram_mydemo">
    <bpmndi:BPMNPlane bpmnElement="mydemo" id="BPMNPlane_mydemo">
    <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
    <omgdc:Bounds height="30.0" width="30.0" x="60.0" y="199.0"></omgdc:Bounds>
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape bpmnElement="sid-7C91C99C-1D01-4AC6-88FB-03CAA1603477" id="BPMNShape_sid-7C91C99C-1D01-4AC6-88FB-03CAA1603477">
    <omgdc:Bounds height="80.0" width="100.0" x="158.0" y="174.0"></omgdc:Bounds>
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape bpmnElement="sid-49E6AEBB-D5B9-4B9E-A99E-2E2454642891" id="BPMNShape_sid-49E6AEBB-D5B9-4B9E-A99E-2E2454642891">
    <omgdc:Bounds height="40.0" width="40.0" x="303.0" y="194.0"></omgdc:Bounds>
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape bpmnElement="sid-457C6876-FE69-47E8-B9B1-5F1AEC979758" id="BPMNShape_sid-457C6876-FE69-47E8-B9B1-5F1AEC979758">
    <omgdc:Bounds height="80.0" width="100.0" x="405.0" y="174.0"></omgdc:Bounds>
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape bpmnElement="sid-05C7AEC3-C967-4056-9AAA-B21C57E214F4" id="BPMNShape_sid-05C7AEC3-C967-4056-9AAA-B21C57E214F4">
    <omgdc:Bounds height="80.0" width="100.0" x="273.0" y="295.0"></omgdc:Bounds>
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape bpmnElement="sid-27C7BF58-F8CF-4B3A-868C-F2158DF03AD8" id="BPMNShape_sid-27C7BF58-F8CF-4B3A-868C-F2158DF03AD8">
    <omgdc:Bounds height="28.0" width="28.0" x="441.0" y="321.0"></omgdc:Bounds>
    </bpmndi:BPMNShape>
    <bpmndi:BPMNEdge bpmnElement="sid-5B89E7D6-7B3A-439A-9F15-D3B985515C7E" id="BPMNEdge_sid-5B89E7D6-7B3A-439A-9F15-D3B985515C7E">
    <omgdi:waypoint x="257.9499999999977" y="214.21623376623376"></omgdi:waypoint>
    <omgdi:waypoint x="303.4130434782609" y="214.4130434782609"></omgdi:waypoint>
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNEdge bpmnElement="sid-C2FEB1B6-B383-41AF-BBA8-CC9CCB4FD2FA" id="BPMNEdge_sid-C2FEB1B6-B383-41AF-BBA8-CC9CCB4FD2FA">
    <omgdi:waypoint x="455.0" y="174.0"></omgdi:waypoint>
    <omgdi:waypoint x="455.0" y="135.0"></omgdi:waypoint>
    <omgdi:waypoint x="204.20703124999994" y="135.0"></omgdi:waypoint>
    <omgdi:waypoint x="204.20703124999994" y="174.0"></omgdi:waypoint>
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNEdge bpmnElement="sid-0EFF9C10-9F5B-45C8-B0D5-DF9C6FA3466C" id="BPMNEdge_sid-0EFF9C10-9F5B-45C8-B0D5-DF9C6FA3466C">
    <omgdi:waypoint x="372.95000000000005" y="335.0"></omgdi:waypoint>
    <omgdi:waypoint x="441.0" y="335.0"></omgdi:waypoint>
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNEdge bpmnElement="sid-A4FA12EE-2B6E-40E1-8324-7C3D08C59D19" id="BPMNEdge_sid-A4FA12EE-2B6E-40E1-8324-7C3D08C59D19">
    <omgdi:waypoint x="342.51504576659045" y="214.42748091603053"></omgdi:waypoint>
    <omgdi:waypoint x="404.99999999999324" y="214.18992395437263"></omgdi:waypoint>
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNEdge bpmnElement="sid-1A2DAF03-7BA0-4531-A02D-09F6AF31C33B" id="BPMNEdge_sid-1A2DAF03-7BA0-4531-A02D-09F6AF31C33B">
    <omgdi:waypoint x="89.94999896690354" y="214.0"></omgdi:waypoint>
    <omgdi:waypoint x="157.99999999997266" y="214.0"></omgdi:waypoint>
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNEdge bpmnElement="sid-5D877DFD-FD4F-4686-AD25-162AF7265D28" id="BPMNEdge_sid-5D877DFD-FD4F-4686-AD25-162AF7265D28">
    <omgdi:waypoint x="273.0" y="335.0"></omgdi:waypoint>
    <omgdi:waypoint x="208.0" y="335.0"></omgdi:waypoint>
    <omgdi:waypoint x="208.0" y="253.95000000000002"></omgdi:waypoint>
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNEdge bpmnElement="sid-218819A2-D9B3-4EAC-858D-A1F12D9DDBFF" id="BPMNEdge_sid-218819A2-D9B3-4EAC-858D-A1F12D9DDBFF">
    <omgdi:waypoint x="323.42083333333335" y="233.52100333055787"></omgdi:waypoint>
    <omgdi:waypoint x="323.1657676348548" y="295.0"></omgdi:waypoint>
    </bpmndi:BPMNEdge>
    <bpmndi:BPMNEdge bpmnElement="sid-73F869E4-1EEF-4218-B568-E431EC21D1DA" id="BPMNEdge_sid-73F869E4-1EEF-4218-B568-E431EC21D1DA">
    <omgdi:waypoint x="455.0" y="253.95000000000002"></omgdi:waypoint>
    <omgdi:waypoint x="455.0" y="321.0"></omgdi:waypoint>
    </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
    </bpmndi:BPMNDiagram>
    </definitions>

    5.部署流程
    service层

    /**
    * 部署流程
    * filePath 文件路径 name 流程名字
    */
    public Map<String, Object> deploymentFlow(String filePath, String name) {
    try {
    DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
    .addClasspathResource(filePath).name(name);
    Deployment deployment = deploymentBuilder.deploy();
    logger.info("成功:部署工作流程:" + filePath);
    logger.error("deployment.getKey():" + deployment.getKey());
    logger.error("deployment.getName():" + deployment.getName());
    //acr_re_deployment表的id
    String id = deployment.getId();
    
    ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
    //搜索条件deploymentId
    query.deploymentId(id);
    //最新版本过滤
    query.latestVersion();
    //查询
    ProcessDefinition definition = query.singleResult();
    //act_re_procdef表的key
    String key = definition.getKey();
    System.out.println("act_re_procdef表的key" + key);
    String id1 = definition.getId();
    System.out.println("流程定义id1:::" + id1);
    
    Map<String, Object> map = new HashMap<>();
    map.put("act_re_procdef表的key", key);
    map.put("act_re_procdef表的id", id1);
    return map;
    } catch (Exception e) {
    logger.error("失败:部署工作流:" + e);
    return null;
    }
    }

    controller层:

    /**
    * 部署流程
    * */
    @RequestMapping("/deploy")
    public Map<String,Object> deploymentFlow(String filePath, String name){
    return flowableService.deploymentFlow(filePath,name);
    }

    测试:http://127.0.0.1:8080/deploy?filePath=processes/demo.bpmn20.xml

    6.启动流程
    service层:

    /**
    * 开始流程
    */
    public ProcessInstance startProcessInstance(String processKey, Map map) {
    // 定义流程的key
    // String processDefinitionKey = processKey;
    if (StringUtils.isEmpty(processKey)) {
    return null;
    }
    ProcessInstance pi = runtimeService.startProcessInstanceByKey(processKey, map);
    
    System.out.println("processInstanceId流程实例ID:" + pi.getId());
    System.out.println("ProcessDefinitionId流程定义ID:" + pi.getProcessDefinitionId());
    return pi;
    }

    controller层:

    /**
    * 启动流程
    * */
    @RequestMapping("/start")
    public Map<String, Object> startProcessInstance(String processKey, String userId){
    Map<String, Object> map = new HashMap<>();
    map.put("user",userId);
    ProcessInstance pi = flowableService.startProcessInstance(processKey, map);
    Map<String, Object> pra = new HashMap<>();
    pra.put("流程实例ID", pi.getId());
    pra.put("流程定义ID:", pi.getProcessDefinitionId());
    return pra;
    }

    测试:http://127.0.0.1:8080/start?processKey=mydemo&userId=123


    7.查看待办任务
    service层:

    /**
    * 查询代理人任务
    */
    public List<Task> queryAssigneeTask(String assignee) {
    List<Task> tasks = taskService.createTaskQuery().taskAssignee(assignee).list();
    return tasks;
    }

    controler层:

    /**
    * 查询代理人任务
    * */
    @RequestMapping("/queryTask")
    public Map<String, Object> queryAssigneeTask(String assignee){
    List<Task> tasks=flowableService.queryAssigneeTask(assignee);
    Map<String, Object> map = new HashMap<>();
    int i = 1 ;
    for (Task task : tasks) {
    map.put("task"+i,task.toString());
    i++;
    }
    return map;
    }

    测试:http://127.0.0.1:8080/queryTask?assignee=123


    id:待办理的任务节点id

    name:待办理的任务的描述

    8.出差报销
    service层:

    /**
    * 完成任务
    */
    public boolean completeTask(String taskId, Map<String, Object> paras) {
    
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    if (task == null) {
    logger.error("task:" + task);
    return false;
    }
    
    if (null == paras) {
    taskService.complete(taskId);
    } else {
    taskService.complete(taskId, paras);
    }
    
    return true;
    }

    controller层:

    /**
    * 出差报销
    */
    @RequestMapping("reimburse")
    public String reimburse(String taskId, Integer money) {
    Map<String, Object> map = new HashMap<>();
    map.put("money", money);
    try {
    flowableService.completeTask(taskId, map);
    } catch (Exception e) {
    e.printStackTrace();
    return "系统异常";
    }
    return "申请报销";
    }

    测试:http://127.0.0.1:8080/reimburse?taskId=5af07084-ccbe-11e9-80cb-1ae3475a33dc&money=600

    9.审核通过
    service层:同上

    /**
    * 完成任务
    */
    public boolean completeTask(String taskId, Map<String, Object> paras) {
    
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    if (task == null) {
    logger.error("task:" + task);
    return false;
    }
    
    if (null == paras) {
    taskService.complete(taskId);
    } else {
    taskService.complete(taskId, paras);
    }
    
    return true;
    }

    controller层

    /**
    * 审核通过
    * */
    @RequestMapping("/pass")
    public String pass(String taskId){
    Map<String, Object> map = new HashMap<>();
    map.put("outcome", "通过");
    try {
    flowableService.completeTask(taskId, map);
    }catch (Exception e){
    e.printStackTrace();
    return "系统异常";
    }
    return "审核通过";
    }

    测试:http://127.0.0.1:8080/pass?taskId=90a3e272-ccbf-11e9-823f-1ae3475a33dc

    10.查看流程图
    service层:

    /**
    * 查看流程是否完成
    */
    public boolean isFinished(String processInstanceId) {
    return historyService.createHistoricProcessInstanceQuery().finished()
    .processInstanceId(processInstanceId).count() > 0;
    }
    
    /**
    * 查看流程图
    */
    public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) {
    /**
    * 获得当前活动的节点
    */
    String processDefinitionId = "";
    if (this.isFinished(processId)) {
    // 如果流程已经结束,则得到结束节点
    HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();
    
    processDefinitionId = pi.getProcessDefinitionId();
    } else {
    // 如果流程没有结束,则取当前活动节点
    // 根据流程实例ID获得当前处于活动状态的ActivityId合集
    ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
    processDefinitionId = pi.getProcessDefinitionId();
    }
    List<String> highLightedActivitis = new ArrayList<String>();
    
    /**
    * 获得活动的节点
    */
    List<HistoricActivityInstance> highLightedActivitList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list();
    
    for (HistoricActivityInstance tempActivity : highLightedActivitList) {
    String activityId = tempActivity.getActivityId();
    highLightedActivitis.add(activityId);
    }
    
    List<String> flows = new ArrayList<>();
    
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    //获取流程图
    BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
    ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
    
    ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
    InputStream in = diagramGenerator.generateDiagram(bpmnModel, "bmp", highLightedActivitis, flows, engconf.getActivityFontName(),
    engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, true);
    OutputStream out = null;
    byte[] buf = new byte[1024];
    int legth = 0;
    try {
    out = httpServletResponse.getOutputStream();
    while ((legth = in.read(buf)) != -1) {
    out.write(buf, 0, legth);
    }
    } catch (IOException e) {
    logger.error("操作异常", e);
    } finally {
    try {
    if (out != null) {
    out.close();
    }
    if (in != null) {
    in.close();
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

    controller层:

    /**
    * 查看流程图
    */
    @RequestMapping("/processDiagram")
    public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) throws Exception {
    flowableService.genProcessDiagram(httpServletResponse, processId);
    }

    测试:http://127.0.0.1:8080/processDiagram?processId=5ae6fa9f-ccbe-11e9-80cb-1ae3475a33dc

    问题:流程图中中文有乱码

    解决:添加配置类

    @Configuration
    public class Config implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration>{
    @Override
    public void configure(SpringProcessEngineConfiguration engineConfiguration) {
    engineConfiguration.setActivityFontName("宋体");
    engineConfiguration.setLabelFontName("宋体");
    engineConfiguration.setAnnotationFontName("宋体");
    }
    }

    重启项目,再次访问
    乱码问题解决!!!

    三.flowable数据库表的介绍

    在项目启动时,会在数据库新建66张表(版本不同,表的数量可能不同)

    1.对表分类

    清单:

    通用数据表

    流程定义存储表

    身份数据表

    运行时流程数据表

    历史流程数据表

    2.流程启动到结束数据库变化

    ​ 部署完毕后,act_re_deployment表中会有一条部署记录,记录这次部署的基本信息,然后是act_ge_bytearray表中有两条记录,记录的是本次上传的bpmn文件和对应的图片文件,每条记录都有act_re_deployment表的外键关联,然后是act_re_procdef表中有一条记录,记录的是该bpmn文件包含的基本信息,包含act_re_deployment表外键。

    流程启动,首先向act_ru_execution表中插入一条记录,记录的是这个流程定义的执行实例,其中id和proc_inst_id相同都是流程执行实例id,也就是本次执行这个流程定义的id,包含流程定义的id外键。

    然后向act_ru_task插入一条记录,记录的是第一个任务的信息,也就是开始执行第一个任务。包括act_ru_execution表中的execution_id外键和proc_inst_id外键,也就是本次执行实例id。

    然后向act_hi_procinst表和act_hi_taskinst表中各插入一条记录,记录的是本次执行实例和任务的历史记录:

    任务提交后,首先向act_ru_variable表中插入变量信息,包含本次流程执行实例的两个id外键,但不包括任务的id,因为setVariable方法设置的是全局变量,也就是整个流程都会有效的变量:

    当流程中的一个节点任务完成后,进入下一个节点任务,act_ru_task表中这个节点任务的记录被删除,插入新的节点任务的记录。

    同时act_ru_execution表中的记录并没有删除,而是将正在执行的任务变成新的节点任务。

    同时向act_hi_var_inst和act_hi_taskinst插入历史记录。

    整个流程执行完毕,act_ru_task,act_ru_execution和act_ru_variable表相关记录全被清空。

    全程有一个表一直在记录所有动作,就是act_hi_actinst表:

    以上就是flowable流程启动到结束的所有流程的变化。

    四.flowable中的五个引擎

    • 内容引擎 ContentEngine
    • 身份识别引擎 IdmEngine
    • 表单引擎 FormEngine
    • 决策引擎DmnEngine
    • 流程引擎 ProcessEngine

    1.流程引擎 ProcessEngine
    1.1 **RepositoryService

    管理流程定义

    1.2 **RuntimeService

    执行管理,包括启动、推进、删除流程实例等操作

    1.3 **TaskService

    任务管理

    1.4 **HistoryService

    历史管理(执行完的数据的管理)

    1.5 IdentityService

    组织机构管理

    1.6 FormService

    一个可选服务,任务表单管理

    1.7 ManagerService

    获取引擎所在的数据库中存在的表、获取表的元数据信息、创建删除等作业、执行命令类、执行自定义SQL、操作事件日志。

    1.8 DynamicBpmnService

    动态修改Bpmn流程定义以及部署库等操作。

    2.内容引擎ContentEngine

    2.1 内容引擎包含的服务有:ContentService和ContentManagementService。

    2.2 ContentManagementService提供对数据库表的管理操作。

    Map<String, Long> getTableCount(); 获取每个表的记录数量;
    String getTableName(Class<?> flowableEntityClass);根据实体类获得对应的数据库表名
    TableMetaData getTableMetaData(String tableName);根据实体类获得对应的数据库表名
    TablePageQuery createTablePageQuery();创建一个可以进行排序、根据条件分页的查询类
    3.身份识别引擎 IdmEngine

    身份识别引擎包含的服务有:IdmIdentityService、IdmManagementService、IdmEngineConfiguration。

    3.1 IdmIdentityService

    • 提供用户的创建、修改、删除、密码修改、登录、用户头像设置等;
    • 提供组Group的创建、删除、用户与组关系的关联、删除关联;
    • 提供权限的创建、删除、关联等.

    3.2 IdmManagementService

    对身份识别相关的数据库表进行统计、获取表的列信息。

    3.3 IdmEngineConfiguration

    提供数据库配置信息。

    4.表单引擎 FormEngine

    4.1 FormManagementService

    提供对数据库表的管理操作。

    4.2 FormRepositoryService

    表单资源服务。

    4.3 FormService

    提供表单实例的增删改查操作服务。

    5.决策引擎DmnEngine

    5.1 DmnManagementService

    该类主要用于获取一系列的数据表元数据信息。

    5.2 DmnRepositoryService

    动态部署流程资源。

    5.3 DmnRuleService

    按照规则启动流程实例。

    5.4 DmnHistoryService

    提供对决策执行历史的访问的服务。

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: