欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關于在IDEA中SpringBoot項目中activiti工作流的使用詳解

 更新時間:2020年08月13日 09:22:43   作者:不正經(jīng)的程序袁  
這篇文章主要介紹了關于在IDEA中SpringBoot項目中activiti工作流的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

記錄一下工作流的在Springboot中的使用,,順便寫個demo,概念,什么東西的我就不解釋了,如有問題歡迎各位大佬指導一下。

1.創(chuàng)建springboot項目后導入依賴

 <dependency>
      <groupId>org.activiti</groupId>
      <artifactId>activiti-spring-boot-starter-basic</artifactId>
      <version>6.0.0</version>
    </dependency>

添加配置之后再springboot啟動類后面加上一行代碼否則啟動時會報錯

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)

添加數(shù)據(jù)源以及activiti的配置

spring:
 activiti:
  database-schema-update: drop‐create 
   //默認為false,activiti在啟動的時候會對比數(shù)據(jù)庫中的表中保存的版本,如果不一樣會拋出異常
   // true activiti會對數(shù)據(jù)庫中的表進行更新操作,如果表不存在,則自動創(chuàng)建
   // create_drop 在activiti啟動的時候創(chuàng)建表,關閉時刪除表,必須手動關閉
   // drop-create 在啟動的時候先刪除表后再創(chuàng)建新的表
  check-process-definitions: false
 datasource:
  driver-class-name: com.mysql.cj.jdbc.Driver
  url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
  username: root
  password: root

2.初始化activiti表

這里一共有3種方式去創(chuàng)建

第一種

@Test
  public void initTables() {
    //創(chuàng)建數(shù)據(jù)源
//    DriverManagerDataSource dataSource=new DriverManagerDataSource();
//    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
//    dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test");
//    dataSource.setUsername("root");
//    dataSource.setPassword("root");

    // 創(chuàng)建流程引擎的配置
    ProcessEngineConfiguration configuration = ProcessEngineConfiguration
        .createStandaloneProcessEngineConfiguration();
    configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");
    configuration.setJdbcUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&nullCatalogMeansCurrent=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC");
    configuration.setJdbcUsername("root");
    configuration.setJdbcPassword("root");
//		configuration.setDataSource(dataSource);
    /**
     * ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE 如果數(shù)據(jù)庫里面沒有activit的表,也不會創(chuàng)建
     * ProcessEngineConfiguration.DB_SCHEMA_UPDATE_CREATE_DROP 創(chuàng)建表,使用完之后刪除
     * ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE 如果數(shù)據(jù)庫里面沒有表,就創(chuàng)建
     *
     * dorp-create 代表如果數(shù)據(jù)庫里面有表,那么先刪除再創(chuàng)建
     *
     */
    //配置表的初始化的方式
    configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

    //得到流程引擎
    ProcessEngine processEngine=configuration.buildProcessEngine();
    System.out.println(processEngine);
  }

第二種配置activiti.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">


  <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    <property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?useUnicode=true%26nullCatalogMeansCurrent=true%26characterEncoding=utf8%26useSSL=false%26serverTimezone=UTC"></property>
    <property name="jdbcUsername" value="root"></property>
    <property name="jdbcPassword" value="root"></property>
    <!--
    flase: 默認值。activiti在啟動時,會對比數(shù)據(jù)庫表中保存的版本,如果沒有表或者版本不匹配,將拋出異常。
    true: activiti會對數(shù)據(jù)庫中所有表進行更新操作。如果表不存在,則自動創(chuàng)建。
    create_drop: 在activiti啟動時創(chuàng)建表,在關閉時刪除表(必須手動關閉引擎,才能刪除表)。
    drop-create: 在activiti啟動時刪除原來的舊表,然后在創(chuàng)建新表(不需要手動關閉引擎)。 -->
    <property name="databaseSchemaUpdate" value="drop-create"></property>
  </bean>
</beans>

然后寫一個測試類

@Test
	public void intiTables2() {
		ProcessEngineConfiguration configuration = ProcessEngineConfiguration
				.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
		// 得到流程引擎
		ProcessEngine processEngine = configuration.buildProcessEngine();
		System.out.println(processEngine);

	}

第三種方法

  @Test
  public void intiTables3() {
    //必須創(chuàng)建activiti.cfg.xml 并配置好數(shù)據(jù)庫的信息
    ProcessEngine processEngine= ProcessEngines.getDefaultProcessEngine();
    System.out.println(processEngine);
  }

3.打開數(shù)據(jù)庫查看

我們打開數(shù)據(jù)庫查看數(shù)據(jù)庫,會發(fā)現(xiàn)activiti已自動幫我們創(chuàng)建了28張表(有的好像也只有24張表,有興趣的可以研究一下)

這里為大家解釋一下各張表的含義:Activiti的后臺是有數(shù)據(jù)庫的支持,所有的表都以ACT_開頭。 第二部分是表示表的用途的兩個字母標識。

ACT_RE_*: 'RE'表示repository。 這個前綴的表包含了流程定義和流程靜態(tài)資源 (圖片,規(guī)則,等等)。

ACT_RU_*: 'RU'表示runtime。 這些運行時的表,包含流程實例,任務,變量,異步任務,等運行中的數(shù)據(jù)。 Activiti只在流程實例執(zhí)行過程中保存這些數(shù)據(jù), 在流程結束時就會刪除這些記錄。 這樣運行時表可以一直很小速度很快。

ACT_ID_*: 'ID'表示identity。 這些表包含身份信息,比如用戶,組等等。

ACT_HI_*: 'HI'表示history。 這些表包含歷史數(shù)據(jù),比如歷史流程實例, 變量,任務等等。

ACT_GE_*: 通用數(shù)據(jù), 用于不同場景下,如存放資源文件。

#RepositoryService
Select * from act_ge_bytearray; 二進制文件夾表
Select * from act_re_deployment; 流程部署表
Select * from act_re_procdef; 流程定義表
Select * from act_ge_property; 屬性數(shù)據(jù)表存儲整個流程引擎級別的數(shù)據(jù),初始化表結構時,會默認插入三條記錄

#RuntimeService TaskService  運行時數(shù)據(jù)庫表
Select * from act_ru_excution; 流程啟動一次只要沒有執(zhí)行完就會有一條數(shù)據(jù)
Select * from act_ru_task; 可能有多條數(shù)據(jù)
Select * from act_ru_variable; 記錄流程運行時的流程變量
Select * from act_ru_identitylink; 存放流程辦理人的信息

#HistoryService 歷史數(shù)據(jù)庫表
Select * from act_hi_procinst; 歷史流程實例
Select * from act_hi_taskinst; 歷史任務實例
Select * from act_hi_actinst; 歷史節(jié)點表
Select * from act_hi_attachment; 歷史附件表
Select * from act_hicomment; 歷史意見表
Select * from act_hi_identitylink; 歷史流程人員表
Select * from act_hi_detail; 歷史詳情表提供歷史變量查詢
Select * from act_hi_procinst; 歷史流程實例表
Select * from act_hi_taskinst; 歷史任務實例表
Select * from act_hi_varinst; 歷史變量表

#IdentityService 這四張表盡量使用自己的一套,難以滿足需求
Select * from act_id_group; 用戶組信息表
Select * from act_id_info; 用戶拓展信息表
Select * from act_id_menbership; 用戶與用戶組對應表
Select * from act_id_user; 用戶信息表

4.接下來開始畫請假流程圖(需要先安裝插件),新建一個bpm文件開始編輯

Assignee相當于辦理人的意思 我這里是zhang 提出申請,主管yuan 審核。

5.部署流程流程

  // 得到流程引擎
	private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

  @Test
  public void deployProcess01() {
    // 得到流程部署的service
    RepositoryService repositoryService = this.processEngine.getRepositoryService();
    Deployment deploy = repositoryService.createDeployment().name("請假流程").addClasspathResource("activitiTest.bpmn").deploy();
    System.out.println("部署成功:流程部署ID:" + deploy.getId());
  }

6.啟動流程(這里的key與第五部第一張途中對應)

  /**
   * 啟動流程
   */
  @Test
  public void startProcess() {
    RuntimeService runtimeService = this.processEngine.getRuntimeService();
//    String processDefinitionId="HelloWorld:1:4";
//		runtimeService.startProcessInstanceById(processDefinitionId);
    String processDefinitionKey="mytest";
    runtimeService.startProcessInstanceByKey(processDefinitionKey);
    System.out.println("流程啟動成功");
  }

7.根據(jù)用戶查詢任務(這里使用流程圖中的assignee字段)

 @Test
  public void queryTask() {
    TaskService taskService = this.processEngine.getTaskService();
    String assignee="chen";
    List<Task> list = taskService.createTaskQuery().taskAssignee(assignee).list();
    if(null!=list&&list.size()>0) {
      for (Task task : list) {
        System.out.println("任務ID:"+task.getId());
        System.out.println("流程實例ID:"+task.getProcessInstanceId());
        System.out.println("執(zhí)行實例ID:"+task.getExecutionId());
        System.out.println("流程定義ID:"+task.getProcessDefinitionId());
        System.out.println("任務名稱:"+task.getName());
        System.out.println("任務辦理人:"+task.getAssignee());
        System.out.println("################################");
      }
    }
  }

8.辦理任務(配合步驟8查詢出taskid然后進行辦理任務)

  @Test
  public void completeTask() {
    TaskService taskService = this.processEngine.getTaskService();
    String taskId="5005";//步驟8中查詢出來的taskId
    taskService.complete(taskId);
    System.out.println("任務完成");
  }

重復7、8兩個步驟,自此一個完整的請假流程就完成了。

那么肯定會有人問了,如果我想查看一我們流程定義的信息,流程圖,刪除流程定義等怎么辦呢,話不多說直接上代碼

package com.example;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.junit.jupiter.api.Test;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

public class TestProcessProdef {
  // 得到流程引擎
  private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

  /**
   * 部署流程使用classpath
   */
  @Test
  public void deployProcess01() {
    // 得到流程部署的service
    RepositoryService repositoryService = this.processEngine.getRepositoryService();
    Deployment deploy = repositoryService.createDeployment().name("請假流程2").addClasspathResource("activiti.bpmn").deploy();
    System.out.println("部署成功:流程部署ID:" + deploy.getId());
  }


  /**
   * 查詢流程部署信息 act_re_deployment
   */
  @Test
  public void queryProcessDeploy() {
    RepositoryService repositoryService = this.processEngine.getRepositoryService();
    // 創(chuàng)建部署信息的查詢
    String deploymentId = "1";
//		Deployment deploy = repositoryService.createDeploymentQuery()
    List<Deployment> list = repositoryService.createDeploymentQuery()
        // 條件
        // .deploymentId(deploymentId) //根據(jù)部署ID去查詢
        // .deploymentName(name)//根據(jù)部署名稱去查詢
        // .deploymentTenantId(tenantId)//根據(jù)tenantId去查詢
//		.deploymentNameLike(nameLike)//根據(jù)部署名稱模糊查詢
        // .deploymentTenantIdLike(tenantIdLike)//根據(jù)tenantId模糊查詢
        // 排序
//		.orderByDeploymentId().asc() //根據(jù)部署ID升序
        // .orderByDeploymenTime().desc() //根據(jù)部署時間降序
        // .orderByDeploymentName()//根據(jù)部署名稱升序
        // 結果集
        .list(); // 查詢返回list集合
//		.listPage(firstResult, maxResults) 分頁查詢返回list集合
    // .singleResult(); //返回單個對象
//		.count();

    /*
     * System.out.println("部署ID:"+deploy.getId());
     * System.out.println("部署名稱:"+deploy.getName());
     * System.out.println("部署時間:"+deploy.getDeploymentTime());
     */
//		System.out.println(count);
    for (Deployment deployment : list) {
      System.out.println("部署ID:" + deployment.getId());
      System.out.println("部署名稱:" + deployment.getName());
      System.out.println("部署時間:" + deployment.getDeploymentTime());
      System.out.println("########################");
    }
  }

  /**
   * 查詢流程定義
   */
  @Test
  public void queryProcDef() {
    RepositoryService repositoryService = this.processEngine.getRepositoryService();
    List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
        // 條件
//		.deploymentId(deploymentId) 根據(jù)部署ID查詢
//		.deploymentIds(deploymentIds) 根據(jù)部署ID的集合查詢Set<String> deploymentIds
//		.processDefinitionId(processDefinitionId)//根據(jù)流程定義IDHelloWorld:1:4
//		.processDefinitionIds(processDefinitionIds)//根據(jù)流程定義的IDS查詢
//		.processDefinitionKey(processDefinitionKey)//根據(jù)流程定義的的key查詢
//		.processDefinitionKeyLike(processDefinitionKeyLike)//根據(jù)流程定義的的key模糊查詢
//		.processDefinitionName(processDefinitionName)//根據(jù)流程定義的名稱查詢
//		.processDefinitionNameLike(processDefinitionNameLike)//根據(jù)流程定義的名稱模糊查詢
//		.processDefinitionResourceName(resourceName)//根據(jù)流程圖的BPMN文件名查詢
//		.processDefinitionResourceNameLike(resourceNameLike)//根據(jù)流程圖的BPMN文件名模糊查詢
//		.processDefinitionVersion(processDefinitionVersion)//根據(jù)流程定義的版本查詢
//		.processDefinitionVersionGreaterThan(processDefinitionVersion)//version>num
//		.processDefinitionVersionGreaterThanOrEquals(processDefinitionVersion)//version>=num
//		.processDefinitionVersionLowerThan(processDefinitionVersion)//version<num
//		.processDefinitionVersionLowerThanOrEquals(processDefinitionVersion)//version<=num
        // 排序
//		.orderByDeploymentId()
//		.orderByProcessDefinitionId()
//		.orderByProcessDefinitionKey()
//		.orderByProcessDefinitionName()
//		.orderByProcessDefinitionVersion()
        // 結果集
        .list();
//		.listPage(firstResult, maxResults)\
//		.count()
//		.singleResult()
    if (null != list && list.size() > 0) {
      for (ProcessDefinition pd : list) {
        System.out.println("流程定義ID:" + pd.getId());
        System.out.println("流程部署ID:" + pd.getDeploymentId());
        System.out.println("流程定義KEY:" + pd.getKey());
        System.out.println("流程定義的名稱:" + pd.getName());
        System.out.println("流程定義的bpmn文件名:" + pd.getResourceName());// bpmn的name
        System.out.println("流程圖片名:" + pd.getDiagramResourceName());// png的name
        System.out.println("流程定義的版本號:" + pd.getVersion());
        System.out.println("##################");
      }
    }
  }

  /**
   * 啟動流程
   */
  @Test
  public void startProcess() {
    RuntimeService runtimeService = this.processEngine.getRuntimeService();
    String processDefinitionKey = "mytest";
    runtimeService.startProcessInstanceByKey(processDefinitionKey);
    System.out.println("流程啟動成功");
  }

  /**
   * 刪除流程定義
   */
  @Test
  public void deleteProcessDef() {
    RepositoryService repositoryService = this.processEngine.getRepositoryService();
    String deploymentId = "2501";
    // 根據(jù)流程部署id刪除流程定義 如果當前id的流程正在執(zhí)行,那么會報錯
    // repositoryService.deleteDeployment(deploymentId);
    // 根據(jù)流程部署id刪除刪除流程定義 如果當前id的流程正在執(zhí)行,會把正在執(zhí)行的流程數(shù)據(jù)刪除 act_ru_*和act_hi_*表里面的數(shù)據(jù)
    repositoryService.deleteDeployment(deploymentId, true);
//		repositoryService.deleteDeploymentCascade(deploymentId);==repositoryService.deleteDeployment(deploymentId, true);
    System.out.println("刪除成功");
  }

  /**
   * 查詢流程圖 根據(jù)流程定義ID
   */
  @Test
  public void viewProcessImg() {
    RepositoryService repositoryService = this.processEngine.getRepositoryService();
    String processDefinitionId = "mytest:2:2504";
    InputStream inputStream = repositoryService.getProcessDiagram(processDefinitionId);

    File file = new File("d:/mytest.png");
    try {
      BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
      int len = 0;
      byte[] b = new byte[1024];
      while ((len = inputStream.read(b)) != -1) {
        outputStream.write(b, 0, len);
        outputStream.flush();
      }
      outputStream.close();
      inputStream.close();
      System.out.println("查詢成功");
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  /**
   * 查詢流程圖 根據(jù)流流程部署ID
   */
  @Test
  public void viewProcessImg2() {
    RepositoryService repositoryService = this.processEngine.getRepositoryService();
    // 根據(jù)流程部署ID查詢流程定義對象
    String deploymentId = "1";
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .deploymentId(deploymentId).singleResult();
    // 從流程定義對象里面查詢出流程定義ID
    String processDefinitionId = processDefinition.getId();
    InputStream inputStream = repositoryService.getProcessDiagram(processDefinitionId);

    File file = new File("d:/" + processDefinition.getDiagramResourceName());
    try {
      BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
      int len = 0;
      byte[] b = new byte[1024];
      while ((len = inputStream.read(b)) != -1) {
        outputStream.write(b, 0, len);
        outputStream.flush();
      }
      outputStream.close();
      inputStream.close();
      System.out.println("查詢成功");
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  /**
   * 查詢最新的流程定義
   */
  @Test
  public void queryNewProcessDef() {
    Map<String, ProcessDefinition> map = new HashMap<>();

    // 查詢所有的流程定義根據(jù)版本號升序
    RepositoryService repositoryService = this.processEngine.getRepositoryService();
    List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
        .orderByProcessDefinitionVersion().asc().list();
    if (null != list && list.size() > 0) {
      for (ProcessDefinition pd : list) {
        map.put(pd.getKey(), pd);
      }
    }
    // 循環(huán)map集合
    Collection<ProcessDefinition> values = map.values();
    for (ProcessDefinition pd : values) {
      System.out.println("流程定義ID:" + pd.getId());
      System.out.println("流程部署ID:" + pd.getDeploymentId());
      System.out.println("流程定義KEY:" + pd.getKey());
      System.out.println("流程定義的名稱:" + pd.getName());
      System.out.println("流程定義的bpmn文件名:" + pd.getResourceName());// bpmn的name
      System.out.println("流程圖片名:" + pd.getDiagramResourceName());// png的name
      System.out.println("流程定義的版本號:" + pd.getVersion());
      System.out.println("##################");
    }
  }

  /**
   * 已知key 附加功能:刪除流程定義(刪除key相同的所有不同版本的流程定義)
   */
  public void deleteAllSameVersion() {
    String processDefinitionKey = "mytest";
    RepositoryService repositoryService = this.processEngine.getRepositoryService();
    // 根據(jù)流程定義的key查詢流程集合
    List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey(processDefinitionKey).list();

    if (null != list && list.size() > 0) {
      for (ProcessDefinition pd : list) {
        repositoryService.deleteDeployment(pd.getDeploymentId(), true);

      }
    }

  }
}

肯定還有人會問,上面的請假流程是走完了,但是沒有寫請假理由,請假天數(shù),如果是報銷單的話 還需要上傳報銷單據(jù)等,那么這個怎么解決呢?這個時候就需要activiti提供給我們的流程變量了,那么什么是流程變量呢?

流程變量在整個工作流中扮演很重要的作用。例如:請假流程中有請假天數(shù)、請假原因等一些參數(shù)都為流程變量的范圍。流程變量的作用域范圍是只對應一個流程實例。也就是說各個流程實例的流程變量是不相互影響的。流程實例結束完成以后流程變量還保存在數(shù)據(jù)庫中(存放到流程變量的歷史表中)。圖中紅框的信息就是流程變量。

那么我們怎么設置流程變量呢,我們啟動流程的時候就可以設置流程變量了,見代碼:

	/**
	 * 啟動流程
	 */
	@Test
	public void startProcess() {
		RuntimeService runtimeService = this.processEngine.getRuntimeService();
		String processDefinitionKey = "mytest";
//		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
		//創(chuàng)建流程變量對象
		Map<String,Object> variables=new HashMap<>();
		variables.put("請假天數(shù)", 30);//int
		variables.put("請假原因", "結婚");
		variables.put("請假時間", new Date());
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
		System.out.println("流程啟動成功:" + processInstance.getId() + "  " + processInstance.getProcessDefinitionId() + " "
				+ processInstance.getProcessInstanceId());

	}

說明:

1)流程變量的作用域就是流程實例,所以只要設置就行了,不用管在哪個階段設置

2)基本類型設置流程變量,在taskService中使用任務ID,定義流程變量的名稱,設置流程變量的值。

3)Javabean類型設置獲取流程變量,除了需要這個javabean實現(xiàn)了Serializable接口外,還要求流程變量對象的屬性不能發(fā)生變化,否則拋出異常。解決方案,固定序列化ID

4)設置流程變量的時候,向act_ru_variable這個表添加數(shù)據(jù)

RuntimeService對象可以設置流程變量和獲取流程變量  TaskService對象可以設置流程變量和獲取流程變量

Map集合的key表示流程變量的名稱    Map集合的value表示流程變量的值

查詢流程變量以及查詢歷史流程變量:

	/**
	 * 獲取流程變量
	 */
	@Test
	public void getVariables() {
		RuntimeService runtimeService = this.processEngine.getRuntimeService();
		String executionId="2501";
		Integer days=(Integer) runtimeService.getVariable(executionId, "請假天數(shù)");
		Date date=(Date) runtimeService.getVariable(executionId, "請假時間");
		User user=(User) runtimeService.getVariable(executionId, "用戶對象");
		System.out.println(days);
		System.out.println(date.toLocaleString());
		System.out.println(user.getId()+" "+user.getName());
	}
	
	/**
	 * 7:查詢歷史的流程變量
	 */
	@Test
	public void getHistoryVariables() {
		HistoryService historyService = this.processEngine.getHistoryService();
		
		/*HistoricVariableInstance singleResult = historyService.createHistoricVariableInstanceQuery().id("2503").singleResult();;
		System.out.println(singleResult.getId());
		System.out.println(singleResult.getValue());
		System.out.println(singleResult.getVariableName());
		System.out.println(singleResult.getVariableTypeName());*/
		String processInstanceId="2501";
		List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list();
		
		for (HistoricVariableInstance hvs : list) {
			System.out.println("ID"+hvs.getId());
			System.out.println("變量值"+hvs.getValue());
			System.out.println("變量名"+hvs.getVariableName());
			System.out.println("變量類型"+hvs.getVariableTypeName());
			System.out.println("#####################");
		}
	}

查詢歷史流程實例 、查詢歷史活動 以及查詢歷史任務 

public class TestHistoryQuery {

	private ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
	HistoryService historyService = this.processEngine.getHistoryService();
	
	/* 1,查詢歷史流程實例 */
	@Test
	public void historyProcessInstince() {
		List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
		//條件
//		.processDefinitionId(processDefinitionId)
//		.processDefinitionKey(processDefinitionKey)
//		.processDefinitionKeyIn(processDefinitionKeys)
//		.processDefinitionName(processDefinitionName)
//		.processDefinitionVersion(processDefinitionVersion)
//		.processInstanceBusinessKey(processInstanceBusinessKey)
//		.processInstanceId(processInstanceId)
//		.processInstanceIds(processInstanceIds)
		//排序
//		.orderByProcessDefinitionId()
//		.orderByProcessInstanceBusinessKey()
//		.orderByProcessInstanceDuration()
//		.orderByProcessInstanceStartTime()
//		.orderByProcessInstanceId()
		//結果集
		.list();
//		.listPage(firstResult, maxResults)
//		.count()
//		.singleResult();
		
		if(null!=list&&list.size()>0) {
			for (HistoricProcessInstance hpi : list) {
				System.out.println("歷史流程實例ID:" + hpi.getId());
				System.out.println("流程定義ID:" + hpi.getProcessDefinitionId());
				System.out.println("歷史流程實例的業(yè)務ID:" + hpi.getBusinessKey());
				System.out.println("流程部署ID:" + hpi.getDeploymentId());
				System.out.println("流程定義KEY:" + hpi.getProcessDefinitionKey());
				System.out.println("開始活動ID:" + hpi.getStartActivityId());
				System.out.println("結束活動ID:" + hpi.getEndActivityId());
				System.out.println("########################");
			}
		}
		
	}
	
	
	
	/* 2,查詢歷史活動 */
	@Test
	public void queryHistoryAct() {
		List<HistoricActivityInstance> list = this.historyService.createHistoricActivityInstanceQuery()
		//條件
//		.activityId(activityId)
//		.activityInstanceId(activityInstanceId)
//		.activityName(activityName)
		//排序
//		.orderByActivityId()
//		.orderByActivityName()
		//結果集
		.list();
		if(null!=list&&list.size()>0)
		{
			for (HistoricActivityInstance hai : list) {
				System.out.println("ID:"+hai.getId());
				System.out.println("流程定義ID:"+hai.getProcessDefinitionId());
				System.out.println("流程實例ID:"+hai.getProcessInstanceId());
				System.out.println("執(zhí)行實例ID:"+hai.getExecutionId());
				System.out.println("活動ID:"+hai.getActivityId());
				System.out.println("任務ID:"+hai.getTaskId());
				System.out.println("活動名稱:"+hai.getActivityName());
				System.out.println("活動類型:"+hai.getActivityType());
				System.out.println("任務辦理人:"+hai.getAssignee());
				System.out.println("開始時間:"+hai.getStartTime());
				System.out.println("結束時間:"+hai.getEndTime());
				System.out.println("持續(xù)時間:"+hai.getDurationInMillis());
				System.out.println("#######################################");
			}
		}
	}
	/* 3,查詢歷史任務 act_hi_taskinst */
	@Test
	public void queryHistoryTask() {
		List<HistoricTaskInstance> list = this.historyService.createHistoricTaskInstanceQuery()
		//條件
//		.deploymentId(deploymentId)
//		.deploymentIdIn(deploymentIds)
//		.executionId(executionId)
//		.processDefinitionId(processDefinitionId)
//		.processDefinitionKey(processDefinitionKey)
//		.processDefinitionKeyIn(processDefinitionKeys)
//		.processDefinitionKeyLike(processDefinitionKeyLike)   processDefinitionKeyLike="%Hello%"
//		.processDefinitionName(processDefinitionName)
//		.processDefinitionNameLike(processDefinitionNameLike)
		//排序
//		.orderByTaskDefinitionKey()
		//結果集
		.list();
//		.listPage(firstResult, maxResults)
//		.count()
//		.singleResult()
		if(null!=list&&list.size()>0)
		{
			for (HistoricTaskInstance task : list) {
				System.out.println("任務ID:" + task.getId());
				System.out.println("任務辦理人:" + task.getAssignee());
				System.out.println("執(zhí)行實例ID:" + task.getExecutionId());
				System.out.println("任務名稱:" + task.getName());
				System.out.println("流程定義ID:" + task.getProcessDefinitionId());
				System.out.println("流程實例ID:" + task.getProcessInstanceId());
				System.out.println("任務創(chuàng)建時間:" + task.getCreateTime());
				System.out.println("任務結束時間:" + task.getEndTime());
				System.out.println("#######################################");
			}
		}
	}
}

最近我發(fā)現(xiàn)上面的代碼不能完全在開發(fā)中應用,比如上面的用戶申請是在畫流程圖的時候寫死的,在實際開發(fā)中肯定是根據(jù)當前登錄的用戶來提出申請,另外還沒有分支的情況,所以我特地修改了一下流程圖。

這個流程圖中 沒有設置用戶,在Condition中傳入?yún)?shù)#{UserId},后面的重要與不重要分支同樣加上Condition條件${message=='重要'}和${message=='不重要'},然后主管審核和總經(jīng)理的assignee可以設置成固定的值也可以像用戶一樣根據(jù)傳參設置。接下來直接上代碼

1.啟動流程

 /**啟動流程實例*/

  @Test
  public void startProcessInstance(){
    String processDefinitionKey = "myProcess_1";
    /**啟動流程實例的同時,設置流程變量,使用流程變量用來指定任務的辦理人,對應task.pbmn文件中#{userID}*/

    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("userID", "袁志豪");
    ProcessInstance pi = processEngine.getRuntimeService()//與正在執(zhí)行的流程實例和執(zhí)行對象相關的Service
     .startProcessInstanceByKey(processDefinitionKey,variables);//使用流程定義的key啟動流程實例,key對應helloworld.bpmn文件中id的屬性值,使用key值啟動,默認是按照最新版本的流程定義啟動

    System.out.println("流程實例ID:"+pi.getId());//流程實例ID  101

    System.out.println("流程定義ID:"+pi.getProcessDefinitionId());//流程定義ID

  }

用戶完成申請?zhí)峤唬鞴茉诹鞒蓤D中沒有設置固定值

  @Test
  public void completeTask() {
    TaskService taskService = this.processEngine.getTaskService();
    String taskId = "2508";
    // 根據(jù)任務ID去完成任務
   // taskService.complete(taskId);
    // 根據(jù)任務ID去完成任務并指定流程變量
    Map<String,Object > variable =new HashMap<>();
    String shenheren ="張三";//實際開發(fā)中可在前臺選擇主管傳入后臺
    variable.put("zhuguan","張三");//這里的 zhuguan 和 activiti.bpmn中的#{zhuguan}保持一致,既可以設置下一級審核主管
		taskService.complete(taskId, variables);
    System.out.println("任務完成");
  }

主管審核

  @Test
  public void complateTask2(){
    TaskService taskService = this.processEngine.getTaskService();
    String taskId2= "5002";
    Map<String,Object > variable =new HashMap<>();
    /***這里的message 是流程圖中分支條件message,根據(jù)傳入的參數(shù)判斷走那一條線***/
    variable.put("message","重要");
//    variable.put("message","不重要");
    taskService.complete(taskId2,variable);
  }

經(jīng)理審核

 @Test
  public void complateTask3(){
    TaskService taskService = this.processEngine.getTaskService();
    String taskId2= "7503";
    Map<String,Object > variable =new HashMap<>();
    variable.put("審核意見","好好休假注意身體");//領導審核意見
    taskService.complete(taskId2,variable);
  }

另外我在開發(fā)中發(fā)現(xiàn)在流程圖畫完之后將bpmn后綴改為xml方式生成圖片之后,再次改為bpmn的時候,發(fā)現(xiàn)之前寫的Condition中變成了\n,如圖

我們再次將后綴改為xml之后查看我們的條件:

解決方式:

將condition前面后面的空格刪掉即可;

到此這篇關于關于在IDEA中SpringBoot項目中activiti工作流的使用詳解的文章就介紹到這了,更多相關IDEA SpringBoot activiti工作流內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 解決JAVA非對稱加密不同系統(tǒng)加密結果不一致的問題

    解決JAVA非對稱加密不同系統(tǒng)加密結果不一致的問題

    這篇文章主要介紹了解決JAVA非對稱加密不同系統(tǒng)加密結果不一致的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 使用MyBatis攔截器實現(xiàn)SQL的完整打印

    使用MyBatis攔截器實現(xiàn)SQL的完整打印

    當我們使用Mybatis結合Mybatis-plus進行開發(fā)時,為了查看執(zhí)行sql的信息通常我們可以通過屬性配置的方式打印出執(zhí)行的sql語句,但這樣的打印出了sql語句常帶有占位符信息,不利于排錯,所以本文介紹了構建MyBatis攔截器,實現(xiàn)SQL的完整打印,需要的朋友可以參考下
    2024-07-07
  • java基礎-數(shù)組擴容詳解

    java基礎-數(shù)組擴容詳解

    這篇文章主要介紹了Java數(shù)組擴容實現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2021-08-08
  • JAVA發(fā)送HTTP請求的多種方式詳細總結

    JAVA發(fā)送HTTP請求的多種方式詳細總結

    目前做項目中有一個需求是這樣的,需要通過Java發(fā)送url請求,查看該url是否有效,這時我們可以通過獲取狀態(tài)碼來判斷,下面這篇文章主要給大家介紹了關于JAVA發(fā)送HTTP請求的多種方式總結的相關資料,需要的朋友可以參考下
    2023-01-01
  • Java程序員的10道常見的XML面試問答題(XML術語詳解)

    Java程序員的10道常見的XML面試問答題(XML術語詳解)

    包括web開發(fā)人員的Java面試在內的各種面試中,XML面試題在各種編程工作的面試中很常見。XML是一種成熟的技術,經(jīng)常作為從一個平臺到其他平臺傳輸數(shù)據(jù)的標準
    2014-04-04
  • IDEA Maven 配置備忘筆記

    IDEA Maven 配置備忘筆記

    這篇文章主要介紹了IDEA Maven 配置備忘筆記,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • 使用JPA+querydsl如何實現(xiàn)多條件動態(tài)查詢

    使用JPA+querydsl如何實現(xiàn)多條件動態(tài)查詢

    這篇文章主要介紹了使用JPA+querydsl如何實現(xiàn)多條件動態(tài)查詢,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java高并發(fā)下鎖的優(yōu)化詳解

    Java高并發(fā)下鎖的優(yōu)化詳解

    這篇文章主要介紹了Java高并發(fā)下鎖的優(yōu)化詳解,鎖是最常用的同步方法之一,在高并發(fā)的環(huán)境下,激烈的鎖競爭會導致程序的性能下降,下面是一些關于鎖的使用建議,可以把這種副作用降到最低,需要的朋友可以參考下
    2024-01-01
  • 圖解Eclipse j2ee開發(fā)環(huán)境的搭建過程

    圖解Eclipse j2ee開發(fā)環(huán)境的搭建過程

    這篇文章以圖文結合的方式介紹了Eclipse j2ee開發(fā)環(huán)境的搭建過程,內容很詳細,每一個步驟都有對應的操作截圖,需要的朋友可以參考下
    2015-08-08
  • 解決TreeSet類的排序問題

    解決TreeSet類的排序問題

    本文介紹TreeSet支持兩種排序方法:自然排序和定制排序。TreeSet默認采用自然排序。詳細請看下文
    2015-09-09

最新評論