activiti7工作流的使用
1、pom.xml
<!-- activiti -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.1.0.M4</version>
</dependency>
2、配置类
package com.demo.activiti.config;
import org.activiti.engine.impl.event.EventSubscriptionPayloadMappingProvider;
import org.activiti.runtime.api.impl.VariablesMappingProvider;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.activiti.spring.boot.DefaultActivityBehaviorFactoryMappingConfigurer;
import org.activiti.spring.process.ProcessVariablesInitiator;
import org.springframework.context.annotation.Configuration;
import java.util.Collections;
@Configuration
public class ActivitiConfiguration extends DefaultActivityBehaviorFactoryMappingConfigurer {
public ActivitiConfiguration(VariablesMappingProvider variablesMappingProvider,
ProcessVariablesInitiator processVariablesInitiator,
EventSubscriptionPayloadMappingProvider eventSubscriptionPayloadMappingProvider) {
super(variablesMappingProvider, processVariablesInitiator, eventSubscriptionPayloadMappingProvider);
}
@Override
public void configure(SpringProcessEngineConfiguration springProcessEngineConfiguration) {
super.configure(springProcessEngineConfiguration);
springProcessEngineConfiguration.setEventListeners(
Collections.singletonList(new ActivitiTaskEventListener()));
}
}
3、工作流介绍
RepositoryService
Activiti 中每一个不同版本的业务流程的定义都需要使用一些定义文件,部署文件和支持数据 ( 例如 BPMN2.0 XML 文件,表单定义文件,流程定义图像文件等 ),这些文件都存储在 Activiti 内建的 Repository 中。Repository Service 提供了对 repository 的存取服务。
RuntimeService
在 Activiti 中,每当一个流程定义被启动一次之后,都会生成一个相应的流程对象实例。Runtime Service 提供了启动流程、查询流程实例、设置获取流程实例变量等功能。此外它还提供了对流程部署,流程定义和流程实例的存取服务。
TaskService
在 Activiti 中业务流程定义中的每一个执行节点被称为一个 Task,对流程中的数据存取,状态变更等操作均需要在 Task 中完成。Task Service 提供了对用户 Task 和 Form 相关的操作。它提供了运行时任务查询、领取、完成、删除以及变量设置等功能。
IdentityService
Activiti 中内置了用户以及组管理的功能,必须使用这些用户和组的信息才能获取到相应的 Task。Identity Service 提供了对 Activiti 系统中的用户和组的管理功能。
ManagementService
Management Service 提供了对 Activiti 流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用,主要用于 Activiti 系统的日常维护。
HistoryService: History Service
用于获取正在运行或已经完成的流程实例的信息,与RuntimeService中获取的流程信息不同,历史信息包含已经持久化存储的永久信息,并已经被针对查询优化。
FormService
Activiti 中的流程和状态 Task 均可以关联业务相关的数据。通过使用FormService可以存取启动和完成任务所需的表单数据并且根据需要来渲染表单。
4、具体使用
4.1开启审批流程
//开启审批流程
@Test
public void start() {
String processKey="demo";//流程图key值
String businessKey="1634113862777905152";//作业的id
Authentication.setAuthenticatedUserId("111");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processKey, businessKey);
System.out.println("ProcessInstanceId:"+processInstance.getProcessInstanceId());
}
4.2获取指定用户待办任务(分页)
String userId="3";
int total=taskService.createTaskQuery().taskAssignee(userId)
.orderByTaskCreateTime().desc().list().size();
int start=(entity.getPageNum()-1)*entity.getPageSize();
List<Task> taskList = taskService.createTaskQuery().taskAssignee(userId)
.orderByTaskCreateTime().desc().listPage(start,entity.getPageSize());
List<Work> list= new ArrayList<>();
for (Task task : taskList) {
//获取流程实例id
String processInstanceId = task.getProcessInstanceId();
//根据processInstanceId查询作业申请信息
Leave leave=leaveService.getByProcessInstanceId(processInstanceId);
//请假信息
if (leave!= null) {
Work work= new Work ();
//任务节点的id,完成节点时需要用到
work.setTaskId(task.getId());
//任务节点的名称
work.setTaskName(task.getName());
//流程实例的id
work.setProcessInstanceId(processInstanceId);
list.add(work);
}
}
4.3完成任务
//完成待办任务(通过)
@Test
public void complete(){
String userId="3";
String taskId="150e9004-c0b6-11ed-8daa-fcaa1464656d";
String processInstanceId="48a330d8-c0a3-11ed-adde-fcaa1464656d";
String remark="同意了,符合规定";
Authentication.setAuthenticatedUserId(userId);
//意见
taskService.addComment(taskId, processInstanceId, remark);
// 设置局部变量,因变量是局部的所以每个连线对应的变量可以重名
taskService.setVariable(taskId,"result",1);
taskService.complete(taskId);
}
//完成待办任务(驳回)
@Test
public void refuse(){
String userId="1";
String taskId="334b844a-bef7-11ed-bb8b-fcaa1464656d";
String processInstanceId="5c637ec9-bef6-11ed-9f67-fcaa1464656d";
String remark="不行,不符合要求";
Authentication.setAuthenticatedUserId(userId);
taskService.addComment(taskId, processInstanceId, remark);
// 设置局部变量,因变量是局部的所以每个连线对应的变量可以重名
taskService.setVariable(taskId,"result",0);
taskService.complete(taskId);
}
//拒绝 删除流程实例
@Test
public void delete(){
String taskId="334b844a-bef7-11ed-bb8b-fcaa1464656d";
String processInstanceId="5c637ec9-bef6-11ed-9f67-fcaa1464656d";
String remark="拒绝";
taskService.addComment(taskId, processInstanceId, remark);
runtimeService.deleteProcessInstance("61110e3e-c177-11ed-920d-fcaa1464656d","删除流程的原因");
}
4.4获取指定用户历史任务(分页)
String userId="3";
int total=historyService.createHistoricTaskInstanceQuery().taskAssignee(userId).finished()
.orderByHistoricTaskInstanceEndTime().desc().list().size();
int start=(entity.getPageNum()-1)*entity.getPageSize();
List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().taskAssignee(userId).finished()
.orderByHistoricTaskInstanceEndTime().desc().listPage(start,entity.getPageSize());
for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
//任务节点id
System.out.println("Id:" + historicTaskInstance.getId());
//任务节点名称
System.out.println("Name:" + historicTaskInstance.getName());
//审批人
System.out.println("Assignee:" + historicTaskInstance.getAssignee());
//流程实例id
System.out.println("ProcessInstanceId:" + historicTaskInstance.getProcessInstanceId());
//任务节点结束时间
System.out.println("EndTime:" + historicTaskInstance.getEndTime());
}
4.5根据processInstanceId获取节点的信息
@Test
public void ActicitiTaskQueryId() {
//根据流程实例id来实现当前用户的任务列表查询
List<org.activiti.engine.task.Task> taskList = taskService.createTaskQuery()
.processInstanceId("4fb0d3a8-bee5-11ed-bd8c-509a4c546546")
.list();
//任务列表展示
for (Task task : taskList) {
System.out.println("流程实例id:" + task.getProcessInstanceId());
System.out.println("任务id:" + task.getId());
System.out.println("任务负责人:" + task.getAssignee());
System.out.println("任务名称:" + task.getName());
}
}
4.6根据processInstanceId已完成(历史)节点的任务名、审批人、审批时间、备注
@Test
public void getInfo() {
String processInstanceId = "8279247e-d08c-11ee-b0bc-fcaa1464656d";
List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().
processInstanceId(processInstanceId).finished().
orderByHistoricTaskInstanceEndTime().asc().list();
for (HistoricTaskInstance historicTaskInstance : list) {
System.out.println("任务id:" + historicTaskInstance.getId());
System.out.println("任务名:" + historicTaskInstance.getName());
System.out.println("节点开始时间:" + historicTaskInstance.getStartTime());
System.out.println("审批时间:" + historicTaskInstance.getEndTime());
System.out.println("审批人:" + historicTaskInstance.getAssignee());
String str = "";
//根据TaskId查询批注
List<Comment> taskComments = taskService.getTaskComments(historicTaskInstance.getId());
for (Comment comment : taskComments) {
str = str + comment.getFullMessage();
}
System.out.println("审批意见:" + str);
}
}
任务id:8297f723-d08c-11ee-b0bc-fcaa1464656d
任务名:人事部
节点开始时间:Wed Feb 21 15:40:40 CST 2024
审批时间:Wed Feb 21 15:41:03 CST 2024
审批人:1
审批意见:同意
任务id:90ad9e08-d08c-11ee-b0bc-fcaa1464656d
任务名:部门组长
节点开始时间:Wed Feb 21 15:41:03 CST 2024
审批时间:Wed Feb 21 15:41:15 CST 2024
审批人:2
审批意见:符合要求
任务id:9797f12f-d08c-11ee-b0bc-fcaa1464656d
任务名:部门主管
节点开始时间:Wed Feb 21 15:41:15 CST 2024
审批时间:Wed Feb 21 15:41:25 CST 2024
审批人:3
审批意见:通过
4.7根据流程id获取各个节点的详细信息
@Autowired
private RepositoryService repositoryService;
@Test
public void getCurrentNextUserTaskAssign() {
//流程定义Id
String processDefId = "processDemo:1:77035473-bcb6-11ed-9347-60ee5c361c52";
//通过流程资源部署类获取BpmnModel
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefId);
//通过BpmnModel获取Process
org.activiti.bpmn.model.Process process = bpmnModel.getProcesses().get(0);
//通过Process获取UserTask信息
List<UserTask> UserTaskList = process.findFlowElementsOfType(UserTask.class);
for (UserTask userTask : UserTaskList) {
String id = userTask.getId(); //流程节点Id
String name = userTask.getName();
String assign = userTask.getAssignee(); //节点任务执行人
System.out.println("流程节点Id:" + id);
System.out.println("节点名称:" + name);
System.out.println("节点任务执行人:" + assign);
}
}
流程节点Id:Activity_0sdlsip
节点名称:人事部
节点任务执行人:1
流程节点Id:Activity_0d3bui8
节点名称:部门组长
节点任务执行人:2
流程节点Id:Activity_1gmido5
节点名称:部门主管
节点任务执行人:3
4.8根据任务节点id获取任务意见
String taskId = "363f2069-be24-11ed-8951-60ee5c361c52";
String str = "";
//根据TaskId查询批注
List<Comment> taskComments = taskService.getTaskComments(taskId);
for (Comment comment : taskComments) {
str = str + comment.getFullMessage();
}
System.out.println("审批意见:" + assign);
List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
.taskId(entity.getTaskId()).finished().list();
System.out.println("审批时间:" + historicTaskInstances.get(0).getEndTime());
System.out.println("审批人:" + historicTaskInstances.get(0).getAssignee());
System.out.println("任务节点名称:" + historicTaskInstances.get(0).getName());
4.9获取流程定义XML
//根据processInstanceId获取流程定义XML
@PostMapping(value = "/getDefinitionXML")
public void getProcessDefineXML(HttpServletResponse response,@RequestBody WorkResp entity) throws IOException {
HistoricProcessInstance historicProcessInstance=historyService.createHistoricProcessInstanceQuery()
.processInstanceId(entity.getProcessInstanceId())
.singleResult();
String deploymentId=historicProcessInstance.getDeploymentId();
String resourceName="CreateWithBPMNJS.bpmn";
processDefinitionService.getProcessDefineXML(response, deploymentId, resourceName);
}
5、 流程监听
package com.demo.activiti.config;
import com.demo.application.entity.WorkApplication;
import com.demo.application.service.WorkApplicationService;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
/**
* 监听流程结束
*
*/
@Component
@Slf4j
public class ActivitiTaskEventListener implements ActivitiEventListener, ApplicationContextAware {
private static WorkApplicationService workApplicationService;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
workApplicationService = applicationContext.getBean(WorkApplicationService .class);
}
@Override
public void onEvent(ActivitiEvent activitiEvent) {
if (!StringUtils.hasText(activitiEvent.getProcessInstanceId())) {
return;
}
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//流程实例
ProcessInstance processInstance = processEngine.getRuntimeService().createProcessInstanceQuery()
.processInstanceId(activitiEvent.getProcessInstanceId()).singleResult();
String businessKey = processInstance.getBusinessKey();
if (processInstance == null) {
return;
}
switch (activitiEvent.getType()) {
//进程完成
case PROCESS_COMPLETED:
//日志信息
log.info("processInstance:" + processInstance + "已完成!");
//更新数据状态
WorkApplication application = workApplicationService.getByNumber(businessKey);
if (application != null) {
application.setApplyStatus(1);//已审批
workApplicationService.updateApplication(application);
}
break;
default:
}
}
@Override
public boolean isFailOnException() {
return false;
}
}
6、删除作业信息(比如删除请假信息)
当我们想要删除请假信息时,要一并删除流程信息
/**
* 批量删除请假
*
* @param ids 需要删除的请假主键
* @return 结果
*/
@Override
public int deleteLeaveapplyByIds(String ids)
{
String[] keys = Convert.toStrArray(ids);
for (String key : keys) {
ProcessInstance process = runtimeService.createProcessInstanceQuery().processDefinitionKey("leave").processInstanceBusinessKey(key).singleResult();
if (process != null) {
runtimeService.deleteProcessInstance(process.getId(), "删除");
}
// 删除历史数据
HistoricProcessInstance history = historyService.createHistoricProcessInstanceQuery().processDefinitionKey("leave").processInstanceBusinessKey(key).singleResult();
if (history != null){
historyService.deleteHistoricProcessInstance(history.getId());
}
leaveapplyMapper.deleteLeaveapplyById(Long.parseLong(key));
}
return keys.length;
}
7、清除库数据(参考网上)
mysql 清理数据库
-- 取消外键约束
SET FOREIGN_KEY_CHECKS=0;
DELETE FROM ACT_RU_IDENTITYLINK ; -- 删除运行状态的
DELETE FROM ACT_RU_TASK ; -- 删除任务
DELETE FROM ACT_RU_VARIABLE; -- 删除运行 遍历
DELETE FROM ACT_RU_EXECUTION ; -- 删除执行的数据
-- 删除历史数据
DELETE FROM ACT_HI_VARINST ; -- 历史变量
DELETE FROM ACT_HI_TASKINST ; -- 历史 任务 实例
DELETE FROM ACT_HI_PROCINST ; -- 历史 执行流程实例 ;
DELETE FROM ACT_HI_IDENTITYLINK; -- 历史 身份 链接
DELETE FROM ACT_HI_DETAIL ; -- 详情
DELETE FROM ACT_HI_ACTINST ; -- 流程 实例
DELETE FROM ACT_HI_COMMENT ; -- 提交备注
-- 启用外键约束
SET FOREIGN_KEY_CHECKS=1;
-- 删除历史数据
DELETE FROM `act_hi_varinst` ; -- 历史变量
DELETE FROM `act_hi_taskinst` ; -- 历史 任务 实例
DELETE FROM `act_hi_procinst` ; -- 历史 执行流程实例 ;
DELETE FROM `act_hi_identitylink`; -- 历史 身份 链接
DELETE FROM `act_hi_detail` ; -- 详情
DELETE FROM `act_hi_actinst` ; -- 流程 实例
DELETE FROM `act_hi_comment` ; -- 提交备注
DELETE FROM act_hi_taskinst
DELETE FROM act_ru_identitylink
DELETE FROM act_ru_task
DELETE FROM act_hi_identitylink
DELETE FROM act_hi_procinst
DELETE FROM act_hi_varinst
DELETE FROM act_ru_variable
DELETE FROM act_ru_execution
8、参考文章
万字解析Activiti7流程框架(一),这位作者写的非常详细,强烈推荐。
关于网关的学习,可以参考这篇文章【activiti】网关。