如何利用SpringBoot+Activiti工作流引擎实现请假审批流程?

Activiti是由Alfresco发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。Activiti基于Apache许可的开源BPM平台,创始人Tom Baeyens是JBoss jBPM的项目架构师,它特色是提供了eclipse插件,开发人员可以通过插件直接绘画出业务流程图。bliblibli...

概念啥的就不扯了,网上大把资料.话不多说,直接切入正题,预完成一个员工请假流程,1天部门经理审核,3天以内(含3天)副总审核,3天到7天(含7天)总经理审核,7天以上其他渠道审核.

如何利用SpringBoot+Activiti工作流引擎实现请假审批流程?

  1. demo结构图如上图所示,springboot+maven项目,整合Activiti6.0,pom依赖如下图所示:
 org.springframework.boot
 spring-boot-starter-parent
 2.1.5.RELEASE
   

cn.dale
activiti-demo
1.0-SNAPSHOT

 1.8
 UTF-8


 
 org.springframework.boot
 spring-boot-starter-jdbc
 
 
 org.mybatis.spring.boot
 mybatis-spring-boot-starter
 2.0.1
 
 
 org.springframework.boot
 spring-boot-starter-web
 
 
 mysql
 mysql-connector-java
 runtime
 
 
 org.springframework.boot
 spring-boot-starter-test
 test
 
 
 com.alibaba
 druid
 1.1.10
 
 
 org.activiti
 activiti-spring-boot-starter-basic
 6.0.0
 
 
 org.slf4j
 slf4j-api
 1.7.21
 
 
 org.slf4j
 slf4j-log4j12
 1.7.21
 



 
 
 org.springframework.boot
 spring-boot-maven-plugin
 
 

Activiti6.0已经整合到springboot了,所以上手起来顺畅的多.

  1. 在application.properties文件中做些许配置:
##spring database configuration
spring.datasource.url=jdbc:mysql://172.10.3.150:3306/activiti?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=Mysql_108
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#activiti
#自动检查、部署流程定义文件
spring.activiti.check-process-definitions=true
#自动更新数据库结构
spring.activiti.database-schema-update=true
#流程定义文件存放目录
spring.activiti.process-definition-location-prefix=classpath:/processes/
  1. 接下来运行一段代码,生成工作流所需的表,你得先在数据库里建好数据库activiti:
package cn.dale.activitidemo;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;

/**
 * @Author: dale
 * @Date: 2019/11/5 17:26
 */
public class ActivitiTable {
 public static void main(String[] args) {
 // 引擎配置
 ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
 .setJdbcUrl("jdbc:mysql://172.10.3.150:3306/activiti?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull")
 .setJdbcUsername("root")
 .setJdbcPassword("Mysql_108")
 .setJdbcDriver("com.mysql.jdbc.Driver")
 .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
 // 获取流程引擎对象
 ProcessEngine processEngine = cfg.buildProcessEngine();
 }
}
  1. run main()方法,表就建好了,接下来在idea添加一个叫actiBPM的插件,直接下载安装就好了,重启idea;
如何利用SpringBoot+Activiti工作流引擎实现请假审批流程?

  1. 在resources目录下新建process目录,右键新建bpmn文件—>leave_process.bpmn,通过拖拽右边的图形元素绘图,将鼠标停留在元素中部,出现黑点后可以画连线.
如何利用SpringBoot+Activiti工作流引擎实现请假审批流程?

  1. 画图时要注意id不能重复,Name要想好怎么命名,一个项目会有很多图形元素需要命名,一定要起名有规律,后面要用到的.哪个红色中间带个×的叫排他网关,达到某种条件才能进入这个网关,需要人为设定,如下图所示:
如何利用SpringBoot+Activiti工作流引擎实现请假审批流程?

这个也不好描述,直接上这个图对应的xml文件:


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 7}]]>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

要用的使用,把后缀名改成bpmn就行了.

  1. 跑一个测试用例,看能不能按照预先设定的逻辑执行:
package cn.dale.activitidemo;

import cn.dale.activitidemo.entity.Employee;
import cn.dale.activitidemo.task.ActivitiTask;
import org.activiti.engine.*;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: dale
 * @Date: 2019/11/5 17:59
 */
@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest
@Transactional
@Rollback(false)
//@Ignore
public class ActiTest {
 @Autowired
 private RuntimeService runtimeService;

 @Autowired
 private IdentityService identityService;

 @Autowired
 private TaskService taskService;

 @Autowired
 private RepositoryService repositoryService;

 //初始化一个要请假的员工
 private static final Employee emp = new Employee("zs", 8);

 @Test
 public void testInitProcess() {
 System.out.println("method startActivityDemo begin....");
 System.out.println("调用流程存储服务,已部署流程数量:"
 + repositoryService.createDeploymentQuery().count());
 Map map = new HashMap();
 // 流程图里写的${user} ,这里传进去user
 map.put("Applier", emp.getEmployeeName());
 map.put("DeptMng", "ls");
 map.put("ViceMng", "ww");
 map.put("GnlMng", "zl");
 map.put("special", "sq");

 // 指定流程的发起者 不指定发起者的字段就为空,注意跟审核人分开
 identityService.setAuthenticatedUserId(emp.getEmployeeName());
 //流程启动
 ExecutionEntity pi = (ExecutionEntity) runtimeService.startProcessInstanceByKey("start", map);
 String processInstanceId = pi.getId();
 System.out.println("流程开启成功,流程实例id:" + processInstanceId);
 ActivitiTask at = new ActivitiTask(taskService);
 //开始进行流程
 while (runtimeService
 .createProcessInstanceQuery()//获取查询对象
 .processInstanceId(processInstanceId)//根据id查询流程实例
 .singleResult()//获取查询结果,如果为空,说明这个流程已经执行完毕,否则,获取任务并执行
 != null) {
 Task task = taskService.createTaskQuery()//创建查询对象
 .processInstanceId(processInstanceId)//通过流程实例id来查询当前任务
 .singleResult();//获取单个查询结果
 String taskName = task.getName();
 System.out.println("任务ID: " + task.getId());
 System.out.println("任务的办理人: " + task.getAssignee());
 System.out.println("任务名称: " + taskName);
 System.out.println("任务的创建时间: " + task.getCreateTime());
 System.out.println("流程实例ID: " + task.getProcessInstanceId());
 switch (taskName) {
 case "Applier": //职员节点
 at.completeEmployeeTask(task, emp);
 break;
 case "DeptMng": //部门经理节点
 at.completeLeaderTask(task, emp);
 break;
 default: //经理节点
 at.completeJingliTask(task, emp);
 break;
 }
 System.out.println(emp.getApplyStatus().getName());
 }
 System.out.println("method startActivityDemo end....");
 }

}
 

ActivitiTask代码:

package cn.dale.activitidemo.task;

import cn.dale.activitidemo.entity.Employee;
import cn.dale.activitidemo.enums.ApplyStatusEnum;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: dale
 * @Date: 2019/11/6 15:38
 */
public class ActivitiTask {

 private TaskService taskService;

 public ActivitiTask(TaskService taskService) {
 this.taskService = taskService;
 }

 //职员提交申请
 public void completeEmployeeTask(Task task, Employee emp){
 //获取任务id
 String taskId = task.getId();

 //完成任务
 taskService.complete(taskId);
 emp.setApplyStatus(ApplyStatusEnum.AUDITING);
 System.out.println("职员已经提交申请.......");

 }
 //领导审批
 public void completeLeaderTask(Task task, Employee emp){
 //获取任务id
 String taskId = task.getId();

 //领导意见
 Map variables = new HashMap();
 variables.put("day",emp.getDay());
 variables.put("deptMngResult", 1);
 emp.setApplyStatus(ApplyStatusEnum.AUDITING);
 //完成任务
 taskService.complete(taskId, variables);
 System.out.println("领导审核完毕........");

 }
 //经理审批
 public void completeJingliTask(Task task, Employee emp){
 //获取任务id
 String taskId = task.getId();
 String name = task.getName();
 //经理意见
 Map variables = new HashMap();
 variables.put("day",emp.getDay());
// variables.put("result", 0);
// emp.setApplyStatus(ApplyStatusEnum.NO);
 variables.put("result", 1);
 emp.setApplyStatus(ApplyStatusEnum.YES);
 //完成任务
 taskService.complete(taskId, variables);
 System.out.println("经理审核完毕........,审核经理:"+name);

 }
}

请假被sq拒绝后的运行结果:

如何利用SpringBoot+Activiti工作流引擎实现请假审批流程?

可以看到流程一直循环执行,因为到最后一环被拒绝了,现在我让sq同意请假申请,结果如下图:

如何利用SpringBoot+Activiti工作流引擎实现请假审批流程?

这样,一个8天的请假流程就顺利走完了.简单的一个案例,当然Activiti还有满足不同场景需求的更多的Api,这里就不一一列举,大家根据自己项目的实际需要去学习

演示案例GitHub仓库地址:https://github.com/DaleZl/ActivitiDemo.git


分享到:


相關文章: