• 基于springboot的flowable工作流实例实现


    基于springboot的flowable工作流实例实现

    flowableUI 创建实例教程 https://www.cnblogs.com/nanstar/p/11959389.html

    Flowable 中文官网 https://tkjohn.github.io/flowable-userguide/#_deploying_a_process_definition
    1、首先创建一空白的个springboot的项目

    2、这里是编辑项目名称,我这里写的是flowabledemo

    3、这个位置是选择配置的,因为是demo所以我没有选择任何配置

    4、这里输入的是输出文件夹的名称,我选择了和项目文件名一致


    5、创建完成之后打开项目:

    在pomx里添加flowable和mysql依赖(生成数据库要用到),我选择的是MySQL数据库,因为我电脑上有现成的mysql

    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-engine</artifactId>
        <version>6.5.0-SNAPSHOT</version>
      </dependency>
     <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.45</version>
     </dependency>
    
    6、这时候他会自动下载相应的文件,等待事件有点长,我们可以去新加一个数据库,已备后用。

    新建flowable数据库(数据库名字自己设定)

    7、然后在主函数入口部分添加数据库信息(用来自动生成所需要的表,原来的那句话需要注释或删除掉)
    //        SpringApplication.run(FlowabledemoApplication.class, args);
    ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
            .setJdbcUrl("jdbc:mysql://localhost:3306/flowable")
            .setJdbcUsername("root")
            .setJdbcPassword("123456")
            .setJdbcDriver("com.mysql.jdbc.Driver")
            .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
    ProcessEngine processEngine = cfg.buildProcessEngine();
    

    8、接着右键运行,生成数据库表信息。然后会在控制台输出很长的内容,等到输出停止,去数据库查看,会发现flowable数据库中新建了很多表,这样操作就可以继续了。

    在运行实例的时候,关于数据库新建的这部分代码是不需要注释掉的(若数据库有更新的化会自动更新数据库内容)。


    9、接着书写一个关于请假的实例:

    我们需要再resource文件夹里新加配置文件 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="Holiday Request" isExecutable="true">
            <startEvent id="startEvent"/>
            <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>
            <userTask id="approveTask" name="Approve or reject request" flowable:candidateGroups="managers"/>
            <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="com.flowable.flowabledemo.CallExternalSystemDelegate"/>
            <sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/>
            <userTask id="holidayApprovedTask" name="Holiday approved" flowable:assignee="${employee}"/>
            <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>
            <serviceTask id="sendRejectionMail" name="Send out rejection email"
                         flowable:class="com.flowable.flowabledemo.SendRejectionMail"/>
    <!--这里的class需要注意,后边跟的路径是你项目类问价所在的相对位置,若运行的时候报错,需要来修改这里的位置代码-->
            <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/>
            <endEvent id="approveEnd"/>
            <endEvent id="rejectEnd"/>
        </process>
    </definitions>
    
    10、接着在入口函数(main)下追加以下内容
    /**
     * 部署工作流文件到流程引擎,其实就是将xml文件解析成Java对象,从而可以在程序里使用.
     */
    RepositoryService repositoryService = processEngine.getRepositoryService();
    Deployment deployment = repositoryService.createDeployment()
            .addClasspathResource("holiday-request.bpmn20.xml")
            .deploy();
    /**
     * API使用
     */
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
            .deploymentId(deployment.getId())
            .singleResult();
    System.out.println("Found process definition : " + processDefinition.getName());
    /**
     * 初始化流程变量
     */
    Scanner scanner= new Scanner(System.in);
    System.out.println("Who are you?");
    String employee = scanner.nextLine();
    System.out.println("How many holidays do you want to request?");
    Integer nrOfHolidays = Integer.valueOf(scanner.nextLine());
    System.out.println("Why do you need them?");
    String description = scanner.nextLine();
    /**
     * 通过RuntimeService启动一个流程实例,简称“启动流程”,这里就是启动请假流程
     */
    RuntimeService runtimeService = processEngine.getRuntimeService();
    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("employee", employee);
    variables.put("nrOfHolidays", nrOfHolidays);
    variables.put("description", description);
    ProcessInstance processInstance =
            runtimeService.startProcessInstanceByKey("holidayRequest", variables);
    /**
     * 查询某个用户的任务
     */
    TaskService taskService = processEngine.getTaskService();
    List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list();
    System.out.println("You have " + tasks.size() + " tasks:");
    for (int i=0; i<tasks.size(); i++) {
        System.out.println((i+1) + ") " + tasks.get(i).getName() + " created by [" + taskService.getVariables(tasks.get(i).getId()).get("employee") + "]");
    }
    /**
     * 根据任务获取到这个任务涉及的流程变量
     */
    System.out.println("Which task would you like to complete?");
    int taskIndex = Integer.valueOf(scanner.nextLine());
    Task task = tasks.get(taskIndex - 1);
    Map<String, Object> processVariables = taskService.getVariables(task.getId());
    System.out.println(processVariables.get("employee") + " wants " +
            processVariables.get("nrOfHolidays") + " of holidays. Do you approve this?");
    
    /**
     * 如果是y,则流程结束
     */
    boolean approved = scanner.nextLine().toLowerCase().equals("y");
    variables = new HashMap<String, Object>();
    variables.put("approved", approved);
    taskService.complete(task.getId(), variables);
    
    /**
     * 查询历史数据,每个步骤的花费的时间
     */
    HistoryService historyService = processEngine.getHistoryService();
    List<HistoricActivityInstance> activities =
            historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(processInstance.getId())
                    .finished()
                    .orderByHistoricActivityInstanceEndTime().asc()
                    .list();
    
    for (HistoricActivityInstance activity : activities) {
        System.out.println(activity.getActivityId() + " took "
                + activity.getDurationInMillis() + " milliseconds");
    }
    
    11、接着需要在主函数的同级目录下新建一个类文件 CallExternalSystemDelegate 内容是:
    package com.flowable.flowabledemo;
    import org.flowable.engine.delegate.DelegateExecution;
    import org.flowable.engine.delegate.JavaDelegate;
    
    public class CallExternalSystemDelegate implements JavaDelegate {
        public void execute(DelegateExecution execution) {
            System.out.println("Calling the external system for employee "
                    + execution.getVariable("employee"));
        }
    }
    
    目录层级展示

    13、运行截图:

    这时候是员工身份进行操作。
    依次输入:姓名 请假时长 请假理由

    14、敲击回车,这时候会进入到管理者的角色,会让你选择处理哪一个请假事务,显示的是有16个任务,向上滚动可以查看具体的内容的编号,我们刚才新建的任务编号是14,所以这里输入14,敲击回车继续

    15、这时候会列出请假者的名字,请假时长,需要你输入y来同意这个请假请求。

    16、然后敲击回车,程序完成,并输出相关信息。

    于是,一个简单的flowable工作流实例就算是完成了!

    点击下载源文件
    点我 Touch Me

  • 相关阅读:
    Ant Design Vue中TreeSelect详解
    ant-design-vue 表单验证详解
    vue3跟新视图遇见神奇现象
    遇见这样的数型结构图我是这样画的
    Ant Design Vue中Table的选中详解
    2021 年百度之星·程序设计大赛
    2021 年百度之星·程序设计大赛
    2021牛客暑期多校训练营7 H. xay loves count(枚举)
    2021牛客暑期多校训练营6 H. Hopping Rabbit(扫描线)
    P1494 [国家集训队]小Z的袜子(莫队)
  • 原文地址:https://www.cnblogs.com/nanstar/p/11935133.html
Copyright © 2020-2023  润新知