activti相关介绍 参考
springBoot项目搭建 参考
1. 引入依赖
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.0.0.Beta2</version>
</dependency>
2. 配置 application.yml
spring:
activiti:
#1.flase: 默认值。activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
#2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
#3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
#4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
database-schema-update: true
#检测历史表是否存在
db-history-used: true
#记录历史等级 可配置的历史级别有none, activity, audit, full
history-level: full
#校验流程文件,默认校验resources下的processes文件夹里的流程文件
check-process-definitions: false
3. 启动项目
首次启动项目会自动创建activiti相关的表
项目启动报错 java.sql.SQLSyntaxErrorException: Table 'springboot.act_ge_property' doesn't...
---- 表不存在而没有去创建?
原因:
出现这种问题的原因是mysql版本问题,mysql8.xxx以上驱动会出现这个问题
因为mysql使用schema标识库名而不是catalog,因此mysql会扫描所有的库来找表,如果其他库中有相同名称的表,activiti就以为找到了,本质上这个表在当前数据库中并不存在。
设置nullCatalogMeansCurrent=true,表示mysql默认当前数据库操作,在mysql-connector-java 5.xxx该参数默认为true,在6.xxx以上默认为false,因此需要设置nullCatalogMeansCurrent=true。
解决:配置mysql连接时加上:nullCatalogMeansCurrent=true
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC&nullCatalogMeansCurrent=true
创建bpmn(业务流程建模与标注)
这里使用的是IDEA的bpmn插件,当然也可以通过其他方式创建bpmn
- 右键新建BpmnFile
这是一个简单的请假的流程,bpmn路径如图:
编写测试用例
package com.boo.activoti;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.persistence.entity.VariableInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** activiti测试类
* description: ActivitiApplicationTests <br>
* date: 2021/3/24 11:28 <br>
* author: boo <br>
* version: 1.0 <br>
*/
@SpringBootTest
@Slf4j
public class ActivitiApplicationTests {
/** 流程引擎 */
@Autowired
private ProcessEngine processEngine;
/** activiti内置服务 帮助我们实现流程定义的部署。此服务会处理与流程定义相关的静态数据。 */
@Autowired
private RepositoryService repositoryService;
/** activiti内置服务 管理 ProcessInstances(当前正在运行的流程)以及流程变量 */
@Autowired
private RuntimeService runtimeService;
/** activiti内置服务 会跟踪 UserTasks,可以使用此服务创建任务,声明并完成任务,分配任务的受让人等。 */
@Autowired
private TaskService taskService;
/**
* 1. 部署流程定义
*/
// @Test
public void createDeploy() {
// 通过流程引擎的方式获取内部服务
// RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("bpmn/leave.bpmn")//添加bpmn资源
.name("请假申请单流程") // 流程定义名称
.key("myProcess_leave") // 流程定义名称key
.deploy(); // 部署
log.info("流程部署id:" + deployment.getId());
log.info("流程部署名称:" + deployment.getName());
}
/** 功能描述: 1.1 查询部署流程定义
* @Author: boo
*/
@Test
public void selectDeploy() {
// 删除流程定义
// repositoryService.deleteDeployment("d453faf4-8c5e-11eb-baf1-b42e99226260");
List<Deployment> deployments =
repositoryService.createDeploymentQuery() // 流程定义查询
.list(); // 流程定义列表
deployments.forEach(deployment ->{
System.out.println("name: " + deployment.getName()); // 请假申请单流程
System.out.println("id: " + deployment.getId()); // 97f43dfe-8c5f-11eb-92a5-b42e99226260
System.out.println("key: " + deployment.getKey()); // myProcess_leave
});
}
/** 功能描述: 2. 启动流程 (创建流程实例)
* @Author: boo
*/
// @Test
public void startProcess() {
// 使用流程定义的key启动 流程实例
ProcessInstance processInstance =
runtimeService.startProcessInstanceByKey("myProcess_leave");
log.info("流程实例ID:" + processInstance.getId());
log.info("流程定义ID:" + processInstance.getProcessDefinitionId());
}
/** 功能描述: 2.1. 查询流程实例
* @Author: boo
*/
@Test
public void selectProcessInstance() {
// 使用流程定义的key启动 流程实例
List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery() // 流程实例查询
.list(); // 查询列表
processInstances.forEach(processInstance -> {
log.info("流程实例ID:" + processInstance.getId());
log.info("流程定义ID:" + processInstance.getProcessDefinitionId());
});
}
/** 功能描述: 3 提交任务 (学生提交请假申请)
* @Author: boo
*/
@Test
public void completeTaskByUser() {
String assignee = "user"; // 代理人
List<Task> tasks = taskService.createTaskQuery() // 查询任务
.taskAssignee(assignee) // 通过任务代理人筛选
.orderByTaskCreateTime().asc() // 按照创建时间升序排列
.list();
tasks.forEach(task -> {
log.info("任务名称:" + task.getName()); // 请假
log.info("任务代理人:" + task.getAssignee()); // user
log.info("任务id:" + task.getId()); // dd9db03e-8c60-11eb-ba97-b42e99226260
// 代理人完成任务
if (assignee.equals(task.getAssignee())){
// 设置任务参数
// taskService.setVariable(taskId, "cause","肚子不舒服");
Map<String, Object> map = new HashMap<>(); // 设置参数
map.put("cause","肚子不舒服"); // 请假原因
map.put("days",1); // 请假时长
taskService.complete(task.getId(),map); // 完成任务并提交数据
}
});
}
/** 功能描述: 3.1 提交任务 (老师审批请假申请)
* @Author: boo
*/
@Test
public void completeTaskByAdmin() {
String assignee = "admin"; // 代理人
List<Task> tasks = taskService.createTaskQuery() // 查询任务
.taskAssignee(assignee) // 通过任务代理人筛选
.orderByTaskCreateTime().asc() // 按照创建时间升序排列
.list();
tasks.forEach(task -> {
log.info("任务名称:" + task.getName()); // 请假
log.info("任务代理人:" + task.getAssignee()); // user
log.info("任务id:" + task.getId()); // dd9db03e-8c60-11eb-ba97-b42e99226260
// 代理人完成任务
if (assignee.equals(task.getAssignee())){
// 获取参数
Map<String, VariableInstance> variableInstanceMap = taskService.getVariableInstances(task.getId());
// variableInstanceMap.keySet().forEach(key -> {
// VariableInstance var = variableInstanceMap.get(key);
// System.out.println(key + ": " + var.getName() + ": " + var.getValue());
// });
Map<String, Object> map = new HashMap<>(); // 设置参数
map.put("applyOK",0); // 驳回申请
try {
if ((int) variableInstanceMap.get("days").getValue() < 2) {
map.put("applyOK",1); // 同意申请 流程结束
}
}catch (Exception e){
}
taskService.complete(task.getId(),map); // 完成任务并提交数据
}
});
}
}