工做流引擎activiti

一。activiti简介html

      Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准,包括支持对象管理组(OMG),面对新技术的机遇,诸如互操做性和云架构,提供技术实现。
       创始人Tom Baeyens是JBoss jBPM的项目架构师,以及另外一位架构师Joram Barrez,一块儿加入到建立Alfresco这项首次实现Apache开源许可的BPMN 2.0引擎开发中来。
web

       Activiti是一个独立运做和经营的开源项目品牌,并将独立于Alfresco开源ECM系统运行。 Activiti将是一种轻量级,可嵌入的BPM引擎,并且还设计适用于可扩展的云架构。 Activiti将提供宽松的Apache许可2.0,以便这个项目能够普遍被使用,同时促进Activiti BPM引擎和BPMN 2.0的匹配,该项目现正由OMG经过标准审定。 加入Alfresco Activiti项目的是VMware的SpringSource分支,Alfresco的计划把该项目提交给Apache基础架构,但愿吸引更多方面的BPM专家和促进BPM的创新。spring

    Activiti框架用于定义业务逻辑相关的流程 ,开启相关流程实例,流程变量控制流程走向,用户及组完成流程任务
数据库

Activiti流程定义使用bpmn2.0标准 该标准经过xml定义了全部业务流程相关的节点 好比 开始 结束 用户任务 排他路由 并行路由等 因为编写xml比较困难 activiti提供了eclipse相关插件 经过绘图方式来生成xmlexpress

相关网站:
官网:https://www.activiti.org/
用户向导:https://www.activiti.org/userguide
中文用户向导:http://www.mossle.com/docs/activiti/index.html

eclipse插件安装(参考用户向导https://www.activiti.org/userguide/#activitiDesigner)
eclipse点击菜单  Help → Install New Software
输入如下信息:
  Name:Activiti BPMN 2.0 designer
  Location:http://activiti.org/designer/update/

api

点击ok 后选择赞成协议后安装完成便可 新建任意项目 新建diagram文件 操做以下gif动态图

springboot

相关概念解释
架构

  •   流程引擎:流程定义和流程实例相关的入口api 流程引擎能够生成数据库的存储表 经过产生不一样的service来操做不一样的流程  
  1. repositoryService 用于发布流程定义  
  2. taskService用于操做任务 (任务查询,任务完成,设置流程变量)
  3. runtimeService能够用于操做流程实例 (运行流程,设置流程变量) 
  4. historyService能够查看历史流程
  5. IdentityService 操做用户和组信息

    如下代码就是流程引擎以及各服务的相关代码
    oracle

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RuntimeService runtimeService = processEngine.getRuntimeService();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    TaskService taskService = processEngine.getTaskService();
    ManagementService managementService = processEngine.getManagementService();
    IdentityService identityService = processEngine.getIdentityService();
    HistoryService historyService = processEngine.getHistoryService();
    FormService formService = processEngine.getFormService();
    DynamicBpmnService dynamicBpmnService = processEngine.getDynamicBpmnService();

  •   流程定义:将bpmn相关的文件和图片发布到流程数据库中 生成对应的流程信息 流程通过哪些任务 指派给哪一个用户完成任务
  •   流程实例 : 每一个定义均可以产生多个流程实例 流程实例全部的任务须要指派的用户去完成后才能走向下一个节点,存在多个分支的用户节点须要经过流程变量值来判断流程走向
bpmn图中相关节点解释(经常使用)

开始节点 全部的流程图都须要有个开始节点
框架

  结束节点 全部流程图都必须有个结束节点
   任务节点 须要用户处理的任务 好比审批就是须要人工去完成的一个任务 就须要定义任务节点 该节点被广泛
                     使用
顺序线 上一个节点完成后 须要走到的下一个节点能够经过 顺序线链接

 排他节点 流程须要分支须要经过排他节点 进行判断 若是有多个分支 最后流程只会走向其中一个分支

                     好比请假  天数<3天 走组长审批  3-5天 走项目经理审批  5天以上boss审批 最后请假了多少天 只会是某我的审批 
                     具备排他性 

 并行节点 好比有两个分支  有可能两个分支流程都须要走  可使用并行节点                

 流程变量和脚本
   在流程运行过程当中能够定义流程变量 分为全局变量和临时变量 全局变量在整个流程中可用 局部变量在当前节点定义只能在当前节点中使用  通常好比请假 提交请假的天数 请假的时间 能够在请假任务完成后 添加全局变量   还好比若是有个排他节点 能够
经过请假的天数判断走哪一个审批流程
   全部定义的变量能够是普通的数据类型也能够是对象 在流程定义时可使用uel表达式来获取流程变量的值 
 好比 ${userDay} 能够获取天数 ,判断 ${userDay<3} 也能够调用对象方法 好比 ${user.getUserDay()} 
 表达式能够参考 https://www.activiti.org/userguide/#apiExpressions
 流程变量参考 https://www.activiti.org/userguide/#apiVariables
好比官网图 定义排他节点(input==1走上面流程 input==2走中间流程 input==3走下面流程) 流程开始时只须要添加一个键值对的流程变量 input=某个值 就能决定走哪条线路



二。activiti配置

        ProcessEngines.getDefaultProcessEngine()会在第一次调用时 初始化并建立一个流程引擎,之后再调用就会返回相同的流程引擎。 使用对应的方法能够建立和关闭全部流程引擎:ProcessEngines.init() 和 ProcessEngines.destroy()。

          ProcessEngines会扫描全部activiti.cfg.xml 和 activiti-context.xml 文件。 对于activiti.cfg.xml文件,流程引擎会使用Activiti的经典方式构建:                                         ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine().             对于activiti-context.xml文件,流程引擎会使用Spring方法构建:先建立一个Spring的环境, 而后经过环境得到流程引擎。

 全部流程相关的数据都保存在数据库中 须要先经过流程引擎配置生成数据库的表  具体的实现参考官方用户向导
(https://www.activiti.org/userguide/#_configuration)

类路径下添加 activiti.cfg.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

    <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:orcl" />
    <property name="jdbcDriver" value="oracle.jdbc.driver.OracleDriver" />
    <property name="jdbcUsername" value="ac" />
    <property name="jdbcPassword" value="ac" />

    <property name="databaseSchemaUpdate" value="true" />
  </bean>

</beans>
添加maven依赖
<dependencies>
		<!-- https://mvnrepository.com/artifact/org.activiti/activiti-engine -->
		<dependency>
			<groupId>org.activiti</groupId>
			<artifactId>activiti-engine</artifactId>
			<version>5.22.0</version>
		</dependency>
<!-- https://mvnrepository.com/artifact/com.hynnet/oracle-driver-ojdbc -->
<dependency>
    <groupId>com.hynnet</groupId>
    <artifactId>oracle-driver-ojdbc</artifactId>
    <version>12.1.0.2</version>
</dependency>
</dependencies>

获取流程实例 自动建立表

package activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;

public class TestCreateDb {

	public static void main(String[] args) {
		ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	}

}

运行main方法 查看数据库 发现产生了25张表


Activiti的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应。

  1. ACT_RE_*: 'RE'表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
  2. ACT_RU_*: 'RU'表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程当中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表能够一直很小速度很快。
  3. ACT_ID_*: 'ID'表示identity。 这些表包含身份信息,好比用户,组等等。
  4. ACT_HI_*: 'HI'表示history。 这些表包含历史数据,好比历史流程实例, 变量,任务等等。
  5. ACT_GE_*: 通用数据, 用于不一样场景下。


三。activiti 实例,bpmn及经常使用api操做

如下经过一个流程实例显示 activiti的全部相关api操做 

模拟实例 好比威客网站中某个雇主发布了一个单人悬赏的任务 此时不一样的威客均可以发起投稿投标的流程  流程图以下

威客开启一个流程定义流程变量(威客用户id)威客交稿的任务当前威客经过威客id能够查询到任务  威客交稿任务

 开始 用户须要传递投稿的任务编号 雇主信息 稿件信息 完成任务后 雇主选稿 选稿任务完成 须要进入排他路由 选中
和未选中经过一个流程变量来控制  若是未选中 直接发送落选邮件到威客帐号 选中继续后 使用并行路由 同时开启两个流程
(发送通知邮件 ,威客提交终稿)是同时执行 互不影响  只演示前半部分 后面部分类似
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:activiti="http://activiti.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.activiti.org/test">
  <process id="inviteProcess" name="inviteProcess" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="wkInvite" name="威客交稿" activiti:assignee="${userWk}"></userTask>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="wkInvite"></sequenceFlow>
    <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
    <serviceTask id="mailtask1" name="发送落选邮件" activiti:type="mail">
      <extensionElements>
        <activiti:field name="to">
          <activiti:expression><![CDATA[${email_to}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="from">
          <activiti:expression><![CDATA[${email_from}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="subject">
          <activiti:expression><![CDATA[${email_title}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="html">
          <activiti:expression><![CDATA[${email_content}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="charset">
          <activiti:string><![CDATA[utf-8]]></activiti:string>
        </activiti:field>
      </extensionElements>
    </serviceTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow4" sourceRef="exclusivegateway1" targetRef="mailtask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${shortlist==0}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow5" sourceRef="mailtask1" targetRef="endevent1"></sequenceFlow>
    <parallelGateway id="parallelgateway1" name="Parallel Gateway"></parallelGateway>
    <serviceTask id="mailtask2" name="发送中标邮件" activiti:type="mail">
      <extensionElements>
        <activiti:field name="to">
          <activiti:expression><![CDATA[${email_to}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="from">
          <activiti:expression><![CDATA[${email_from}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="subject">
          <activiti:expression><![CDATA[${email_title}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="html">
          <activiti:expression><![CDATA[${email_content}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="charset">
          <activiti:string><![CDATA[utf-8]]></activiti:string>
        </activiti:field>
      </extensionElements>
    </serviceTask>
    <sequenceFlow id="flow6" sourceRef="exclusivegateway1" targetRef="parallelgateway1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${shortlist==1}]]></conditionExpression>
    </sequenceFlow>
    <userTask id="usertask1" name="提交最终稿件" activiti:assignee="${userWk}"></userTask>
    <sequenceFlow id="flow7" sourceRef="parallelgateway1" targetRef="mailtask2"></sequenceFlow>
    <sequenceFlow id="flow8" sourceRef="parallelgateway1" targetRef="usertask1"></sequenceFlow>
    <userTask id="usertask2" name="雇主确认" activiti:assignee="${employer}"></userTask>
    <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow9" sourceRef="exclusivegateway2" targetRef="usertask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${ifaccept==0}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow10" sourceRef="usertask2" targetRef="exclusivegateway2"></sequenceFlow>
    <sequenceFlow id="flow11" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
    <userTask id="usertask3" name="威客收款" activiti:assignee="${userWk}"></userTask>
    <sequenceFlow id="flow12" sourceRef="exclusivegateway2" targetRef="usertask3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${ifaccept==1}]]></conditionExpression>
    </sequenceFlow>
    <endEvent id="endevent2" name="End"></endEvent>
    <sequenceFlow id="flow13" sourceRef="usertask3" targetRef="endevent2"></sequenceFlow>
    <endEvent id="endevent3" name="End"></endEvent>
    <sequenceFlow id="flow14" sourceRef="mailtask2" targetRef="endevent3"></sequenceFlow>
    <userTask id="usertask4" name="雇主选稿" activiti:assignee="${employer}"></userTask>
    <sequenceFlow id="flow15" sourceRef="wkInvite" targetRef="usertask4"></sequenceFlow>
    <sequenceFlow id="flow16" sourceRef="usertask4" targetRef="exclusivegateway1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_inviteProcess">
    <bpmndi:BPMNPlane bpmnElement="inviteProcess" id="BPMNPlane_inviteProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="0.0" y="172.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="wkInvite" id="BPMNShape_wkInvite">
        <omgdc:Bounds height="55.0" width="105.0" x="60.0" y="162.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
        <omgdc:Bounds height="40.0" width="40.0" x="300.0" y="169.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="mailtask1" id="BPMNShape_mailtask1">
        <omgdc:Bounds height="55.0" width="105.0" x="380.0" y="216.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="415.0" y="380.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="parallelgateway1" id="BPMNShape_parallelgateway1">
        <omgdc:Bounds height="40.0" width="40.0" x="380.0" y="110.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="mailtask2" id="BPMNShape_mailtask2">
        <omgdc:Bounds height="55.0" width="105.0" x="470.0" y="56.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="470.0" y="135.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
        <omgdc:Bounds height="55.0" width="105.0" x="640.0" y="135.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
        <omgdc:Bounds height="40.0" width="40.0" x="672.0" y="223.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
        <omgdc:Bounds height="55.0" width="105.0" x="640.0" y="300.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent2" id="BPMNShape_endevent2">
        <omgdc:Bounds height="35.0" width="35.0" x="675.0" y="414.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent3" id="BPMNShape_endevent3">
        <omgdc:Bounds height="35.0" width="35.0" x="670.0" y="66.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask4" id="BPMNShape_usertask4">
        <omgdc:Bounds height="55.0" width="105.0" x="180.0" y="164.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="35.0" y="189.0"></omgdi:waypoint>
        <omgdi:waypoint x="60.0" y="189.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="320.0" y="209.0"></omgdi:waypoint>
        <omgdi:waypoint x="320.0" y="243.0"></omgdi:waypoint>
        <omgdi:waypoint x="380.0" y="243.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
        <omgdi:waypoint x="432.0" y="271.0"></omgdi:waypoint>
        <omgdi:waypoint x="432.0" y="380.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
        <omgdi:waypoint x="320.0" y="169.0"></omgdi:waypoint>
        <omgdi:waypoint x="320.0" y="138.0"></omgdi:waypoint>
        <omgdi:waypoint x="353.0" y="138.0"></omgdi:waypoint>
        <omgdi:waypoint x="388.0" y="138.0"></omgdi:waypoint>
        <omgdi:waypoint x="388.0" y="138.0"></omgdi:waypoint>
        <omgdi:waypoint x="420.0" y="130.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
        <omgdi:waypoint x="400.0" y="110.0"></omgdi:waypoint>
        <omgdi:waypoint x="400.0" y="83.0"></omgdi:waypoint>
        <omgdi:waypoint x="470.0" y="83.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
        <omgdi:waypoint x="400.0" y="150.0"></omgdi:waypoint>
        <omgdi:waypoint x="400.0" y="162.0"></omgdi:waypoint>
        <omgdi:waypoint x="470.0" y="162.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
        <omgdi:waypoint x="692.0" y="223.0"></omgdi:waypoint>
        <omgdi:waypoint x="522.0" y="190.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
        <omgdi:waypoint x="692.0" y="190.0"></omgdi:waypoint>
        <omgdi:waypoint x="692.0" y="223.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
        <omgdi:waypoint x="575.0" y="162.0"></omgdi:waypoint>
        <omgdi:waypoint x="640.0" y="162.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
        <omgdi:waypoint x="692.0" y="263.0"></omgdi:waypoint>
        <omgdi:waypoint x="692.0" y="300.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">
        <omgdi:waypoint x="692.0" y="355.0"></omgdi:waypoint>
        <omgdi:waypoint x="692.0" y="414.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14">
        <omgdi:waypoint x="575.0" y="83.0"></omgdi:waypoint>
        <omgdi:waypoint x="670.0" y="83.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">
        <omgdi:waypoint x="165.0" y="189.0"></omgdi:waypoint>
        <omgdi:waypoint x="180.0" y="191.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">
        <omgdi:waypoint x="285.0" y="191.0"></omgdi:waypoint>
        <omgdi:waypoint x="300.0" y="189.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>
演示代码以下
 假定流程引擎对象已经以下定义
//建立流程引擎对象
	private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

步骤1 发布流程定义

/**
	 * 发布流程 添加发布bpmn和图片 也能够打包成  zip发布
	 * 
	 */
	@Test
	public void deployProcess() {
		//用于发布流程资源 以及流程定义
		RepositoryService repositoryService = processEngine.getRepositoryService();
		Deployment deploy = repositoryService.createDeployment()
			.addClasspathResource("diagrams/MyProcess.bpmn")
			.addClasspathResource("diagrams/MyProcess.png")
			//.addZipInputStream(zipInputStream) 能够添加压缩包 web定义流程就可使用这个方法上传
			.name("威客单人投标流程")
			.deploy();
		//资源文件在act_ge_bytearray表中
		//流程定义在act_re_procdef表中
		System.out.println("流程定义id:"+deploy.getId());
		System.out.println("流程定义名称:"+deploy.getName());
		System.out.println("流程定义发布时间:"+deploy.getDeploymentTime().toGMTString());
		//查看发布的流程信息 查看发布的流程总和
		long count = repositoryService.createDeploymentQuery().count();
		System.out.println("总流程定义数:"+count);
	}
步骤2 zs查看本身的任务编号 完成投稿任务
查看任务
/**
	 * 运行流程
	 * 相同的流程被发布(id不一样 _key相同)多, 每发布 一次 ACT_RE_PROCDEF 多一条数据, Version都会加1,
	 *    根据key来启动 会启动最新版本号的流程定义
	 *   若是想执行旧的流程定义就可使用id来启动
	 * 模拟场景 某个威客 开始向某个任务投稿 任务就开始了  
	 */
	@Test
	public void startProcess() {
		//运行流程使用runtimesErvice
		RuntimeService runtimeService = processEngine.getRuntimeService();
		//流程变量 传入是谁启动的流程
		Map map=new HashMap();
		map.put("userWk", "zs");
		//key就是流程图的 id (注意不是数据库里面的id 数据库里面的key是流程里开始定义的id)
		//流程实例数据在 ACT_RU_EXECUTION表中 
		//流程变量 在 ACT_RU_VARIABLE中
		//用户任务在 ACT_RU_TASK中
		ProcessInstance  instance= runtimeService.startProcessInstanceByKey("inviteProcess",map);
		System.out.println("用户"+map.get("userWk")+"开启了一个投稿流程");
		System.out.println("流程实例编号是:"+instance.getProcessInstanceId());
		long count = runtimeService.createExecutionQuery().count();
		System.out.println("总流程实例数:"+count);
	}

完成任务

/**
	 * 张三完成任务 就须要交稿 定义流程变量
	 */
	@Test
	public void submitTask() {
		//用户任务的完成 使用TaskService
		TaskService taskService = processEngine.getTaskService();
		String taskId="20005";
		Map map=new HashMap();
		/**
		 * 张三交稿数据
		 * **/
		map.put("employer", "ls");//设置任务的雇主
		map.put("taskNo", "雇主任务编号");
		map.put("taskContent", "用字符串模拟");
		
		
		taskService.complete(taskId, map);
	}

步骤3 雇主ls查看本身的任务编号 完成选稿稿任务 这里模拟shortlist==0表示没选中 进入发送邮件结束流程的步骤 

须要配置邮件的smtp和用户密码信息 修改activiti.cfg.xml 添加


<property name="mailServerHost" value="smtp.126.com" />
    <property name="mailServerPort" value="25" />
    <property name="mailServerUsername" value="lixin1112003@126.com"></property>
    <property name="mailServerPassword" value="XXXXXXXXXX您的邮箱密码"></property>
未选中代码
/**
	 * 李四完成任务 就须要选稿  
	 */
	@Test
	public void submitTask() {
		//用户任务的完成 使用TaskService
		TaskService taskService = processEngine.getTaskService();
		String taskId="20005";
		Map map=new HashMap();
		
		map.put("shortlist", 0);
		map.put("email_to", "973465719@qq.com");
		map.put("email_from", "lixin1112003@126.com");
		map.put("email_title", "973465719@qq.com");
		map.put("email_content", "您对雇主任务编号"+taskService.getVariable(taskId, "taskNo")+"的投稿稿件 已经落选。。");
		
		taskService.complete(taskId, map);
	}
选中代码
/**
	 * 李四完成任务 就须要选稿  
	 */
	@Test
	public void submitTask() {
		//用户任务的完成 使用TaskService
		TaskService taskService = processEngine.getTaskService();
		String taskId="20005";
		Map map=new HashMap();
		
		map.put("shortlist", 1);
		map.put("email_to", "973465719@qq.com");
		map.put("email_from", "lixin1112003@126.com");
		map.put("email_title", "973465719@qq.com");
		map.put("email_content", "您对雇主任务编号"+taskService.getVariable(taskId, "taskNo")+"的投稿稿件 已经被选中 请完成终稿。。");
		
		taskService.complete(taskId, map);
	}

其余代码就不演示 具体参考https://www.activiti.org/userguide/#chapterApi

四。springboot集成activiti

 集成web参考  https://www.activiti.org/userguide/#springintegration

相关文章
相关标签/搜索