转办:某个节点,候选人是好几人。其中一个人拾取了该任务,发现不应该办理,可以转给候选人中的其他人
会签:
| StartEvent | 开始事件(重要) |
| EndEvent | 结束事件(重要) |
| IntermediateEvent | 中间事件 |
| UserTask | 用户任务:表示需要人参与的任务,可以配置候选人/组/代理人等。(重要) |
| ServiceTask | 服务任务:调用外部服务或自动执行程序。 |
| ManualTask | 手工任务:就是一个直接通过的任务。可以使用它来自动执行一些可以直接通过的任务 |
| BusinessRuleTask | 规则任务: |
| SubProcess | 子流程:子流程表示多个activity的组合。子流程内部的元件禁止和外部的元件直连,只能作为一个整体与父流程的元件相连接。 |
| Lane | |
| ExclusiveGateway | 排他网关 |
| EventGateway | |
| IntermediateCatchingEvent | |
| Annotation | |
| ScriptTask | 脚本任务:用于执行定义好的脚本程序,流程执行到这个结点自动执行脚本。 |
| MailTask | |
| ReceiveTask | |
| CallActivityTask | |
| Pool | |
| ParallelGateway | 并行网关 |
| InclusiveGateway | 包容性网关 |
| BoundaryEvent | |
| IntermediateThrowingEvent |
BPMN2.0之顺序流和网关_Richard678的博客-CSDN博客_bpmn顺序
https://www.jianshu.com/p/6f38a0275e98/
userTask属性:
| documentation | 文档 |
| asynchronous | 异步 |
| exclusive | 独家专用的 |
| multi instance | 多实例 |
| assignee | 代理人,受让人 |
| candidate users | 候选人 ; 申请人 |
| candidate groups | 候选组 |
| due date | 到期日 |
| form key | 表单键 |
| priority | 优先事项 |
| task listeners | 任务监听器 |
| execution listeners | 执行监听器 |
| form | 表单 |
| 表分类 | 表名 | |
| 一般数据 | ||
| act_ge_bytearray | 通用的流程定义和流程资源 | |
| act_ge_property | 系统相关属性 | |
| 流程历史记录 | ||
| act_hi_actinst | 历史的流程实例 (节点表,审批到哪个节点了,) | |
| act_hi_attachment | 历史的流程附件 | |
| act_hi_comment | 历史的流程说明性信息 | |
| act_hi_detail | 历史的流程运行中的细节信息 | |
| act_hi_identitylink | 历史的流程运行过程中用户关系 | |
| act_hi_procinst | 历史的流程实例 | |
| act_hi_taskinst | 历史的任务实例 | |
| act_hi_varinst | 历史的流程运行中的变量信息 | |
| 流程定义表 | ||
| act_re_deployment | 部署单元信息 | |
| act_re_model | 模型信息 | |
| act_re_procdef | 部署的流程定义 | |
| 运行实例表 | ||
| act_ru_deadletter_job | 死信 | |
| act_ru_event_subscr | 运行时事件 | |
| act_ru_execution | 运行时流程执行实例 | |
| act_ru_identitylink | 运行时用户关系信息,存储任务节点与参与者的相关信息 | |
| act_ru_integration | 集成 | |
| act_ru_job | 运行时作业 | |
| act_ru_suspended_job | 暂停 | |
| act_ru_task | 运行时任务 | |
| act_ru_timer_job | ||
| act_ru_variable | 运行时变量表 |
- Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应。
- ACT_RE_*: 'RE'表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
- ACT_RU_*: 'RU'表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
- ACT_ID_*: 'ID'表示identity。 这些表包含身份信息,比如用户,组等等。
- ACT_HI_*: 'HI'表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。
- ACT_GE_*: 通用数据, 用于不同场景下,如存放资源文件。
不同点:activiti6是28张数据表,activiti7是25张,少了用户和组的三张表。相应的服务接口也少了俩:IdentityService和FormService。另外activiti7中对activiti6的API再次进行了封装,新增加了分布式和云部署的功能,核心没变

RepositoryService:流程定义和部署对象
RuntimeService:执行管理,包括流程实例和执行对象(正在执行)
TaskService:执行任务相关的(正在执行)
HistoryService:历史管理
IdentityService:Activiti表的用户角色组
ManagementService:引擎管理服务





功能复用:对于像查询待办任务、已办任务、抄送我的、我发起的流程、流程部署、流程挂起与激活、生成流程图等这样的可以复用的功能,使用一套代码即可,提供统一的接口或service。
功能不复用:但是对于启动流程、完成任务这样的功能,因为每个流程的参数或流程变量不一样,并且任务完成之后做的回调事情也不一样,如果不能复用,则每一个流程都单独开发这样的功能。
目前采用的方式是:对于启动流程、完成任务抽象出一个interface,让不同的流程service实现各自不同的操作;创建一个简单工厂,根据流程类型实例化不同的流程service;对外只暴露出启动流程和完成任务两个接口,前端传递不同的流程类型,执行不同的service操作。
数据表扩展:如果activiti提供的数据表无法满足业务需求,可以建立关联表,辅助业务运行。
idea插件actiBPM 和pom
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>2.2.2</version>
- </dependency>
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid-spring-boot-starter</artifactId>
- <version>1.1.10</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <scope>runtime</scope>
- <!-- <version>8.0.30</version>-->
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <!-- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-bpmn-converter</artifactId>
- <version>6.0.0</version>
- </dependency>-->
- <!--
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-engine</artifactId>
- <version>7.0.0.Betal</version>
- </dependency>
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-spring</artifactId>
- <version>7.0.0.Betal</version>
- </dependency>
- <!– bpmn模型处理–>
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-bpmn-model</artifactId>
- <version>7.0.0.Betal</version>
- </dependency>
- <!– bpmn转换–>
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-bpmn-converter</artifactId>
- <version>7.0.0.Betal</version>
- </dependency>
- <!– bpmn json数据转换–>
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-json-converter</artifactId>
- <version>7.0.0.Betal</version>
- </dependency>
- <!– bpmn 布局–>
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-bpmn-layout</artifactId>
- <version>7.0.0.Betal</version>
- </dependency>
- <!– activiti 云支持–>
- <dependency>
- <groupId>org.activiti.cloud</groupId>
- <artifactId>activiti-cloud-service-api</artifactId>
- <version>7.0.0.Betal</version>
- </dependency>
- -->
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>1.6.6</version>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.12</version>
- </dependency>
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-spring-boot-starter</artifactId>
- <version>7.0.0.Beta2</version>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.6</version>
- </dependency>
yml
- server:
- port: 8080
- spring:
- application:
- name: activiti
- datasource:
- driver-class-name: com.mysql.jdbc.Driver
- url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=UTF-8&useTimezone=true&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
- username: root
- password: root
- druid:
- filter:
- stat:
- enabled: true
- db-type: mysql
- log-slow-sql: true
-
- activiti:
- # false:默认值。在activiti启动时,会对比数据库表中保存的版本,如果没有表或版本不匹配,将抛出异常。(生产环境常用)
- # true:activiti会对数据库中所有表进行更新操作。如果表不存在,将会创建。(开发环境常用)
- # create-drop:在activiti启动时创建表,在关闭时删除表,必须手动关闭引擎才会删除表。(单元测试用)
- # drop-create:在activiti启动时删除旧表,然后创建新表,不需要关闭引擎。
- database-schema-update: true
- #检测历史表是否存在,activiti7默认没有开启数据库历史记录,true启动数据库历史记录
- db-history-used: true
- #记录历史等级,可配置的历史级别有:none,activity,audit,full
- # none:不保存任何的历史数据,因此在流程执行过程中,这是最高效的
- # activity:级别高于none,保存流程实例与流程行为,其他数据不保存
- # audit:除保存activity保存的数据外,还会保存全部的流程任务及其属性。history-level的默认值
- # full:保存历史数据的最高级别,会额外保存全部流程相关的细节数据。
- history-level: full
- #校验流程文件,默认校验resources下的process文件夹的流程文件
- check-process-definitions: false
- logging:
- pattern:
- console: "%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n"
- level:
- org.activiti.engine.impl.persistence.entity: trace
- mybatis:
- configuration:
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
activiti.cfg.xml:springboot方式就不用了。
- <?xml version="1.0" encoding="UTF-8"?>
- <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">
-
-
- <!--dbcp数据源-->
- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
- <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
- <property name="url" value="jdbc:mysql://localhost:3306/activiti"/>
- <property name="username" value="root"/>
- <property name="password" value="root"/>
- </bean>
-
- <!--配置Activiti的ProcessEngineConfiguration对象,因为没有跟spring整合,所以这里使用单例的。-->
- <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
- <!--注入数据源-->
- <property name="dataSource" ref="dataSource"/>
- <!--指定数据表生成策略,该策略是,若数据表不存在则创建,存在则更新-->
- <property name="databaseSchemaUpdate" value="true"/>
- </bean>
- </beans>
Activiti学习——踩坑和经验_chuchui5713的博客-CSDN博客
分配个人任务的三种方式
1:直接给值,在Xxxx.bpmn文件中指定
2:流程变量${流程变量的名称}或者#{}
3:使用类 监听这个类(实现一个接口),指定任务的办理人(setAssgnee())
个人任务和组任务的查询一样吗?
* 不一样
* 都是用TaskService完成(TaskService.createTasQuery)
* 个人任务(taskAssgnee),组任务(taskCandidateUser)
* 数据库存放,个人任务(类型:参与),组任务(类型,参与,候选)
张三提交申请单---> 李四经理审批--->王五总经理审批


生成图片流程:
1将travel.bpmn 改名为 travel.xml
2:右击 找到Diagrams --->show BPMN 2.0 Designer
3: 点击导出 image
4 将 travel.xml改为 travel.bpmn


结论:
act_re_deployment (流程部署 )和act_re_procdef(流程定义) 一对多的关系
procdef表中,可以有多条记录,每一条记录,对应一个流程的定义信息。
张三 走这个出差申请流程
李四 也走这个出差申请流程
简单的案例代码
- package com.example.activiti;
-
- import org.activiti.engine.*;
- import org.activiti.engine.history.HistoricActivityInstance;
- import org.activiti.engine.history.HistoricActivityInstanceQuery;
- import org.activiti.engine.repository.Deployment;
- import org.activiti.engine.repository.ProcessDefinition;
- import org.activiti.engine.repository.ProcessDefinitionQuery;
- import org.activiti.engine.runtime.ProcessInstance;
- import org.activiti.engine.task.Task;
- import org.activiti.engine.task.TaskQuery;
- import org.apache.commons.io.IOUtils;
- import org.junit.jupiter.api.BeforeEach;
- import org.junit.jupiter.api.Test;
- import org.springframework.boot.test.context.SpringBootTest;
-
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.List;
- import java.util.zip.ZipInputStream;
-
- @SpringBootTest
- class ActivitiApplicationTests {
- static ProcessEngine processEngine = null;
-
- @BeforeEach
- void test() {
- /**
- * 初始化流程引擎对象,将会根据配置创建25数据表(创建了索引和外键)
- */
- processEngine = ProcessEngines.getDefaultProcessEngine();
-
- }
-
- /**
- * 部署流程 将流程保存到数据中
- */
- @Test
- void test1() {
- RepositoryService repositoryService = processEngine.getRepositoryService();
-
- //zip方式部署 (可以很多流程都压缩在一个zip下)
- InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("bpmn/travel.zip");
- ZipInputStream zipInputStream = new ZipInputStream(inputStream);
- Deployment deploy = repositoryService.createDeployment().addZipInputStream(zipInputStream)
- // .name("")
- .deploy();
-
- // 单个部署方式
- Deployment deployment = repositoryService.createDeployment()
- .addClasspathResource("bpmn/travel.bpmn")
- .addClasspathResource("bpmn/travel.png")
- // .name("请假流程测试")
- // .category("办公类别") //设置部署的类别
- .deploy();
- System.out.println(deployment.getId());//流程部署id 6f2030ef-58ec-11ed-bbe8-fa89d281dc2b
- System.out.println(deployment.getName());//流程部署名字 请假流程测试
- System.out.println(deployment.getKey());//null
- System.out.println(deployment.getCategory());//null
- System.out.println(deployment.getDeploymentTime());
- System.out.println(deployment.getTenantId());//null
-
- /*
- 受影响的表:3个
- act_re_deployment:流程部署表 : 添加一条流程部署记录 主键是贯穿这三个表
- act_re_procdef::流程定义:添加一条流程定义记录,一个流程定义记录和一个流程图一一对应,流程定义记录的key就是流程图的id
- act_ge_bytearray:blob形式保存部署的资源
- */
-
- /*
- 流程部署意味着两件事:
- 1、将流程定义文件放到activiti引擎配置的持久化存储中,以便activiti引擎重启时能再次读取部署的流程。
- 2、解析bpmn文件并转化为activiti内存中的对象模型,然后就能使用acticiti提供的api对持久化的数据进行操作。
- */
- }
-
- /**
- * 查询流程定义 act_re_procdef
- */
- @Test
- void tes2() {
- RepositoryService repositoryService = processEngine.getRepositoryService();
- ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
- List<ProcessDefinition> myTravel_1 = processDefinitionQuery.processDefinitionKey("myTravel_1")
- .orderByProcessDefinitionVersion() //根据 Version 正序
- .asc() //正序
- .list();
- for (ProcessDefinition processDefinition : myTravel_1) {
- System.out.println("流程定义ID: "+processDefinition.getId());//IDmyTravel_1:1:6f3602e2-58ec-11ed-bbe8-fa89d281dc2b
- System.out.println("流程定义名称: "+processDefinition.getName()); //出差申请流程
- System.out.println("流程定义key: "+processDefinition.getKey()); //keymyTravel_1
- System.out.println("流程定义版本: "+processDefinition.getVersion()); //1
- System.out.println("流程定义部署id: "+processDefinition.getDeploymentId()); //710668f8-5904-11ed-b08d-fa89d281dc2b
- }
- }
-
- /**
- * 删除流程定义 act_re_procdef
- */
- @Test
- void tes3() {
- RepositoryService repositoryService = processEngine.getRepositoryService();
- //通过部署id删除流程部署信息 不会删除历史表的信息
- repositoryService.deleteDeployment("54215d66-5903-11ed-a890-fa89d281dc2b");
- //历史信息也会删除
- repositoryService.deleteDeployment("54215d66-5903-11ed-a890-fa89d281dc2b",true);
- /**
- * delete from ACT_GE_BYTEARRAY where DEPLOYMENT_ID_ =
- * delete from ACT_RE_DEPLOYMENT where ID_ =
- * delete from ACT_RE_PROCDEF where DEPLOYMENT_ID_ =
- * delete from ACT_RU_IDENTITYLINK where PROC_DEF_ID_ =
- */
- }
-
- /**
- * 下载流程
- */
- @Test
- void tes4() throws IOException {
- RepositoryService repositoryService = processEngine.getRepositoryService();
- //查询流程定义信息
- ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
- .processDefinitionKey("myTravel_1").singleResult();
- //获取流程部署id
- String deploymentId = processDefinition.getDeploymentId();
-
- //获取图片目录和名字
- String pngName = processDefinition.getDiagramResourceName();
- InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, pngName);
-
- //获取bpmn目录和名字
- String bpmnName = processDefinition.getResourceName();
- InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, bpmnName);
- File pngfile = new File("D:/travel.png");
- File bpmnfile = new File("D:/travel.bpmn");
-
- FileOutputStream pngOutputStream = new FileOutputStream(pngfile);
- FileOutputStream bpmnOutputStream = new FileOutputStream(bpmnfile);
-
- IOUtils.copy(pngInput, pngOutputStream);
- IOUtils.copy(bpmnInput, bpmnOutputStream);
- pngInput.close();
- bpmnInput.close();
- pngOutputStream.close();
- bpmnOutputStream.close();
- }
-
-
-
- /**
- * 运行工作流
- */
- @Test
- void test5() {
- RuntimeService runtimeService = processEngine.getRuntimeService();
- //act_re_procdef---拿来的参数
- ProcessInstance processInstance = runtimeService.startProcessInstanceById("myTravel_1:1:6f3602e2-58ec-11ed-bbe8-fa89d281dc2b");
- // runtimeService.startProcessInstanceByKey("myTravel_1");
- System.out.println("流程定义ID"+processInstance.getProcessDefinitionId());//myTravel_1:1:6f3602e2-58ec-11ed-bbe8-fa89d281dc2b
- System.out.println("流程实例ID"+processInstance.getId());//c96e78ef-58f7-11ed-9f8b-fa89d281dc2b
- System.out.println("流程活动ID"+processInstance.getActivityId());//null
-
- /* act_ru_task 任务信息
- * act_ru_identitylink 标识链接 流程的参与用户信息
- * act_ru_execution 处决 流程正在执行信息
- * act_hi_taskinst 任务 流程任务历史信息
- * act_hi_procinst 流程实例历史信息
- * act_hi_identitylink 流程的参与用户信息历史
- * act_hi_actinst 流程实例执行历史
- *
- * */
- }
-
- /**
- * 查询张三正在执行任务查询
- * 正在执行的任务会在这个表 ACT_RU_TASK ,一旦这个节点完成,会到历史表中,下一个节点到 ACT_RU_TASK 中
- * https://blog.csdn.net/JHC23/article/details/97001687?ops_request_misc=&request_id=&biz_id=102&utm_term=activi&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-5-97001687.142^v62^pc_search_tree,201^v3^control_1,213^v1^control&spm=1018.2226.3001.4187
- */
- @Test
- void test6() {
- TaskService taskService = processEngine.getTaskService();
- //创建任务查询对象
- TaskQuery taskQuery = taskService.createTaskQuery();
- //查看办理人的任务列表
- List<Task> list = taskQuery
- .processDefinitionKey("myTravel_1") // 流程key
- .taskAssignee("张三").list();//要查询的负责人
- //select distinct RES.* from ACT_RU_TASK RES WHERE RES.ASSIGNEE_ ="张三"
- // select distinct RES.* from ACT_RU_TASK RES inner join ACT_RE_PROCDEF D on RES.PROC_DEF_ID_ = D.ID_ WHERE RES.ASSIGNEE_ = '张三' and D.KEY_ = 'myTravel_1'
- for (Task task : list) {
- System.out.println("任务办理人:"+task.getAssignee());
- System.out.println("任务id:" + task.getId());
- System.out.println("任务名称:"+ task.getName());
- System.out.println("流程实例id:"+ task.getProcessInstanceId());
-
- }
-
- }
-
- /**
- * 张三提交申请单 完成个人任务
- */
- @Test
- void test7() {
-
- TaskService taskService = processEngine.getTaskService();
- //根据任务id act_ru_task 表的 id 完成任务
- // act_ru_task 目前节点是 提交申请单
- taskService.complete("75b2666e-598d-11ed-951f-fa89d281dc2b");
-
- // 执行后 act_ru_task 节点变成 经理审批 act_hi_taskinst 也会多一个经理审批
- /*流程sql
- select * from ACT_RU_TASK where ID_ = 'c972e5c3-58f7-11ed-9f8b-fa89d281dc2b'
- * select * from ACT_RE_PROCDEF where ID_ = 'myTravel_1:1:6f3602e2-58ec-11ed-bbe8-fa89d281dc2b'
- * select * from ACT_RE_DEPLOYMENT where ID_ ='6f2030ef-58ec-11ed-bbe8-fa89d281dc2b'
- * select * from ACT_GE_BYTEARRAY where DEPLOYMENT_ID_ = '6f2030ef-58ec-11ed-bbe8-fa89d281dc2b' order by NAME_ asc
- * insert into ACT_HI_TASKINST 经理审批的数据
- * insert into ACT_HI_ACTINST 经理审批的数据
- * insert into ACT_HI_IDENTITYLINK 李四人员数据
- insert into ACT_RU_TASK 经理审批的数据
- insert into ACT_RU_IDENTITYLINK 李四人员数据
- * update ACT_HI_ACTINST 张三
- update ACT_RU_EXECUTION update ACT_HI_TASKINST delete from ACT_RU_TASK 张三
- */
-
- }
-
-
- /**
- * 查看历史信息 (审批节点) ACT_HI_ACTINST
- */
- @Test
- void test8() {
- HistoryService historyService = processEngine.getHistoryService();
- HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
- //act_hi_actinst表 PROC_INST_ID_字段
- //select RES.* from ACT_HI_ACTINST RES WHERE RES.PROC_INST_ID_ = ?
- instanceQuery.processInstanceId("c96e78ef-58f7-11ed-9f8b-fa89d281dc2b");
- //排序 开始
- instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
- List<HistoricActivityInstance> list = instanceQuery.list();
- for (HistoricActivityInstance instance : list) {
- System.out.println(instance.getActivityId());//_3
- System.out.println(instance.getActivityName());// 经理审批
- System.out.println(instance.getProcessDefinitionId()); //myTravel_1:1:6f3602e2-58ec-11ed-bbe8-fa89d281dc2b
- System.out.println(instance.getProcessInstanceId());//c96e78ef-58f7-11ed-9f8b-fa89d281dc2b
- }
-
- }
-
-
-
- @Test
- void del() {
- RepositoryService repositoryService = processEngine.getRepositoryService();
- // repositoryService.deleteDeployment();
-
-
- RuntimeService runtimeService = processEngine.getRuntimeService();
- //act_re_procdef---拿来的参数
- // ProcessInstance processInstance = runtimeService.startProcessInstanceById("myTravel_1:1:6f3602e2-58ec-11ed-bbe8-fa89d281dc2b");
- runtimeService.deleteProcessInstance("51b423d0-5902-11ed-b595-fa89d281dc2b","");
- }
-
-
-
-
-
-
-
- }
绑定其他业务表

占位符方式
UEL-value方式: ${submitName}
UEL-method方式: ${User.submitName}
结合版: ${userService.findUser(userBean)}
详解:userService是spring容器的类,调用接口 findUser 入参 userBean 是activiti流程变量
其他:${order.price>100 && order.price<200} 表达式支持解析基础类型,bean,list,array,map

- static ProcessEngine processEngine = null;
-
- @BeforeEach
- void test() {
- /**
- * 初始化流程引擎对象,将会根据配置创建25数据表(创建了索引和外键)
- */
- processEngine = ProcessEngines.getDefaultProcessEngine();
-
- }
- /**
- * 分配任务负责人
- * 1:固定方式
- * 2 uel表达式方式 ( UEL-value 和 UEL-method)
- * 3 监听器方式
- */
- @Test
- void test4() {
- // 1:固定方式 就是我们用idea软件画图的时候直接给死了人员名称。创建申请单就是张三。
-
- /* 注意一定变成xml方式看看是不是写的表达式,有的时候变不过来
- 2: UEL-value方式: ${submitName}
- UEL-method方式: ${User.submitName}
- 结合版: ${userService.findUser(userBean)} userService是spring容器的类,调用接口 findUser 入参 userBean 是activiti流程变量
- 其他:${order.price>100 && order.price<200} 表达式支持解析基础类型,bean,list,array,map
- */
- RepositoryService repositoryService = processEngine.getRepositoryService();
- Deployment deployment = repositoryService.createDeployment()
- .addClasspathResource("bpmn/travel3.bpmn")
- .name("动态人员出差申请流程")
- .deploy();
- RuntimeService runtimeService = processEngine.getRuntimeService();
- HashMap<String, Object> hashMap = new HashMap<>();
- hashMap.put("submitName","张三-动态");
- hashMap.put("approval1","李四-动态");
- hashMap.put("approval2","王五-动态");
- runtimeService.startProcessInstanceByKey("myTravel_3",hashMap);
- // act_ru_variable 会存 字段和人名 映射关系
-
- // 删除 repositoryService.deleteDeployment("240b39a6-59c8-11ed-8bd7-fa89d281dc2b",true);
- }
挂起
- /**
- * 挂起:当流程实例没有跑完,如果已经挂起,就不能继续处理了,只有当流程激活后,才能继续执行。
- * 挂起后 完成任务 taskService.complete() 报错会
- * act_ru_task:SUSPENSION_STATE_ 暂停_状态_ 1 未暂停 2 暂停
- */
- @Test
- void test3() {
- /**
- * 多实例流程的挂起
- */
- RepositoryService repositoryService = processEngine.getRepositoryService();
- ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("myTravel_1").singleResult();
- //当前所有流程实例是否被挂起
- boolean suspended = processDefinition.isSuspended();
- if(suspended){
- //激活方法 参数1:流程定义id 参数2:是否激活 参数3:激活时间
- repositoryService.activateProcessDefinitionById(processDefinition.getId(),true,null);
- }else {
- //挂起方法 参数1:流程定义id 参数2:是否暂停 参数3:暂停时间
- repositoryService.suspendProcessDefinitionById(processDefinition.getId(),true,null);
- }
-
- /**
- * 单个流程实例的挂起
- */
- RuntimeService runtimeService = processEngine.getRuntimeService();
- ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processDefinitionId("c96e78ef-58f7-11ed-9f8b-fa89d281dc2b").singleResult();
- boolean suspended1 = processInstance.isSuspended();
- if(suspended1){
- //激活方法 参数1:流程定义id
- runtimeService.activateProcessInstanceById(processInstance.getId());
- }else {
- //挂起方法
- runtimeService.suspendProcessInstanceById(processInstance.getId());
- }
-
- }
监听器方式 动态分配人员 我的插件不好使了。始终出不来 算了

员工创建出差申请单,由经理审核,经理审核通过后出差3天一下直接由财务审批,3天以上由总经理审批,在财务审核。


- static ProcessEngine processEngine = null;
-
- @BeforeEach
- void test() {
- /**
- * 初始化流程引擎对象,将会根据配置创建25数据表(创建了索引和外键)
- */
- processEngine = ProcessEngines.getDefaultProcessEngine();
-
- }
- /**
- * 使用global变量控制流程
- */
- @Test
- void test6() {
- //保存到数据库
- RepositoryService repositoryService = processEngine.getRepositoryService();
- Deployment deployment = repositoryService.createDeployment()
- .addClasspathResource("bpmn/evection-global.bpmn")
- .name("global变量动态人员出差申请流程")
- .deploy();
- //开启流程
- RuntimeService runtimeService = processEngine.getRuntimeService();
- HashMap<String, Object> hashMap = new HashMap<>();
- Evection evection = new Evection();
- evection.setNum(2.0);
- evection.setId(1L);
- evection.setReason("项目出差原因");
- hashMap.put("evection",evection);
- hashMap.put("submitName","张三提交");
- hashMap.put("approval1","李四经理审批");
- hashMap.put("approval2","王五总经理-动态");
- hashMap.put("approval3","李六财务-动态");
- runtimeService.startProcessInstanceByKey("evection-global",hashMap);
- }
就是给当前流程设置多个负责人。


多人审批该任务时候。不能立即审批。先看这个人是不是候选人之一,是的话,还要在拾取该任务,变成个人任务。才能办理。
如果不想办理,还要将任务还回去。

- /**
- * 组任务 74
- */
- @Test
- void test7() {
- //保存到数据库
- RepositoryService repositoryService = processEngine.getRepositoryService();
- Deployment deployment = repositoryService.createDeployment()
- .addClasspathResource("bpmn/travel-candidate.bpmn")
- .name("组人员出差申请流程")
- .deploy();
- //流程定义的key
- String key="travel-candidate";
- //开启流程
- RuntimeService runtimeService = processEngine.getRuntimeService();
- runtimeService.startProcessInstanceByKey(key);
- TaskService taskService = processEngine.getTaskService();
-
- //创建申请单(张三) ----->经理审批(候选人 wangwu和lisi)-------等等
- String userId="张三";
- //创建申请单步骤
- // 张三查询自己待办任务
- Task task1 = taskService.createTaskQuery().processDefinitionKey(key).taskAssignee(userId).singleResult();
- if(task1!=null){
- //完成任务
- taskService.complete(task1.getId());
- }
-
- //经理审批 (组任务模式 候选人 wangwu和lisi)
- String candidateUserId="wangwu";
- //查询这个候选人待办任务
- Task task3 = taskService.createTaskQuery().processDefinitionKey(key)
- .taskCandidateUser(candidateUserId) //候选人
- //.list() 查询所有待办
- .singleResult();
- System.out.println("任务id"+task3.getId());
- System.out.println("任务负责人"+task3.getAssignee()); //null 因为还没有人拾取任务
- if(task3!=null){
- //拾取该任务
- taskService.claim(task3.getId(),candidateUserId);
- }
- //拾取完可以办理或归还任务
- // taskService.complete(task3.getId()); 完成任务
-
- //归还任务
- taskService.setAssignee(task3.getId(),null); //归还任务就是把负责人设置为null
-
- // 任务的转办(任务交接) :这个任务我做不了,想交给别人做。
- // 候选人王五做不了,转给李四做
- taskService.setAssignee(task3.getId(),"lisi"); //转办任务就是把负责人设置为目标人
- }
排他网关exclusiveGateway: 排他网关只会选择一个为true去执行。都为true 选择id值较小的那条线去执行。 (global变量控制流程)连线上设置分支条件方式: 不符合任何一条条件时,会结束任务 排他网关方式: 不符合任何一条条件时,会抛异常。扔我们知道哪出问题了。
拆分:拆分处,有几个分支就会走几个分支,不会因为连线处有条件而不执行。
聚合:等所有分支都执行完,才能继续往下走。
