如何利用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


分享到:


相關文章: