一、创建 eclipse maven新项目

1、设置项目选项

其中,Create a simple project 要选中。

2、填写项目包名和项目名称

这里的Group id:必须是 org.flowable (后面的流程配置文件需要用到这个包路径)

二、添加项目maven依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.flowable</groupId>
    <artifactId>HolidayRequest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.flowable</groupId>
            <artifactId>flowable-engine</artifactId>
            <version>6.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.3.176</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>
    </dependencies>
</project>

三、创建Java运行入口

package org.flowable;

public class HolidayRequest {

  public static void main(String[] args) {

  }

}

四、创建流程配置文件

src/main/resources/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="org.flowable.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="org.flowable.SendRejectionMail" />
        <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd" />

        <endEvent id="approveEnd" />

        <endEvent id="rejectEnd" />

    </process>

</definitions>

五、创建log配置文件

src/main/resources/log4j.properties

log4j.rootLogger=DEBUG, CA

log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n

六、创建Java代理类

这个类在前面的流程配置中被设置为id = externalSystemCall 的 serviceTask 的执行类。

package org.flowable;

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"));
    }

}

七、完成代码逻辑

package holidy;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import org.flowable.engine.HistoryService;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Task;

public class HolidayRequest {

    public static void main(String[] args) {

        // 创建流程引擎相关数据库表
        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
                .setJdbcUrl("jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1").setJdbcUsername("sa").setJdbcPassword("")
                .setJdbcDriver("org.h2.Driver")
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

        ProcessEngine processEngine = cfg.buildProcessEngine();

        // 设计好的流程部署到流程引擎中(数据库)
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment = repositoryService.createDeployment().addClasspathResource("holiday-request.bpmn20.xml")
                .deploy();

        // 根据流程ID查找已经部署的流程
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId()).singleResult();
        System.out.println(" 发现定义的流程 : " + processDefinition.getName());

        // 模拟请假流程,输入相关的参数
        Scanner scanner = new Scanner(System.in);

        // 请假人
        System.out.println("你是谁?");
        String employee = scanner.nextLine();

        // 请假天数
        System.out.println("你要请几天假?");
        Integer nrOfHolidays = Integer.valueOf(scanner.nextLine());

        // 请假理由
        System.out.println("请假理由?");
        String description = scanner.nextLine();

        // 流程引擎服务
        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("你有 " + tasks.size() + " 个待办任务:");
        for (int i = 0; i < tasks.size(); i++) {
            System.out.println((i + 1) + ") " + tasks.get(i).getName());
        }

        // 任务选择
        System.out.println("请选择你要处理的任务ID?");
        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") + " 要请 " + processVariables.get("nrOfHolidays")
                + " 天假. 是否同意? 同意回复 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");
        }
    }

}

flowable 6.1.2 命令行完成请假审批流程的例子的更多相关文章

  1. 使用flowable 6.1.2 REST API 运行请假审批流程

    一.下载 flowable rest war 包 http://download.csdn.net/detail/teamlet/9913312 二.部署 复制flowable REST.war到To ...

  2. FS BPM 业余研发(用户详细操作手册--单人串行/并行)之 深圳分公司技术部请假审批流程

    1.FS BPM 简介 BPM软件中BPM是英文字母缩写,大致有二个意思.第一.Business Process Management,即业务流程管理,是一套达成企业各种业 务环节整合的全面管理模式. ...

  3. Wireshark命令行工具tshark详解(含例子)-01

    Wireshark命令行工具tshark使用小记 1.目的 写这篇博客的目的主要是为了方便查阅,使用wireshark可以分析数据包,可以通过编辑过滤表达式来达到对数据的分析:但我的需求是,怎么样把D ...

  4. MySQL命令行下执行.sql脚本详解

    本文主要介绍一个在MySQL命令行下执行脚本文件的例子,通过这个例子让我们来了解一下在命令行下MySQL是怎样执行脚本的吧.现在我们开始介绍这一过程. 1.首先编写sql脚本,保存为的:book.sq ...

  5. Grub命令行

    今天电脑无缘无故无法正常启动,只提示 GRUB> 看来是GRUB引导出问题了,要解决下. 先 想到用制作U盘启动盘来启动,参照网上的方法,很简单用USBBOOT软件做了一个U盘启动盘,按F11在 ...

  6. 《Linux命令行与shell脚本编程大全》第十四章 处理用户输入

    有时还会需要脚本能够与使用者交互.bash shell提供了一些不同的方法来从用户处获得数据, 包括命令行参数,命令行选项,以及直接从键盘读取输入的能力. 14.1 命令行参数 就是添加在命令后的数据 ...

  7. 《Linux命令行与shell脚本编程大全》第二十一章 sed进阶

    本章介绍一些sed编辑器提供的高级特性. 21.1 多行命令 按照之前的知识,所有的sed编辑器命令都是针对单行数据执行操作的. 在sed编辑器读取数据流时,它会基于换行符的位置将数据分成行,一次处理 ...

  8. 【转】winrar命令行详解

    从命令行也可以运行 WinRAR 命令,常规的命令行语法描述如下: WinRAR  <命令> -<开关1> -<开关N> <压缩文件> <文件.. ...

  9. [原] Android自动打包之命令行打包

    Android自动打包流程详细图: 总结为以下几个步骤: 1. 生成R文件 2. Java代码编译成class文件 3. class文件生成dex文件 4. 打包资源 5. 生成apk 6. 创建密匙 ...

随机推荐

  1. pyplot基本绘制

    pyplot实现的功能与Matlab中的绘制方式很相似. 先看一个绘制折线的例子: import matplotlib.pyplot as plt plt.plot([1, 17, 8, 9]) pl ...

  2. nginx灰度环境

    1.nginx.conf split_clients "${remote_addr}AAA" $request_type { 25% "abtest"; * & ...

  3. jupyter常用快捷键

    Jupyter Notebook 有两种键盘输入模式.即命令模式和编辑模式,这与 vim有些类似. 在编辑模式下,可以往单元中键入代码或文本,此时单元格被绿色的框线包围,且命令模式下的快捷键不生效. ...

  4. django联合查询

    假设A表的主键aid作为B表的外键,A表有属性name,那么想查询B表中name为abc的元素就可以这样写: B.objects.all().filter(aid__name = 'abc') __真 ...

  5. Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration info

    Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the ...

  6. Mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

    Mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) Linux: MyS ...

  7. 14.python模块之subprocess

    我们几乎可以在任何操作系统上通过命令行指令与操作系统进行交互,比如Linux平台下的shell.那么我们如何通过Python来完成这些命令行指令的执行呢?另外,我们应该知道的是命令行指令的执行通常有两 ...

  8. [SCOI2005]扫雷Mine

    1088: [SCOI2005]扫雷Mine Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2028  Solved: 1187[Submit][St ...

  9. SpringBoot ControllerAdvice

    在Spring3.2中新增了@ControllerAdvice注解,可用于定义@ExceptionHandler @ModelAttribute @InitBinder,并应用到所有被@Request ...

  10. spring security结合数据库验证用户-注解方式

    项目目录结构如下: 首先数据库的建立和数据导入,以及一些类的依赖参考XML配置方式,需要修改一些配置. 一.在AppConfig文件中添加DataSource的配置 @Bean(name = &quo ...