1.flowable

流程配置

holiday-request.bpmn20.xml

<?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: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"
             xmlns:flowable="http://flowable.org/bpmn"
             typeLanguage="http://www.w3.org/2001/XMLSchema"
             expressionLanguage="http://www.w3.org/1999/XPath"
             targetNamespace="http://www.flowable.org/processdef">

    <process id="holidayRequest" name="请假流程" isExecutable="true">

        <startEvent id="startEvent"/>
        <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>

        <userTask id="approveTask" name="同意或者拒绝请假" flowable:assignee="zhangsan"/>
        <sequenceFlow sourceRef="approveTask" targetRef="decision"/>

        <exclusiveGateway id="decision"/>
        <sequenceFlow sourceRef="decision" targetRef="externalSystemCall">
            <conditionExpression xsi:type="tFormalExpression">
                <![CDATA[
          ${approved}
        ]]>
            </conditionExpression>
        </sequenceFlow>
        <sequenceFlow  sourceRef="decision" targetRef="sendRejectionMail">
            <conditionExpression xsi:type="tFormalExpression">
                <![CDATA[
          ${!approved}
        ]]>
            </conditionExpression>
        </sequenceFlow>

        <serviceTask id="externalSystemCall" name="Enter holidays in external system"
                     flowable:class="org.flowable.CallExternalSystemDelegate"/>
        <sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/>

        <userTask id="holidayApprovedTask" name="Holiday approved"/>
        <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>

        <serviceTask id="sendRejectionMail" name="Send out rejection email"
                     flowable:class="org.flowable.SendRejectionMail"/>
        <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/>

        <endEvent id="approveEnd"/>

        <endEvent id="rejectEnd"/>
    </process>

</definitions>

1. 部署流程

 @Before
    public void before(){
        // 获取  ProcessEngineConfiguration 对象
        configuration = new StandaloneProcessEngineConfiguration();
        // 配置 相关的数据库的连接信息
        configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");
        configuration.setJdbcUsername("root");
        configuration.setJdbcPassword("123456");
        configuration.setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn?serverTimezone=UTC&nullCatalogMeansCurrent=true");
        // 如果数据库中的表结构不存在就新建
        configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
    }
 /**
     * 部署流程
     *
     */
    @Test
    public void testDeploy(){
        // 1.获取 ProcessEngine 对象
        ProcessEngine processEngine = configuration.buildProcessEngine();
        // 2.获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 3.完成流程的部署操作
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("holiday-request.bpmn20.xml")// 关联要部署的流程文件
                .name("请求流程")
                .category("公司流程")
                .deploy() ;// 部署流程
        System.out.println("deploy.getId() = " + deploy.getId());
        System.out.println("deploy.getName() = " + deploy.getName());
    }

flowable 部署工作流,会将往如下表中保存数据:

act_ge_bytearray
在这里插入图片描述
act_re_deployment 流程部署
在这里插入图片描述
act_re_procdef 流程定义
在这里插入图片描述

一个流程定义会产生多个流程实例

2. 查询流程

 /**
     * 查询流程定义的信息
     */
    @Test
    public void testDeployQuery(){
        ProcessEngine processEngine = configuration.buildProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        /*ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        ProcessDefinition processDefinition = processDefinitionQuery.deploymentId("1").singleResult();*/
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId("1")
                .singleResult();
        System.out.println("processDefinition.getDeploymentId() = " + processDefinition.getDeploymentId());
        System.out.println("processDefinition.getName() = " + processDefinition.getName());
        System.out.println("processDefinition.getDescription() = " + processDefinition.getDescription());
        System.out.println("processDefinition.getId() = " + processDefinition.getId());
    }

processDefinition.getDeploymentId() = 1
processDefinition.getName() = 请假流程
processDefinition.getDescription() = null
processDefinition.getId() = holidayRequest:1:3

3. 删除流程定义

  /**
     * 删除流程定义
     */
    @Test
    public void testDeleteDeploy(){
        ProcessEngine processEngine = configuration.buildProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 删除部署的流程 第一个参数是 id  如果部署的流程启动了就不允许删除了
       // repositoryService.deleteDeployment("2501");
        // 第二个参数是级联删除,如果流程启动了 相关的任务一并会被删除掉
         repositoryService.deleteDeployment("1",true);
    }

执行完成后,数据库中以上三张表中数据就被清除了

重新部署工作流以后,数据变为

在这里插入图片描述
在这里插入图片描述
部署id:2501,流程定义:holidayRequest:1:2503 ,流程key:holidayRequest

3. 启动流程实例

 /**
     * 启动流程实例
     */
    @Test
    public void testRunProcess(){
        ProcessEngine processEngine = configuration.buildProcessEngine();

        // 我们需要通过RuntimeService来启动流程实例
        RuntimeService runtimeService = processEngine.getRuntimeService();
        // 构建流程变量
        Map<String,Object> variables = new HashMap<>();
        variables.put("employee","张三");
        variables.put("nrOfHolidays",3);
        variables.put("desciption","工作累了,出去玩玩");
        // 启动流程实例
        ProcessInstance holidayRequest = runtimeService.startProcessInstanceByKey("holidayRequest", variables);
        System.out.println("holidayRequest.getProcessDefinitionId() = " + holidayRequest.getProcessDefinitionId());
        System.out.println("holidayRequest.getActivityId() = " + holidayRequest.getActivityId());
        System.out.println("holidayRequest.getId() = " + holidayRequest.getId());
    }

holidayRequest.getProcessDefinitionId() = holidayRequest:1:2503
holidayRequest.getActivityId() = null
holidayRequest.getId() = 5001

启动流程会在act_ru_execution中生成如下记录:
在这里插入图片描述
相关的人员会放在act_ru_identitylink中
在这里插入图片描述
所产生的任务 存在表act_ru_task中
在这里插入图片描述
流程变量保存在act_ru_variable中
在这里插入图片描述
操作过的历史记录保存于act_hi_actinst
在这里插入图片描述

创建任务实例5001,并产生第一个执行实例,5001,保存到act_ru_execution中
该任务实例中绑定变量 5002,5003,5004,绑定了3个变量
启动的执行实例完成后,自动执行到下一个执行实例 ,操作id是:approveTask 保存在act_ru_execution中,执行实例ID是5005
记录历史操作实例到act_hi_actinst中
一个startEvent,一个approveTask,分别ID为:5006,5007
执行实例5005的又会产生任务,5008,保存到act_ru_task中,该任务是由执行实例5005产生,是属于任务实例5001上的

4.查看交给zhangsan的任务

 /**
     * 测试任务查询
     */
    @Test
    public void testQueryTask(){
        ProcessEngine processEngine = configuration.buildProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("holidayRequest") // 指定查询的流程编程
                .taskAssignee("zhangsan") // 查询这个任务的处理人
                .list();
        for (Task task : list) {
            System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());
            System.out.println("task.getName() = " + task.getName());
            System.out.println("task.getAssignee() = " + task.getAssignee());
            System.out.println("task.getDescription() = " + task.getDescription());
            System.out.println("task.getId() = " + task.getId());
        }
    }
task.getProcessDefinitionId() = holidayRequest:1:2503
task.getName() = 同意或者拒绝请假
task.getAssignee() = zhangsan
task.getDescription() = null
task.getId() = 5008
部署--->流程定义
                    --->流程定义产生任务实例
                                 ----->任务实例产生多个执行实例
                                             ------>每个执行实例产生多个任务

5. 执行任务

在这里插入图片描述
以上我们看到如果approved是false,则会走发送邮件的的task任务

  @Test
    public void testCompleteTask(){
        ProcessEngine processEngine = configuration.buildProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("holidayRequest")
                .taskAssignee("zhangsan")
                .singleResult();
        // 创建流程变量
        Map<String,Object> map = new HashMap<>();
        map.put("approved",false);
        // 完成任务
        taskService.complete(task.getId(),map);

    }

执行后,控制台输出:

不好意思,你的请假申请被拒绝了…安心工作

走到这里,自动任务就结束了,act_run_xxx相关的表会被清空
我们可以查看历史记录act_hi_actinst
在这里插入图片描述

6. 查看历史

    @Test
    public void testHistory(){
        ProcessEngine processEngine = configuration.buildProcessEngine();
        HistoryService historyService = processEngine.getHistoryService();
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
                .processDefinitionId("holidayRequest:1:2503")
                .finished() // 查询的历史记录的状态是已经完成
                .orderByHistoricActivityInstanceEndTime().asc() // 指定排序的字段和顺序
                .list();
        for (HistoricActivityInstance history : list) {

            System.out.println("流程实例:"+ history.getProcessInstanceId()+"--"+history.getActivityName()+":"+history.getAssignee()+"--"
                    +history.getActivityId()+":" + history.getDurationInMillis()+"毫秒");
        }

    }

流程实例:5001–null:null–startEvent:3毫秒
流程实例:5001–同意或者拒绝请假:zhangsan–approveTask:2891400毫秒
流程实例:5001–null:null–decision:20毫秒
流程实例:5001–Send out rejection email:null–sendRejectionMail:2毫秒
流程实例:5001–null:null–rejectEnd:1毫秒

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值