什么是工作流
1.使用编程语言完成一套固定的审批流程
例如请假审批流程
订单配送流程
入职,辞职审批流程
2.使用场景
业务类:合同审批流程、订单处理流程、出入库审批流程等。
行政类:请假流程、出差流程、用车流程、办公用品申请流程等。
财务类:报销流程、支付流程等。
客户服务类:售后跟踪、客户投诉等。
常见软件
-
尤其在OA,ERP,CRM软件中使用较多
-
OA
-
办公自动化(Office Automation)
-
-
ERP
-
企业资源计划即 ERP (Enterprise Resource Planning)
-
-
CRM
-
客户关系管理(Customer Relationship Management)
-
-
工作流中的核心三要素
-
流程名称
-
流程绑定业务id
-
各流程负责人
官网(https://www.activiti.org/)
activiti
-
Activiti 是一个开源的工作流引擎,它实现了BPMN 2.0规范,可以发布设计好的流程定义,并通过api进行流程调度
-
BPM,Business Process Management 即业务流程管理) 的创建者 Tom Baeyens 离开 JBoss 之后建立的项目
-
BPMN 2.0其实也是一种类似于xml和html的一种标记语言,就是使用bpmn的规范来定义画流程图,最终形成一个bpmn文件
Springboot集成Activiti
1.父工程pom下添加
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.1.0.M6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2.注意: activiti7与spring security 强耦合因此两个依赖 必须都得引入
3.yml中spring节点下增加配置
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
activiti:
#是否让activiti自动创建所有的历史表
history-level: full
#是否需要使用历史表,默认false不使用,而配置true是使用历史表
db-history-used: true
#流程自动部署,关闭,需要手动部署流程 服务启动的时候自动检查resources目录下的bpmn文件 如果为true自动部署流程
check-process-definitions: false
#关闭启动服务自动框架部署
deployment-mode: never-fail
4.集成好之后activiti会自动 再项目连接的MySQL数据库下创建25张表
Activiti开发流程
1.画流程图模型
遵守BPMN的流程规范,使用BPMN的流程定义工具,通过 流程符号 把整个业务流程定义出来,将流程定义文件字节流保存到模型数据表中(Model)。每一个流程图都是一个.bpmn文件
2.部署流程定义
加载画好的流程定义文件,将它转换成流程定义数据(ProcessDefifinition),保存到流程定义数据表中
3.启动流程
生成流程实例数据(ProcessInstance),生成第1个节点的任务数据(Task)
4.处理人审批流程节点任务
完成任务审批,生成审批结果,生成下一节点任务数据。直至满足条件,流程走到结束节点。
流程图模型中的各种符号
1.事件event符号
-
开始事件(Start Event):表示流程的起点,通常用于触发流程的启动。
-
中间事件(Intermediate Event):发生在流程中间的事件,可以根据需要划分为多种类型,如定时器事件、消息事件、信号事件等。
-
结束事件(End Event):表示流程的结束点,通常用于触发流程的结束。
2.活动activity符号
-
任务(Task)是最基本的活动类型,表示一个简单的、可执行的工作单元
-
常见符号
-
1. 用户任务(User Task):表示需要由具体用户来执行的任务。在流程中,当流程执行到用户任务节点时,会生成一个待办任务,需要指定具体的执行人来完成任务。
-
2. 服务任务(Service Task):通过调用外部服务或执行业务逻辑来完成任务的一种任务类型。可以调用Java类、Web服务、REST接口等来执行具体的任务操作。
-
3. 接收任务(Receive Task):表示等待外部触发的任务,当接收到外部的信号或消息时,流程会继续执行下一步。可以用于等待外部系统的通知或事件触发。
-
4. 发送任务(Send Task):表示发送消息或触发事件的任务类型。可以发送消息给外部系统或触发特定的事件,用于与外部系统进行交互。
-
5. 业务规则任务(Business Rule Task):表示执行业务规则来完成任务的一种任务类型。可以通过规则引擎执行事先定义好的业务规则,用于根据特定条件做出决策。
-
3.网关Gateway符号
-
用于处理流程中的决策
-
1. 排他网关(Exclusive Gateway):也称为XOR网关或基于数据的排他网关,用于在流程中创建决策点。当执行到达排他网关时,所有出口顺序流会按照它们定义的顺序进行计算。条件计算为true的顺序流会被选择用于继续流程。
-
相当于if-else只走一个分支
-
-
2. 包容网关(Inclusive Gateway):也称为AND网关或包容性决策网关,用于在流程中创建平行的路径。当执行到达包容网关时,所有出口顺序流同时进行计算,并且至少要有一个条件计算为true的顺序流被选择用于继续流程。
-
只需要满足一个条件
-
-
3. 综合网关(Complex Gateway):用于模拟复杂的同步行为。通过表达式激活条件描述精确的行为。
-
4. 基于事件的网关(Event-based Gateway):基于事件的网关代表流程中的一个分支点,其中遵循网关的替代路径基于发生的事件,而不是使用流程数据对表达式的评估。
-
5. 并行网关(Parallel Gateway):用于同步(组合)并行流并创建并行流。
具体流程
1.部署流程
把xml文件和图片写入到数据库当中
Java类
RepositoryService
创建部署
createDeployment
删除部署
deleteDeployment
涉及表
ACT_RE_PROCDEF 新增数据: 流程定义数据
ACT_RE_DEPLOYMENT 新增数据: 流程部署数据
ACT_GE_BYTEARRAY 新增数据:将当前流程图绑定到此流程定义部署数据上
ACT_RE_MODEL 更新部署id
2.启动流程
读取部署好到表中的流程数据开启流程,创建流程审批模板实例
Java类
RuntimeService
startProcessInstanceByKey(String processDefinitionKey, String businessKey)
参数:
部署好的流程名称选模板
唯一业务主键
涉及到的表
● act_hi_actinst 流程实例执行历史
● act_hi_identitylink 流程的参与用户历史信息
● act_hi_procinst 流程实例历史信息
● act_hi_taskinst 流程任务历史信息
● act_ru_execution 流程执行信息
● act_ru_identitylink 流程的参与用户信息
● act_ru_task 任务信息
3.操作流程
Java类
TaskService
负责人查询待办任务
TaskService
查询单条代办查询
singleResult
查询全部代办任务
list
分页查询代办任务
listPage
条件查询
根据流程名称查询
processDefinitionKey
根据负责人查询
taskAssignee
根据流程绑定业务id查询
processInstanceBusinessKey
模糊查询
方法中带like
精确查询
方法中带equals
范围查询
方法中带after,before,group,in,between等
完成
TaskSercive
complete(String taskId, Map<String,Object> variables, boolean localScope)
可结束当前节点流程,标记为已完成,并且流程会自动开启下一个节点的任务。同时在结束时还可以把填写的数据,作为流程变量传递到下一个流程中
参数
任务id
携带变量
是否为全局变量,是则为全流程可见
拒绝
RuntimeService
deleteProcessInstance(String processInstanceId, String deleteReason);
TaskSercive
deleteTask
查询历史
HistoryService
processInstanceBusinessKey(String processInstanceBusinessKey)
taskId(String taskId)
taskAssignee(String taskAssignee) | taskAssigneeLike(String taskAssignee)
finished()
unfinished()
orderByHistoricTaskInstanceEndTime().desc()
taskName(String var1) | taskNameLike(String var1)
includeProcessVariables()
processVariableValueEquals(String variableName, Object variableValue)
processVariableValueNotEquals(String variableName, Object variableValue)
processVariableValueGreaterThan(String name, Object value)
processVariableValueLessThan(String name, Object value)
createHistoricTaskInstanceQuery
list()
业务流程梳理
1.在web包resources下新建bpmn目录
看看自己是否装了这个插件
新建bpmn.xml文件
2.右击通过你安装的插件中打开
3.开始画流程图
根据判断执行走向
4.创建完成导出png图片
5.流程测试创建
package com.zzyl;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@SpringBootTest
public class TestActiviti {
@Resource
private RepositoryService repositoryService;
@Resource
private RuntimeService runtimeService;
@Resource
private TaskService taskService;
@Resource
private HistoryService historyService;
@Test
public void create() {
//1.创建部署对象
//2.读取要存在mysql中的bpmn文件和图片
//3.部署
repositoryService.createDeployment()
.addClasspathResource("bpmn/学生请假流程.bpmn20.xml")
.addClasspathResource("bpmn/diagram.png")
//name一般和bpmn文件名称一样
.name("学生请假流程")
.deploy();
}
@Test
public void delete() {
//级联删除所有关联 表数据
repositoryService.deleteDeployment("63f13c79-9407-11ee-adad-f0d7afd01b33",true);
}
@Test
public void startProcess() {
runtimeService.startProcessInstanceByKey("学生请假流程", "123455");
}
@Test
public void queryRuntimeProcess() {
List<Task> list = taskService.createTaskQuery().taskAssignee("张三")
.list();
list.forEach(v -> {
log.info("获取任务执行的id:{}", v.getId());
log.info("获取代办人:{}", v.getAssignee());
log.info("获取业务id:{}", v.getBusinessKey());
});
}
@Test
public void completeApplicationTable() {
//填写申请表并且完成申请表的代办
HashMap<String, Object> map = new HashMap<>();
map.put("username", "张三");
map.put("reason", "中秋节回家吃月饼");
map.put("startTime", "2024-09-09");
map.put("endTime", "2024-09-20");
map.put("days", 5);
taskService.complete("3ba73dde-7279-11ef-8e5d-62df74cf4810",map,true);
}
@Test
public void processNextComplete() {
Task task = taskService.createTaskQuery().taskAssignee("l").singleResult();
//获取任务节点传递的变量
Map<String, Object> variables = taskService.getVariables(task.getId());
log.info("代办任务id={}申请内容={}代办人={}", task.getId(), variables, task.getAssignee());
//同意
HashMap<String, Object> okReason = new HashMap<>();
okReason.put("reason", "同意");
okReason.put("remark", "但是课要补回来");
taskService.complete(task.getId(), okReason, true);
// HashMap<String, Object> map = new HashMap<>();
// map.put("reason","拒绝");
// map.put("remark","项目周期长不能让你猖狂");
//
// runtimeService.deleteProcessInstance(task.getProcessInstanceId(),"请假时间过长");
}
@Test
public void queryHistoryProcess() {
List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
.finished().list();
list.forEach(v -> {
log.info("获取业务id={},获取流程名称={},获取流程开始时间={},获取流程结束时间={},拒绝原因={}",
v.getBusinessKey(), v.getProcessDefinitionName(),v.getStartTime(),v.getEndTime(),v.getDeleteReason());
});
}
@Test//查询全部部署信息
public void listDeployments() {
List<Deployment> deployments = repositoryService.createDeploymentQuery().list();
for (Deployment deployment : deployments) {
System.out.println("Deployment ID: " + deployment.getId());
System.out.println("Deployment Name: " + deployment.getName());
}
}
}
6.四个DI注入的作用
在 Activiti 中,
RepositoryService
、RuntimeService
、TaskService
和HistoryService
是四个核心服务接口,分别用于不同的操作和功能。下面是它们的作用和常见用途:1.
RepositoryService
作用: 负责管理流程定义和部署相关的操作。
常见方法:
- 部署流程:
createDeployment()
、deploy()
— 部署新的流程定义。- 删除部署:
deleteDeployment(deploymentId, cascade)
— 删除指定的部署,cascade
参数决定是否级联删除相关数据。- 查询流程定义:
createProcessDefinitionQuery()
— 查询流程定义的列表或特定定义。- 获取流程定义资源:
getProcessDiagram()
— 获取流程图的资源。使用场景:
- 部署新的流程定义到引擎中。
- 查询、删除已部署的流程定义。
- 更新和管理流程模型。
2.
RuntimeService
作用: 负责管理正在运行的流程实例和任务相关的操作。
常见方法:
- 启动流程实例:
startProcessInstanceByKey(processDefinitionKey, businessKey)
— 启动新的流程实例。- 获取流程实例:
createProcessInstanceQuery()
— 查询正在运行的流程实例。- 删除流程实例:
deleteProcessInstance(processInstanceId, reason)
— 删除正在运行的流程实例。使用场景:
- 启动新的流程实例以执行业务流程。
- 查询和管理正在运行的流程实例。
- 结束或取消正在运行的流程实例。
3.
TaskService
作用: 负责管理任务的操作,主要涉及任务的创建、查询、分配和完成。
常见方法:
- 创建任务查询:
createTaskQuery()
— 查询任务的列表或特定任务。- 完成任务:
complete(taskId, variables)
— 完成指定的任务,并可传递流程变量。- 分配任务:
setAssignee(taskId, userId)
— 为任务指定处理人。使用场景:
- 查询当前待办任务和处理任务。
- 完成任务并更新流程变量。
- 分配和重新分配任务。
4.
HistoryService
作用: 负责管理历史数据和流程实例的历史记录。
常见方法:
- 查询历史流程实例:
createHistoricProcessInstanceQuery()
— 查询已完成的流程实例。- 查询历史任务:
createHistoricTaskInstanceQuery()
— 查询已完成的任务历史记录。- 获取历史数据:
getHistoricVariableInstance(variableId)
— 获取历史变量的值。使用场景:
- 查询和分析已完成的流程实例和任务。
- 获取流程执行的历史数据和相关信息。
- 监控和审计业务流程的历史记录。
总结
RepositoryService
: 用于部署、管理和删除流程定义及相关资源。RuntimeService
: 用于启动、查询和管理正在运行的流程实例。TaskService
: 用于处理任务,包括创建查询、完成任务和任务分配。HistoryService
: 用于查询和管理流程实例和任务的历史记录。这些服务接口共同帮助你在 Activiti 引擎中完成从流程定义、运行到历史记录的全面管理。