Activity
0.使用步骤
## SpringBoot整合Activity(启动项目会动态的创建数据库表)
## 创建流程定义(bpmn流程图,并保存成图片)
## 流程定义部署(将流程定义加载到数据库中)
## 创建流程实例(某某人需要使用流程了)
## 查询代办任务(任务负责人查询自己的代办任务)
## 任务审批
流程变量: UEL表达式定义
${变量名称}
网关:
X 排他网关
➕ 并行网关
O 包含网关(相当于排他+并行)
事件网关
1.SpringBoot整合Activity
如果是mysql8需要修改jar版本和配置信息
1.pom依赖
<!-- springboot父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- web依赖springmvc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!--mysql数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--activiti 工作流的依赖-->
<!-- activiti-engine -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.1.0.M6</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>7.1.0.M6</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-image-generator</artifactId>
<version>5.19.0.2</version>
</dependency>
</dependencies>
2.添加配置文件
application-activity.yml
spring:
datasource:
url:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
activiti:
#1.flase:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
#2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
#3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
#4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
database-schema-update: true
#检测历史表是否存在 activiti7默认没有开启数据库历史记录 启动数据库历史记录
db-history-used: true
#记录历史等级 可配置的历史级别有none, activity, audit, full
#none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。
#activity:级别高于none,保存流程实例与流程行为,其他数据不保存。
#audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。
#full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。
history-level: full
#校验流程文件,默认校验resources下的processes文件夹里的流程文件
check-process-definitions: false
#默认采用UUID作为主键, 设置为false, 将采用整型主键
use-strong-uuids: false
logging:
level:
org.activiti.engine.impl.persistence.entity: trace
mybatis:
mapper-locations: classpath:mappers/*.xml
type-aliases-package: com.xushuai.activiti.pojo
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3.添加配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
public class UserConfiguration {
@Bean
public UserDetailsService myUserDetailsService() {
InMemoryUserDetailsManager inMemoryUserDetailsManager = new
InMemoryUserDetailsManager();
inMemoryUserDetailsManager.createUser(User.withUsername("xushuai")
.password("$2a$10$yRkoWX3dbPF8TX4KhB9kC.C4XiOJ4ThD/YQoersDtZjzJUYp4Rs7a")
.authorities("ROLE_ACTIVITI_USER", "GROUP_activitiTeam").build());
return inMemoryUserDetailsManager;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
4.创建对应的数据库
项目启动时会自动创建表,但是不会自动创建数据库,所以需要提前手动创建数据库
5.编写引导类启动项目
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ActivitiDemoApp {
public static void main(String[] args) {
SpringApplication.run(ActivitiDemoApp.class,args);
}
}
6.对象使用
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
private HistoryService historyService;
2.创建流程定义
(bpmn流程图,并保存成图片)
在idea中安装activity插件
绘制流程定义
将定义好的流程保存成图片
3.流程定义部署
(将流程定义加载到数据库中)
package com.baidu.controller;
import com.baidu.domain.ActivitiVo;
import org.activiti.bpmn.model.BpmnModel;
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.HistoricTaskInstance;
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.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: 小许好楠
* @name:QingJiaCpntroller
* @Date:2024/7/30 20:10
*/
@Controller
@RequestMapping("/qingjia3")
public class QingJia3Cpntroller {
// todo:仓库服务对象: 操作流程定义
@Autowired
private RepositoryService repositoryService;
// todo:运行时服务对象: 操作流程实例
@Autowired
private RuntimeService runtimeService;
// todo:任务服务对象: 流程实例中的任务处理
@Autowired
private TaskService taskService;
// todo:历史服务对象: 操作流程实例处理完毕后的历史
@Autowired
private HistoryService historyService;
// todo:1.部署流程定义
@RequestMapping("/deploy")
@ResponseBody
public String deploy(){
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("activiti/qingjia3.bpmn20.xml") //添加bpmn资源
.addClasspathResource("activiti/qingjia3.png")
.name("请假申请单流程3")
.deploy();
//4.输出部署的一些信息
System.out.println(deployment.getName());
System.out.println(deployment.getId());
System.out.println(deployment.getKey());
return "Success";
}
@RequestMapping("/show/{name}")
@ResponseBody
public String show(@PathVariable("name")String name){
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//4.设置条件,并查询出当前的所有流程定义 查询条件:流程定义的key=holiday
//orderByProcessDefinitionVersion() 设置排序方式,根据流程定义的版本号进行排序
List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey(name)
.orderByProcessDefinitionVersion()
.desc().list();
//5.输出流程定义信息
for(ProcessDefinition processDefinition :list){
System.out.println("流程定义ID:"+processDefinition.getId());
System.out.println("流程定义名称:"+processDefinition.getName());
System.out.println("流程定义的Key:"+processDefinition.getKey());
System.out.println("流程定义的版本号:"+processDefinition.getVersion());
System.out.println("流程部署的ID:"+processDefinition.getDeploymentId());
}
return "Success";
}
}
4.创建流程实例
(某某人需要使用流程了)
package com.baidu.controller;
import com.baidu.domain.ActivitiVo;
import org.activiti.bpmn.model.BpmnModel;
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.HistoricTaskInstance;
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.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: 小许好楠
* @name:QingJiaCpntroller
* @Date:2024/7/30 20:10
*/
@Controller
@RequestMapping("/qingjia3")
public class QingJia3Cpntroller {
// todo:仓库服务对象: 操作流程定义
@Autowired
private RepositoryService repositoryService;
// todo:运行时服务对象: 操作流程实例
@Autowired
private RuntimeService runtimeService;
// todo:任务服务对象: 流程实例中的任务处理
@Autowired
private TaskService taskService;
// todo:历史服务对象: 操作流程实例处理完毕后的历史
@Autowired
private HistoryService historyService;
// @RequestMapping("/create/{userid}/{num}")
// public String createInstance(@PathVariable("userid")String userid,@PathVariable("num")Integer num){
// // 业务处理,根据用户id查询用户详情,查询当前用户的经理
// // 根据用户id查询人事信息
// return "Success";
// }
@RequestMapping("/create/{name}/{num}/{manager}/{renshi}")
@ResponseBody
public String createInstance(@PathVariable("name")String name,
@PathVariable("num")Integer num,
@PathVariable("manager")String manager,
@PathVariable("renshi")String renshi
){
// 创建map集合用于存放流程变量
HashMap<String, Object> map = new HashMap<>();
map.put("manager",manager);
map.put("renshi",renshi);
map.put("num",num);
//3.创建流程实例 流程定义的key需要知道 holiday
// 创建流程实例,并设置业务key
ProcessInstance processInstance =
runtimeService.startProcessInstanceByKey("qingjia3",name,map);
//4.输出实例的相关信息
System.out.println("流程部署ID: "+processInstance.getDeploymentId());//null
System.out.println("流程定义ID: "+processInstance.getProcessDefinitionId());//holiday7:1:4
System.out.println("流程实例ID: "+processInstance.getId());//2501
System.out.println("活动ID: "+processInstance.getActivityId());//null
System.out.println("获取业务key: "+processInstance.getBusinessKey());//
return "Success";
}
}
5.查询代办任务
(任务负责人查询自己的代办任务)
package com.baidu.controller;
import com.baidu.domain.ActivitiVo;
import org.activiti.bpmn.model.BpmnModel;
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.HistoricTaskInstance;
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.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: 小许好楠
* @name:QingJiaCpntroller
* @Date:2024/7/30 20:10
*/
@Controller
@RequestMapping("/qingjia3")
public class QingJia3Cpntroller {
// todo:仓库服务对象: 操作流程定义
@Autowired
private RepositoryService repositoryService;
// todo:运行时服务对象: 操作流程实例
@Autowired
private RuntimeService runtimeService;
// todo:任务服务对象: 流程实例中的任务处理
@Autowired
private TaskService taskService;
// todo:历史服务对象: 操作流程实例处理完毕后的历史
@Autowired
private HistoryService historyService;
@RequestMapping("/queryByName")
@ResponseBody
public List<Map<String,Object>> queryByName(ActivitiVo vo){
//根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey(vo.getDefinitionKey())
.taskAssignee(vo.getAssignee())
// .taskCandidateOrAssigned("aa")
// .taskCandidateOrAssigned("damimi")
.list();
List<Map<String,Object>> list = new ArrayList<>();
//任务列表的展示
for(Task task :taskList){
Map<String,Object> map = new HashMap<>();
map.put("instanceId",task.getProcessInstanceId());
map.put("taskId",task.getId());
map.put("assignee",task.getAssignee());
map.put("taskName",task.getName());
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("任务ID:"+task.getId());
System.out.println("任务负责人:"+task.getAssignee());
System.out.println("任务名称:"+task.getName());
System.out.println("--------------------");
list.add(map);
}
return list;
}
}
6.任务审批
package com.baidu.controller;
import com.baidu.domain.ActivitiVo;
import org.activiti.bpmn.model.BpmnModel;
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.HistoricTaskInstance;
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.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: 小许好楠
* @name:QingJiaCpntroller
* @Date:2024/7/30 20:10
*/
@Controller
@RequestMapping("/qingjia3")
public class QingJia3Cpntroller {
// todo:仓库服务对象: 操作流程定义
@Autowired
private RepositoryService repositoryService;
// todo:运行时服务对象: 操作流程实例
@Autowired
private RuntimeService runtimeService;
// todo:任务服务对象: 流程实例中的任务处理
@Autowired
private TaskService taskService;
// todo:历史服务对象: 操作流程实例处理完毕后的历史
@Autowired
private HistoryService historyService;
@RequestMapping("/complete")
@ResponseBody
public String complete(ActivitiVo vo){
taskService.complete(vo.getTaskId());
//5.输出任务的id
System.out.println(vo.getTaskId());
return "success";
}
}
7.查询流程进度
package com.baidu.controller;
import com.baidu.domain.ActivitiVo;
import org.activiti.bpmn.model.BpmnModel;
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.HistoricTaskInstance;
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.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: 小许好楠
* @name:QingJiaCpntroller
* @Date:2024/7/30 20:10
*/
@Controller
@RequestMapping("/qingjia3")
public class QingJia3Cpntroller {
// todo:仓库服务对象: 操作流程定义
@Autowired
private RepositoryService repositoryService;
// todo:运行时服务对象: 操作流程实例
@Autowired
private RuntimeService runtimeService;
// todo:任务服务对象: 流程实例中的任务处理
@Autowired
private TaskService taskService;
// todo:历史服务对象: 操作流程实例处理完毕后的历史
@Autowired
private HistoryService historyService;
@GetMapping("/img")
public void lookCurrentProcessImage(HttpServletResponse response, String taskId) throws Exception {
HistoricTaskInstance task = historyService// 与历史数据(历史表)相关的Service
.createHistoricTaskInstanceQuery()// 创建历史任务实例查询
.taskId(taskId)// 指定历史任务的办理人
.singleResult();
// 流程定义
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
ProcessDiagramGenerator ge = new DefaultProcessDiagramGenerator();
InputStream imageStream = ge.generateDiagram(bpmnModel, "png",
runtimeService.getActiveActivityIds(task.getExecutionId()),
new ArrayList<String>(), "宋体", "宋体", null, 1.0d);
byte[] b = new byte[1024];
int len;
while ((len = imageStream.read(b, 0, 1024)) != -1) {
response.getOutputStream().write(b, 0, len);
}
}
}