activiti筆記(常見api及使用)

工作流:在多個參與者之間按照某種預定義的規則傳遞文檔 信息 任務的過程自動進行。
演示請假流程管理系統平臺:
工作流引擎 processEngine
---定義工作流
---執行和管理工作流

工作流activiti的表是使用來存放流程數據的
而業務的數據都需要用戶自己創建和維護的

一定需要業務去關聯流程,才能開發工作流系統




使用activiti的api

---

流程定義是不能修改的,
控制修改


#部署對象和流程定義相關的表
select * from act_re_deployment #部署對象表
select * from act_re_procdef #流程定義表
select * from act_ge_bytearray #流程文件表
select * from act_ge_property #主鍵生成策略表


#流程實例,執行對象,任務
select * from act_ru_execution #正在執行的執行對象表

#id_ === proc_inst_id_
流程實例Id和執行對象ID

select * from act_hi_procinst  #流程實例歷史表
select * from act_ru_task;#正在執行的任務表,只有節點中存usertask的時候,該表中有數據
select * from act_hi_taskinst #正在執行的歷史任務表
#結論:
1.如果是單例流程(沒有分支和聚合),那麼流程實例Id和執行對象ID是相同的
2.一個流程中流程實例只有一個,執行對象可以多個(如果存在分支和聚合)


流程變量
1.用來傳遞業務參數
2.指定連線完成任務(同意和拒絕)
3.動態指定任務的辦理人

****************************************************************************
流程變量
在流程執行或者任務執行過程中,用於設置流程變量
select * from act_ru_variable ##正在執行的流程變量表
select * from act_hi_varinst ##歷史流程變量表

流程變量支持類型:
基本數據類型,引用數據類型需要序列化並有版本號控制

----------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------

線條:
線設置:condition --》#{}(或者#{} ){boolean值} ,流程變量進行判斷走哪條線

排他網關(exclusiveGaeWay):

組件--》排他網關的組件--》設置任務完成時的condition-->連線時做判斷————》完成排他網關的執行

並行網關(parallelGateWay):
排他網關沒有condition,都是成對出現的

判斷活動是否結束

接收活動(receiveTask,即等待活動):
沒有辦理人

個人任務:
辦理人:assigner-->
1. 直接指定辦理人
2. 使用流程變量 ${} #{}--》在bpmn文件中的userTask屬性assigner指定辦理人${userId}
3. 使用類指定流程的辦理人 -->TaskListener-->在bpmn文件中指定任務監聽的類的全路徑當啓動流程實例會自動監聽到配置好的方法中

組任務:
由一組人來辦理
1. 直接指定辦理人-->candidate users(小A,小B,小C,小D)多個人用逗號隔開
2. 使用流程變量 ${} #{}--》在bpmn文件中的userTask屬性assigner指定辦理人${userId}
3. 使用類指定流程的辦理人 -->TaskListener-->在bpmn文件中指定任務監聽的類的全路徑當啓動流程實例會自動監聽到配置好的方法中

select *from act_ru_identitylink #任務表 包括個人任務也包括組任務
select *from act_hi_identitylink #歷史任務辦理人表 個任務和組任務

工作流定義的用戶組(瞭解)

demo

package com.demo.activiti;

import com.demo.activiti.entity.Person;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@SpringBootTest//(classes = ActivitiApplicationTests.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@RunWith(SpringJUnit4ClassRunner.class)
public class ActivitiApplicationTests {
    private Logger logger = LoggerFactory.getLogger(ActivitiApplicationTests.class);

    /**
     * 默認方式獲取  流程引擎對象
     */
    @Autowired
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 使用代碼創建工作流程需要的23張表
     * <p>
     * public static final String DB_SCHEMA_UPDATE_FALSE = "false"; 不能自動創建表 需要表存在
     * public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop"; 先刪除 再創建
     * public static final String DB_SCHEMA_UPDATE_TRUE = "true"; 如果表不存在 自動創建表
     */
    @Test
    public void createTable() {
        ProcessEngineConfiguration config = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
        config.setJdbcDriver("com.mysql.cj.jdbc.Driver");
        config.setJdbcUrl("jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8");
        config.setJdbcUsername("root");
        config.setJdbcPassword("root");
        config.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE);
        //工作流的核心對象 processEngine對象
        ProcessEngine processEngine = config.buildProcessEngine();
        logger.info("processEngine:" + processEngine);
    }

    /**
     * 通過配置文件activiti.cfg.xml 獲取流程引擎對象
     */
    @Test
    public void createtable_2() {
        ProcessEngine processEngine = ProcessEngineConfiguration
                .createProcessEngineConfigurationFromResource("activiti.cfg.xml")
                .buildProcessEngine();
        logger.info("processEngin:" + processEngine);
    }

    @Test
    public void contextLoads() {
        //通過獲取載入默認獲取
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        logger.info(processEngine.toString());
        processEngine.close();

    }

    /**
     * 部署流程定義
     */
    @Test
    public void deployment() {
        //與流程定義和流程部署相關的service
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment() //創建一個部署對象
                .name("審批流") //添加部署的名稱
                .addClasspathResource("workflow/testActiviti.bpmn")//從classpath加載資源文件 一次只能加載一個文件
                .addClasspathResource("workflow/testActiviti.png")
                .deploy();//完成部署
        logger.info("id:" + deploy.getId());//1
        logger.info("id:" + deploy.getName());//對應的表act_re_procdef() act_re_deployment(部署表) act_ge_bytearray (二進制表) act_ge_property(版本號控制的)
    }

    /**
     * 啓動流程實例
     */
    @Test
    public void startProcessInstance() {
        //流程頂定義的key
        String processDefinitionKey = "myProcess";
        //返回流程實例對象
        ProcessInstance processInstance = processEngine.getRuntimeService() //正在執行的流程實例和執行對象相關的對象--執行管理 ,包括啓動 推進 刪除流程實例等操作
                .startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key 啓動實例,key 爲bpmn 文件id 的屬性值myProcess  或者 流程定義表:act_re_procdef 表中的key
        //默認使用的最新版本的流程定義啓動
        logger.info("流程實例id:"+processInstance.getId());//流程實例id:2501
        logger.info("流程定義id:"+processInstance.getProcessDefinitionId());//流程定義id:myProcess:1:4
        //act_ru_execution  act_ru_task  act_ru_identitylink  act_ru_execution  act_hi_taskinst  act_hi_procinst  act_hi_identitylink act_hi_actinst
    }

    /**
     * 查詢當前人的個人任務
     */
    @Test
    public void findMyPersonProcessTask(){
        String assignee = "李四";//張三 李四
        //任務管理
        List<Task> list = processEngine.getTaskService() //與任務相關的service
                .createTaskQuery()
                .taskAssignee(assignee) //指定個人任務查詢 指定辦理人  act_ru_task
                .list();
        if(list!= null && list.size()>0){
            for(Task task:list){
                logger.info("任務id:"+task.getId());//任務id:2505  任務id:5002
                logger.info("任務名稱:"+task.getName());//任務名稱:提交申請  任務名稱:部門審批
                logger.info("任務的創建時間:"+task.getCreateTime());//任務的創建時間:Tue Apr 14 18:08:52 CST 2020  任務的創建時間:Tue Apr 14 18:42:29 CST 20
                logger.info("任務的辦理人:"+task.getAssignee());//任務的辦理人:張三 任務的辦理人:李四
                logger.info("流程實例Id:"+task.getProcessInstanceId());//流程實例Id:2501  流程實例Id:2501
                logger.info("執行對象Id:"+task.getExecutionId());//執行對象Id:2502 執行對象Id:2502
                logger.info("流程定義Id:"+task.getProcessDefinitionId());//流程定義Id:myProcess:1:4 流程定義Id:myProcess:1:4
                logger.info("***********************************************");
            }
        }
    }

    /**
     * 完成我的任務
     */
    @Test
    public void completeMyPersonTask(){
        //任務id
        String taskId = "40002"; //2505 5002  15005  20002    32505  40002
        processEngine.getTaskService() //與任務相關的service
        .complete(taskId); //完成任務
        logger.info("完成任務,任務id:"+taskId); //完成任務,任務id:5002

    }

    /**
     * 查詢流程定義
     */
    @Test
    public void findProcessDefinition(){
        List<ProcessDefinition> list = processEngine.getRepositoryService()//與流程定義和部署相關的service
                .createProcessDefinitionQuery()//創建一個流程定義的查詢
                /** 指定查詢條件, where 條件**/
//        .deploymentId(deploymentId)//使用部署對象ID查詢
//        .processDefinitionId(processDefinitionId)//使用流程定義Id查詢
//        .processDefinitionKey(processDefinitionKey) //使用流程定義key查詢
//        .processDefinitionName(processDefinionName) //使用流程定義Name查詢

                /** 排序**/
                .orderByProcessDefinitionVersion().asc()//按照版本的升序排列
//        .orderByProcessDefinitionName().desc()//按照流程定義的名稱降序排列
                /** 返回的結果**/
                .list();//返回一個集合列表,封裝流程定義
//        .singleResult();//返回唯一結果集
//        .count();//返回結果集數量
//       .listPage(firstResult,maxResults);//分頁查詢
        if(list!=null && list.size()>0){
            for(ProcessDefinition pd:list){
                System.out.println("流程定義ID:"+pd.getId());//流程定義的key+版本+隨機生成數
                System.out.println("流程定義名稱:"+pd.getName());//bpmn文件中的names屬性值
                System.out.println("流程定義的KEY:"+pd.getKey());//bpmn文件中的id屬性值
                System.out.println("流程定義的版本:"+pd.getVersion());//流程定義的key相同的情況下 版本升級
                System.out.println("資源名稱bpmn文件:"+pd.getResourceName());
                System.out.println("資源名稱png文件:"+pd.getDiagramResourceName());
                System.out.println("部署對象ID:"+pd.getDeploymentId());
                System.out.println("#######################################################");
            }
        }
    }

    /**
     * 刪除流程定義
     */
    @Test
    public void deleteaProcessDefinition(){
        String deploymentId = "65001";
        //使用部署ID 完成刪除
//        processEngine.getRepositoryService()//
//        .deleteDeployment(deploymentId); //不能級聯刪除,只能刪除沒有啓動的流程,如果流程啓動就會拋異常

        //不管流程是否啓動,都能刪除
        processEngine.getRepositoryService()//

        .deleteDeployment(deploymentId,true);//默認是false  實現級聯刪除。
    }

    /**
     * 查看流程圖
     */
    @Test
    public void viewflow() throws IOException {
        //將生成的圖片放到文件夾下
        String deploymentId = "1";
        String resourceName = "";
        //獲取圖片資源名稱
        List<String> list = processEngine.getRepositoryService()
                .getDeploymentResourceNames(deploymentId);
        if(list!=null && list.size()>0){
            for(String name:list){
                if(name.indexOf(".png")>=0){
                    resourceName = name;
                }
            }
        }
        InputStream in = processEngine.getRepositoryService()//
                .getResourceAsStream(deploymentId, resourceName);
        //將圖片生成到d盤的目錄下
        File file = new File("D:/"+resourceName);
        //將輸入流圖片寫入到d盤
        FileUtils.copyInputStreamToFile(in,file);
    }

    /**
     * 附加功能 查詢最新版本的流程
     */
    @Test
    public void findLastVersionProcessDefinition(){
        List<ProcessDefinition> list = processEngine.getRepositoryService()//
                .createProcessDefinitionQuery()
                .orderByProcessDefinitionVersion().asc()//是用流程定義的版本升序排序
                .list();
        Map<String , ProcessDefinition> map = new LinkedHashMap<String , ProcessDefinition>();
        if(list!=null && list.size()>0){
            for(ProcessDefinition pd:list){
                map.put(pd.getKey(),pd);
            }
        }
        List<ProcessDefinition> pdlist = new ArrayList<ProcessDefinition>(map.values());
        if(pdlist!=null && pdlist.size()>0){
            for(ProcessDefinition pd:pdlist){
                System.out.println( "流程定義ID:"+pd.getId());//流程定義的key+版本+隨機生成數
                System.out.println( "流程定義名稱:"+pd.getName());//bpmn文件中的names屬性值
                System.out.println( "流程定義的KEY:"+pd.getKey());//bpmn文件中的id屬性值
                System.out.println( "流程定義的版本:"+pd.getVersion());//流程定義的key相同的情況下 版本升級
                System.out.println( "資源名稱bpmn文件:"+pd.getResourceName());
                System.out.println( "資源名稱png文件:"+pd.getDiagramResourceName());
                System.out.println( "部署對象ID:"+pd.getDeploymentId());
                System.out.println( "#######################################################");
            }
        }
    }

    /**
     * 附加功能,刪除流程定義(刪除key相同的所有不同版本的流程定義)
     */
    public void deleteProcessDefintionByKey(){
        //流程定義的key
        String key ="myProcess";
        List<ProcessDefinition> list = processEngine.getRepositoryService()//先使用流程定義的key查詢流程定義,查詢出所有的版本
                .createProcessDefinitionQuery()
                .list();
        //遍歷 獲取每個流程定義的部署Id
        if(list!=null && list.size()>0){
            for(ProcessDefinition pd:list){
                String deploymentId = pd.getDeploymentId();
                processEngine.getRepositoryService()
                        .deleteDeployment(deploymentId,true);
            }
        }
    }

    /**
     * 查詢流程狀態,判斷流程是否正在執行還是結束
     */
    @Test
    public void isProcessEnd(){
        String processInstanceId = "2501";
        ProcessInstance pi = processEngine.getRuntimeService()//表示正在執行的流程實例和執行對象
                .createProcessInstanceQuery()//創建流程實例查詢
                .processInstanceId(processInstanceId)//使用流程實例ID
                .singleResult();//流程實例對象
        if(pi == null){
            System.out.println("流程結束");
        }else{
            System.out.println("流程沒有結束");
        }
    }

    /**
     * 查詢歷史任務(後面講)
     */
    @Test
    public void findHistoryTask(){
        String taskAssignee ="";
        List<HistoricTaskInstance> list = processEngine.getHistoryService()//與歷史數據(歷史表)相關的service
                .createHistoricTaskInstanceQuery()//創建歷史任務實例查詢
                .taskAssignee(taskAssignee)//指定歷史任務的辦理人
                .list();
        if(list!= null && list.size()>0){
            for(HistoricTaskInstance hti:list){
                System.out.println(hti.getId()+"  "+hti.getName()+" "+hti.getProcessDefinitionId()+" "+hti.getStartTime()+" "+hti.getEndTime());
            }
        }
    }

    /**
     * 查詢歷史流程實例(後面講)
     */
    @Test
    public void findHistoryProcessInstance(){
        String processInstanceId = "";
        HistoricProcessInstance hpi = processEngine.getHistoryService()
                .createHistoricProcessInstanceQuery()//創建歷史流程實例查詢
                .processInstanceId(processInstanceId)//使用流程實例ID查詢
                .singleResult();
        System.out.println(hpi.getId()+" "+hpi.getProcessDefinitionId()+" "+hpi.getStartTime()+" "+hpi.getEndTime());
    }

    /**
     * 設置流程變量
     */
    @Test
    public void setVariables(){
        //任務Id
        String taskId ="32505";//15005 20002        32505
        /** 與任務(正在執行)**/
        TaskService taskService = processEngine.getTaskService();
        /** 1. 設置流程變量 使用基本數據類型**/
//        taskService.setVariableLocal(taskId,"請假天數",5);//與任務Id綁定
//        taskService.setVariable(taskId,"請假日期",new Date());
//        taskService.setVariable(taskId,"請假原因","回家探親--起吃飯");//select * from act_ru_variable

        /** 2. 設置流程變量使用javabean**/
        Person p = new Person(1,"張三");
        taskService.setVariable(taskId,"人員信息",p);
    }

    /**
     * 獲取流程變量
     */
    @Test
    public void getVariables(){
        //任務Id
        String taskId ="32505";//15005 20002        32505
        /** 與任務(正在執行)**/
        TaskService taskService = processEngine.getTaskService();
        /** 1. 獲取流程變量 使用基本數據類型**/
//        Integer days = (Integer) taskService.getVariable(taskId, "請假天數");
//        Date date = (Date) taskService.getVariable(taskId, "請假日期");
//        String reason = (String) taskService.getVariable(taskId, "請假原因");
//
//        System.out.println("請假天數:"+days);
//        System.out.println("請假日期:"+date);
//        System.out.println("請假原因:"+reason);

        /** 2. 獲取流程變量,使用JavaBean類型 **/
        /**
         * 當一個javabean(實現序列)放置到流程變量中,要求javabean的屬性不能再發生變化,
         * 如果發生變化,在獲取的時候會拋出異常
         * 解決辦法加上版本號序列號
         */

        Person p = (Person) taskService.getVariable(taskId, "人員信息");
        System.out.println(p.toString());

    }

    /** 模擬設置和獲取流程變量的場景**/
    public void setAndGetVariables(){
        /** 與流程實例,執行對象(正在執行)**/
        RuntimeService runtimeService = processEngine.getRuntimeService();
        /** 與任務(正在執行)**/
        TaskService taskService = processEngine.getTaskService();

        /** 設置流程變量**/
//        runtimeService.setVariable(executionId,variableName,value);//表示執行對象id 和流程變量的名稱,設置流程變量的值(一次只能設置一個值)
//        runtimeService.setVariables(executionId,variables);//表示使用執行對象ID,和map集合設置流程變量。map集合的key就是流程變量名稱,map集合的value 就是流程變量的值(一次可以設置多個)

//        taskService.setVariable(taskId,variableName,value);//表示任務id 和流程變量的名稱,設置流程變量的值(一次只能設置一個值)
//        taskService.setVariables(taskId,variables);//表示使用任務ID,和map集合設置流程變量。map集合的key就是流程變量名稱,map集合的value 就是流程變量的值(一次可以設置多個)

//        runtimeService.startProcessInstanceByKey(processDefinitionKey,variables);//啓動流程實例的時候設置流程變量,使用map 集合
//        taskService.setVariables(taskId,variables);//完成任務的時候設置流程變量,使用map

        /** 獲取流程變量**/
//        runtimeService.getVariable(executionId,vaiableName);//根據執行對象id,和流程變量名稱 獲取流程變量值
//        runtimeService.getVariables(executionId);//使用執行對象ID,獲取所有的流程變量,將流程變量放置到map集合中
//        runtimeService.getVariables(executionId,vaiableNames);//使用執行對象Id,獲取流程變量的值,通過設置流程變量的名稱存放到集合中,獲取指定流程變量名稱的流程變量的值,值存放到map集合中


//        taskService.getVariable(taskId,vaiableName);//根據任務id,和流程變量名稱 獲取流程變量值
//        taskService.getVariables(taskId);//使用任務ID,獲取所有的流程變量,將流程變量放置到map集合中
//        taskService.getVariables(taskId,vaiableNames);//使用任務Id,獲取流程變量的值,通過設置流程變量的名稱存放到集合中,獲取指定流程變量名稱的流程變量的值,值存放到map集合中


    }

    /**
     * 查詢流程變量的歷史表
     */
    @Test
    public void findHistoryProcessVariables(){
        List<HistoricVariableInstance> list = processEngine.getHistoryService()//
                .createHistoricVariableInstanceQuery()//創建一個歷史的流程變量查詢對象
                .variableName("請假天數")
                .list();
        if(list!=null && list.size()>0){
            for(HistoricVariableInstance hvi :list){
                System.out.println(hvi.getId()+" "+hvi.getProcessInstanceId()+" "+hvi.getVariableTypeName()+" "+hvi.getVariableName()+" "+hvi.getValue());
                System.out.println("######################################################");
            }
        }
    }

    /**
     * 歷史流程實例
     */
    @Test
    public void findHistoryProcessInstance_(){
        String processInstanceId ="15001";
        HistoricProcessInstance hpi = processEngine.getHistoryService()//
                .createHistoricProcessInstanceQuery()//創建一個歷史的流程實例查詢對象
                .processInstanceId(processInstanceId)//使用流程實例ID查詢
                .singleResult();
        if(hpi!=null){
                System.out.println(hpi.getId()+" "+hpi.getProcessDefinitionId()+" "+hpi.getStartTime()+" "+hpi.getEndTime());

        }
    }

    /**
     * 查詢歷史活動
     */
    @Test
    public void findHistoryActiviti(){
        String processInstanceId ="15001";
        List<HistoricActivityInstance> list = processEngine.getHistoryService()
                .createHistoricActivityInstanceQuery()//創建歷史活動實例查詢對象
                .processInstanceId(processInstanceId)
                .orderByHistoricActivityInstanceStartTime().asc()
                .list();
        if(list!=null && list.size()>0){
            for(HistoricActivityInstance hai:list){
                System.out.println(hai.getId()+" "+hai.getProcessInstanceId()+ " "+hai.getStartTime()+" "+hai.getEndTime()+" "+hai.getDurationInMillis());
                System.out.println("####################################################");
            }
        }
    }

    /**
     * 查詢歷任務
     */
    @Test
    public void findHistoryTask_(){
//        String taskAssignee ="";
        String processInstanceId = "15001";
        List<HistoricTaskInstance> list = processEngine.getHistoryService()//與歷史數據(歷史表)相關的service
                .createHistoricTaskInstanceQuery()//創建歷史任務實例查詢
//                .taskAssignee(taskAssignee)//指定歷史任務的辦理人
                .processInstanceId(processInstanceId)
                .orderByHistoricTaskInstanceStartTime().asc()
                .list();
        if(list!= null && list.size()>0){
            for(HistoricTaskInstance hti:list){
                System.out.println(hti.getId()+"  "+hti.getName()+" "+hti.getProcessDefinitionId()+" "+hti.getStartTime()+" "+hti.getEndTime());
            }
        }
    }
}
package com.demo.activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

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

/**
 * 線條
 */
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class SequenceFlowTest {
    private Logger logger = LoggerFactory.getLogger(SequenceFlowTest.class);

    /**
     * 默認方式獲取  流程引擎對象
     */
    @Autowired
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 部署流程定義
     */
    @Test
    public void deployment() {
        //與流程定義和流程部署相關的service
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment() //創建一個部署對象
                .name("連線") //添加部署的名稱
                .addClasspathResource("workflow/sequenceFlow.bpmn")//從classpath加載資源文件 一次只能加載一個文件
                .addClasspathResource("workflow/sequenceFlow.png")
                .deploy();//完成部署
        logger.info("id:" + deploy.getId());//1
        logger.info("id:" + deploy.getName());//對應的表act_re_procdef() act_re_deployment(部署表) act_ge_bytearray (二進制表) act_ge_property(版本號控制的)
    }

    /**
     * 啓動流程實例
     */
    @Test
    public void startProcessInstance() {
        //流程頂定義的key
        String processDefinitionKey = "sequenceFlow";
        //返回流程實例對象
        ProcessInstance processInstance = processEngine.getRuntimeService() //正在執行的流程實例和執行對象相關的對象--執行管理 ,包括啓動 推進 刪除流程實例等操作
                .startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key 啓動實例,key 爲bpmn 文件id 的屬性值myProcess  或者 流程定義表:act_re_procdef 表中的key
        //默認使用的最新版本的流程定義啓動
        logger.info("流程實例id:"+processInstance.getId());//流程實例id:2501
        logger.info("流程定義id:"+processInstance.getProcessDefinitionId());//流程定義id:myProcess:1:4
        //act_ru_execution  act_ru_task  act_ru_identitylink  act_ru_execution  act_hi_taskinst  act_hi_procinst  act_hi_identitylink act_hi_actinst
    }

    /**
     * 查詢當前人的個人任務
     */
    @Test
    public void findMyPersonProcessTask(){
        String assignee = "趙六";//張三 李四 趙六
        //任務管理
        List<Task> list = processEngine.getTaskService() //與任務相關的service
                .createTaskQuery()
                .taskAssignee(assignee) //指定個人任務查詢 指定辦理人  act_ru_task
                .list();
        if(list!= null && list.size()>0){
            for(Task task:list){
                logger.info("任務id:"+task.getId());//任務id:2505  任務id:5002
                logger.info("任務名稱:"+task.getName());//任務名稱:提交申請  任務名稱:部門審批
                logger.info("任務的創建時間:"+task.getCreateTime());//任務的創建時間:Tue Apr 14 18:08:52 CST 2020  任務的創建時間:Tue Apr 14 18:42:29 CST 20
                logger.info("任務的辦理人:"+task.getAssignee());//任務的辦理人:張三 任務的辦理人:李四
                logger.info("流程實例Id:"+task.getProcessInstanceId());//流程實例Id:2501  流程實例Id:2501
                logger.info("執行對象Id:"+task.getExecutionId());//執行對象Id:2502 執行對象Id:2502
                logger.info("流程定義Id:"+task.getProcessDefinitionId());//流程定義Id:myProcess:1:4 流程定義Id:myProcess:1:4
                logger.info("***********************************************");
            }
        }
    }

    /**
     * 完成我的任務
     */
    @Test
    public void completeMyPersonTask(){
        //任務id
        String taskId = "60004"; //50005  57505  60004
        //完成任務的同時 設置流程變量  使用流程變量用來指定完成任務後 下一個連線,對應sequenceFlow.bpmn 文件中的 #{message=='不重要'}
        Map<String,Object> variables = new HashMap<String,Object>();
        variables.put("message","重要");
        processEngine.getTaskService() //與任務相關的service
                .complete(taskId,variables); //完成任務
        logger.info("完成任務,任務id:"+taskId); //完成任務,任務id:5002

    }
}
package com.demo.activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

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

/**
 * 排他網關
 */
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class ExclusiveGaeWayTest {
    private Logger logger = LoggerFactory.getLogger(ExclusiveGaeWayTest.class);

    /**
     * 默認方式獲取  流程引擎對象
     */
    @Autowired
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 部署流程定義
     */
    @Test
    public void deployment() {
        //與流程定義和流程部署相關的service
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment() //創建一個部署對象
                .name("排他網關") //添加部署的名稱
                .addClasspathResource("workflow/exclusiveGaeWay.bpmn")//從classpath加載資源文件 一次只能加載一個文件
                .addClasspathResource("workflow/exclusiveGaeWay.png")
                .deploy();//完成部署
        logger.info("id:" + deploy.getId());//1
        logger.info("id:" + deploy.getName());//對應的表act_re_procdef() act_re_deployment(部署表) act_ge_bytearray (二進制表) act_ge_property(版本號控制的)
    }

    /**
     * 啓動流程實例
     */
    @Test
    public void startProcessInstance() {
        //流程頂定義的key
        String processDefinitionKey = "exclusiveGaeWay";
        //返回流程實例對象
        ProcessInstance processInstance = processEngine.getRuntimeService() //正在執行的流程實例和執行對象相關的對象--執行管理 ,包括啓動 推進 刪除流程實例等操作
                .startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key 啓動實例,key 爲bpmn 文件id 的屬性值myProcess  或者 流程定義表:act_re_procdef 表中的key
        //默認使用的最新版本的流程定義啓動
        logger.info("流程實例id:"+processInstance.getId());//流程實例id:2501
        logger.info("流程定義id:"+processInstance.getProcessDefinitionId());//流程定義id:myProcess:1:4
        //act_ru_execution  act_ru_task  act_ru_identitylink  act_ru_execution  act_hi_taskinst  act_hi_procinst  act_hi_identitylink act_hi_actinst
    }

    /**
     * 查詢當前人的個人任務
     */
    @Test
    public void findMyPersonProcessTask(){
        String assignee = "趙小六";//王小五 胡小八  趙小六
        //任務管理
        List<Task> list = processEngine.getTaskService() //與任務相關的service
                .createTaskQuery()
                .taskAssignee(assignee) //指定個人任務查詢 指定辦理人  act_ru_task
                .list();
        if(list!= null && list.size()>0){
            for(Task task:list){
                logger.info("任務id:"+task.getId());//任務id:2505  任務id:5002
                logger.info("任務名稱:"+task.getName());//任務名稱:提交申請  任務名稱:部門審批
                logger.info("任務的創建時間:"+task.getCreateTime());//任務的創建時間:Tue Apr 14 18:08:52 CST 2020  任務的創建時間:Tue Apr 14 18:42:29 CST 20
                logger.info("任務的辦理人:"+task.getAssignee());//任務的辦理人:張三 任務的辦理人:李四
                logger.info("流程實例Id:"+task.getProcessInstanceId());//流程實例Id:2501  流程實例Id:2501
                logger.info("執行對象Id:"+task.getExecutionId());//執行對象Id:2502 執行對象Id:2502
                logger.info("流程定義Id:"+task.getProcessDefinitionId());//流程定義Id:myProcess:1:4 流程定義Id:myProcess:1:4
                logger.info("***********************************************");
            }
        }
    }

    /**
     * 完成我的任務
     */
    @Test
    public void completeMyPersonTask(){
        //任務id
        String taskId = "85005"; //72505  75005   82505  85005
        //完成任務的同時 設置流程變量  使用流程變量用來指定完成任務後 下一個連線,對應sequenceFlow.bpmn 文件中的 #{message=='不重要'}
        Map<String,Object> variables = new HashMap<String,Object>();
        variables.put("money",800);
        processEngine.getTaskService() //與任務相關的service
                .complete(taskId,variables); //完成任務
        logger.info("完成任務,任務id:"+taskId); //完成任務,任務id:5002

    }

}
package com.demo.activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

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

/**
 * 並行網關
 */
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class PalallelGateWayTest {
    private Logger logger = LoggerFactory.getLogger(PalallelGateWayTest.class);

    /**
     * 默認方式獲取  流程引擎對象
     */
    @Autowired
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 部署流程定義
     */
    @Test
    public void deployment() {
        //與流程定義和流程部署相關的service
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment() //創建一個部署對象
                .name("並行網關") //添加部署的名稱
                .addClasspathResource("workflow/parallelGateWay.bpmn")//從classpath加載資源文件 一次只能加載一個文件
//                .addClasspathResource("workflow/parallelGateWay.png")
                .deploy();//完成部署
        logger.info("id:" + deploy.getId());//1
        logger.info("id:" + deploy.getName());//對應的表act_re_procdef() act_re_deployment(部署表) act_ge_bytearray (二進制表) act_ge_property(版本號控制的)
    }

    /**
     * 啓動流程實例
     */
    @Test
    public void startProcessInstance() {
        //流程頂定義的key
        String processDefinitionKey = "parallelGateWay";
        //返回流程實例對象
        ProcessInstance processInstance = processEngine.getRuntimeService() //正在執行的流程實例和執行對象相關的對象--執行管理 ,包括啓動 推進 刪除流程實例等操作
                .startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key 啓動實例,key 爲bpmn 文件id 的屬性值myProcess  或者 流程定義表:act_re_procdef 表中的key
        //默認使用的最新版本的流程定義啓動
        logger.info("流程實例id:"+processInstance.getId());//流程實例id:2501
        logger.info("流程定義id:"+processInstance.getProcessDefinitionId());//流程定義id:myProcess:1:4
        //act_ru_execution  act_ru_task  act_ru_identitylink  act_ru_execution  act_hi_taskinst  act_hi_procinst  act_hi_identitylink act_hi_actinst
    }

    /**
     * 查詢當前人的個人任務
     */
    @Test
    public void findMyPersonProcessTask(){
        String assignee = "趙小六";//王小五 胡小八  趙小六
        //任務管理
        List<Task> list = processEngine.getTaskService() //與任務相關的service
                .createTaskQuery()
                .taskAssignee(assignee) //指定個人任務查詢 指定辦理人  act_ru_task
                .list();
        if(list!= null && list.size()>0){
            for(Task task:list){
                logger.info("任務id:"+task.getId());//任務id:2505  任務id:5002
                logger.info("任務名稱:"+task.getName());//任務名稱:提交申請  任務名稱:部門審批
                logger.info("任務的創建時間:"+task.getCreateTime());//任務的創建時間:Tue Apr 14 18:08:52 CST 2020  任務的創建時間:Tue Apr 14 18:42:29 CST 20
                logger.info("任務的辦理人:"+task.getAssignee());//任務的辦理人:張三 任務的辦理人:李四
                logger.info("流程實例Id:"+task.getProcessInstanceId());//流程實例Id:2501  流程實例Id:2501
                logger.info("執行對象Id:"+task.getExecutionId());//執行對象Id:2502 執行對象Id:2502
                logger.info("流程定義Id:"+task.getProcessDefinitionId());//流程定義Id:myProcess:1:4 流程定義Id:myProcess:1:4
                logger.info("***********************************************");
            }
        }
    }

    /**
     * 完成我的任務
     */
    @Test
    public void completeMyPersonTask(){
        //任務id
        String taskId = "95004"; //92507   92509  95004  97503
        //完成任務的同時 設置流程變量  使用流程變量用來指定完成任務後 下一個連線,對應sequenceFlow.bpmn 文件中的 #{message=='不重要'}
        Map<String,Object> variables = new HashMap<String,Object>();
        variables.put("money",800);
        processEngine.getTaskService() //與任務相關的service
                .complete(taskId,variables); //完成任務
        logger.info("完成任務,任務id:"+taskId); //完成任務,任務id:5002

    }

}
package com.demo.activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

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

/**
 * 個人任務
 */
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class Person1TaskTest {
    private Logger logger = LoggerFactory.getLogger(Person1TaskTest.class);

    /**
     * 默認方式獲取  流程引擎對象
     */
    @Autowired
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 部署流程定義
     */
    @Test
    public void deployment() {
        //與流程定義和流程部署相關的service
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment() //創建一個部署對象
                .name("個人任務") //添加部署的名稱
                .addClasspathResource("workflow/person1Task.bpmn")//從classpath加載資源文件 一次只能加載一個文件
//                .addClasspathResource("workflow/exclusiveGaeWay.png")
                .deploy();//完成部署
        logger.info("id:" + deploy.getId());//1
        logger.info("id:" + deploy.getName());//對應的表act_re_procdef() act_re_deployment(部署表) act_ge_bytearray (二進制表) act_ge_property(版本號控制的)
    }

    /**
     * 啓動流程實例
     */
    @Test
    public void startProcessInstance() {
        //流程頂定義的key
        String processDefinitionKey = "person1Task";
        /** 啓動流程實例的同時,設置流程變量**/
        Map<String,Object> variables = new HashMap<String,Object>();//userId-->流程變量
        variables.put("userId","周芷若");
        //返回流程實例對象
        ProcessInstance processInstance = processEngine.getRuntimeService() //正在執行的流程實例和執行對象相關的對象--執行管理 ,包括啓動 推進 刪除流程實例等操作
                .startProcessInstanceByKey(processDefinitionKey,variables);//使用流程定義的key 啓動實例,key 爲bpmn 文件id 的屬性值myProcess  或者 流程定義表:act_re_procdef 表中的key
        //默認使用的最新版本的流程定義啓動
        logger.info("流程實例id:"+processInstance.getId());//流程實例id:2501
        logger.info("流程定義id:"+processInstance.getProcessDefinitionId());//流程定義id:myProcess:1:4
        //act_ru_execution  act_ru_task  act_ru_identitylink  act_ru_execution  act_hi_taskinst  act_hi_procinst  act_hi_identitylink act_hi_actinst
    }

    /**
     * 查詢當前人的個人任務
     */
    @Test
    public void findMyPersonProcessTask(){
        String assignee = "周芷若";//張三丰  周芷若
        //任務管理
        List<Task> list = processEngine.getTaskService() //與任務相關的service
                .createTaskQuery()
                .taskAssignee(assignee) //指定個人任務查詢 指定辦理人  act_ru_task
                .list();
        if(list!= null && list.size()>0){
            for(Task task:list){
                logger.info("任務id:"+task.getId());//任務id:2505  任務id:5002
                logger.info("任務名稱:"+task.getName());//任務名稱:提交申請  任務名稱:部門審批
                logger.info("任務的創建時間:"+task.getCreateTime());//任務的創建時間:Tue Apr 14 18:08:52 CST 2020  任務的創建時間:Tue Apr 14 18:42:29 CST 20
                logger.info("任務的辦理人:"+task.getAssignee());//任務的辦理人:張三 任務的辦理人:李四
                logger.info("流程實例Id:"+task.getProcessInstanceId());//流程實例Id:2501  流程實例Id:2501
                logger.info("執行對象Id:"+task.getExecutionId());//執行對象Id:2502 執行對象Id:2502
                logger.info("流程定義Id:"+task.getProcessDefinitionId());//流程定義Id:myProcess:1:4 流程定義Id:myProcess:1:4
                logger.info("***********************************************");
            }
        }
    }

    /**
     * 完成我的任務
     */
    @Test
    public void completeMyPersonTask(){
        //任務id
        String taskId = "127507"; //72505  75005   82505  85005 127507
        //完成任務的同時 設置流程變量  使用流程變量用來指定完成任務後 下一個連線,對應sequenceFlow.bpmn 文件中的 #{message=='不重要'}
        Map<String,Object> variables = new HashMap<String,Object>();
        variables.put("hahaha","哈哈哈");
        processEngine.getTaskService() //與任務相關的service
                .complete(taskId,variables); //完成任務
        logger.info("完成任務,任務id:"+taskId); //完成任務,任務id:5002

    }
    /**
     * 刪除流程定義
     */
    @Test
    public void deleteaProcessDefinition(){
        String deploymentId = "110001";
        //使用部署ID 完成刪除
//        processEngine.getRepositoryService()//
//        .deleteDeployment(deploymentId); //不能級聯刪除,只能刪除沒有啓動的流程,如果流程啓動就會拋異常

        //不管流程是否啓動,都能刪除
        processEngine.getRepositoryService()//

                .deleteDeployment(deploymentId,true);//默認是false  實現級聯刪除。
    }
}
package com.demo.activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

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

/**
 * 個人任務
 */
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class Person2TaskTest {
    private Logger logger = LoggerFactory.getLogger(Person2TaskTest.class);

    /**
     * 默認方式獲取  流程引擎對象
     */
    @Autowired
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 部署流程定義
     */
    @Test
    public void deployment() {
        //與流程定義和流程部署相關的service
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment() //創建一個部署對象
                .name("個人任務2") //添加部署的名稱
                .addClasspathResource("workflow/person2Task.bpmn")//從classpath加載資源文件 一次只能加載一個文件
//                .addClasspathResource("workflow/exclusiveGaeWay.png")
                .deploy();//完成部署
        logger.info("id:" + deploy.getId());//1
        logger.info("id:" + deploy.getName());//對應的表act_re_procdef() act_re_deployment(部署表) act_ge_bytearray (二進制表) act_ge_property(版本號控制的)
    }

    /**
     * 啓動流程實例
     */
    @Test
    public void startProcessInstance() {
        //流程頂定義的key
        String processDefinitionKey = "person2Task";
        /** 啓動流程實例的同時,設置流程變量**/
//        Map<String,Object> variables = new HashMap<String,Object>();//userId-->流程變量
//        variables.put("userId","周芷若");
        //返回流程實例對象
        ProcessInstance processInstance = processEngine.getRuntimeService() //正在執行的流程實例和執行對象相關的對象--執行管理 ,包括啓動 推進 刪除流程實例等操作
                .startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key 啓動實例,key 爲bpmn 文件id 的屬性值myProcess  或者 流程定義表:act_re_procdef 表中的key
        //默認使用的最新版本的流程定義啓動
        logger.info("流程實例id:"+processInstance.getId());//流程實例id:2501
        logger.info("流程定義id:"+processInstance.getProcessDefinitionId());//流程定義id:myProcess:1:4
        //act_ru_execution  act_ru_task  act_ru_identitylink  act_ru_execution  act_hi_taskinst  act_hi_procinst  act_hi_identitylink act_hi_actinst
    }

    /**
     * 查詢當前人的個人任務
     */
    @Test
    public void findMyPersonProcessTask(){
        String assignee = "張翠山";//張三丰  周芷若 張翠山
        //任務管理
        List<Task> list = processEngine.getTaskService() //與任務相關的service
                .createTaskQuery()
                .taskAssignee(assignee) //指定個人任務查詢 指定辦理人  act_ru_task
                .list();
        if(list!= null && list.size()>0){
            for(Task task:list){
                logger.info("任務id:"+task.getId());//任務id:2505  任務id:5002
                logger.info("任務名稱:"+task.getName());//任務名稱:提交申請  任務名稱:部門審批
                logger.info("任務的創建時間:"+task.getCreateTime());//任務的創建時間:Tue Apr 14 18:08:52 CST 2020  任務的創建時間:Tue Apr 14 18:42:29 CST 20
                logger.info("任務的辦理人:"+task.getAssignee());//任務的辦理人:張三 任務的辦理人:李四
                logger.info("流程實例Id:"+task.getProcessInstanceId());//流程實例Id:2501  流程實例Id:2501
                logger.info("執行對象Id:"+task.getExecutionId());//執行對象Id:2502 執行對象Id:2502
                logger.info("流程定義Id:"+task.getProcessDefinitionId());//流程定義Id:myProcess:1:4 流程定義Id:myProcess:1:4
                logger.info("***********************************************");
            }
        }
    }

    /**
     * 完成我的任務
     */
    @Test
    public void completeMyPersonTask(){
        //任務id
        String taskId = "147505"; //72505  75005   82505  85005 127507  142505 147505
        //完成任務的同時 設置流程變量  使用流程變量用來指定完成任務後 下一個連線,對應sequenceFlow.bpmn 文件中的 #{message=='不重要'}
//        Map<String,Object> variables = new HashMap<String,Object>();
//        variables.put("hahaha","哈哈哈");
        processEngine.getTaskService() //與任務相關的service
                .complete(taskId);
//                .complete(taskId,variables); //完成任務
        logger.info("完成任務,任務id:"+taskId); //完成任務,任務id:5002

    }

    /**
     * 可以分配個人任務從一個人到另一個人(認領任務)
     */
    @Test
    public void setAssigneeTask(){
        /** 任務ID  和指定辦理人ID**/
        String taskId ="147505";
        String userId ="張翠山";
        processEngine.getTaskService()
                .setAssignee(taskId,userId);
    }

    /**
     * 刪除流程定義
     */
    @Test
    public void deleteaProcessDefinition(){
        String deploymentId = "137501";
        //使用部署ID 完成刪除
//        processEngine.getRepositoryService()//
//        .deleteDeployment(deploymentId); //不能級聯刪除,只能刪除沒有啓動的流程,如果流程啓動就會拋異常

        //不管流程是否啓動,都能刪除
        processEngine.getRepositoryService()//

                .deleteDeployment(deploymentId,true);//默認是false  實現級聯刪除。
    }
}
package com.demo.activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

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

/**
 * 接收任務活動 即等待活動
 */
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class ReceiveTaskTest {
    private Logger logger = LoggerFactory.getLogger(ReceiveTaskTest.class);

    /**
     * 默認方式獲取  流程引擎對象
     */
    @Autowired
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 部署流程定義
     */
    @Test
    public void deployment() {
        //與流程定義和流程部署相關的service
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment() //創建一個部署對象
                .name("接收活動") //添加部署的名稱
                .addClasspathResource("workflow/receiveTask.bpmn")//從classpath加載資源文件 一次只能加載一個文件
//                .addClasspathResource("workflow/sequenceFlow.png")
                .deploy();//完成部署
        logger.info("id:" + deploy.getId());//1
        logger.info("id:" + deploy.getName());//對應的表act_re_procdef() act_re_deployment(部署表) act_ge_bytearray (二進制表) act_ge_property(版本號控制的)
    }

    /**
     * 啓動流程實例,設置流程變量 獲取流程變量 向後執行一步
     */
    @Test
    public void startProcessInstance() {
        //流程頂定義的key
        String processDefinitionKey = "receiveTask";
        //返回流程實例對象
        ProcessInstance processInstance = processEngine.getRuntimeService() //正在執行的流程實例和執行對象相關的對象--執行管理 ,包括啓動 推進 刪除流程實例等操作
                .startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key 啓動實例,key 爲bpmn 文件id 的屬性值myProcess  或者 流程定義表:act_re_procdef 表中的key
        //默認使用的最新版本的流程定義啓動
        logger.info("流程實例id:" + processInstance.getId());//流程實例id:2501
        logger.info("流程定義id:" + processInstance.getProcessDefinitionId());//流程定義id:myProcess:1:4
        //act_ru_execution  act_ru_task  act_ru_identitylink  act_ru_execution  act_hi_taskinst  act_hi_procinst  act_hi_identitylink act_hi_actinst
        /** 查詢執行對象ID**/
        String processInstanceId = processInstance.getId();
        String activityId = "_4";
        Execution execution = processEngine.getRuntimeService()
                .createExecutionQuery()//創建執行對象查詢
                .processInstanceId(processInstanceId)
                .activityId(activityId)//當前活動Id,對應bpmn文件中的活動節點Id的值(receiveTask-->id)
                .singleResult();
/**使用流程變量設置當日銷售額 用來傳遞業務參數*/
        String executionId = execution.getId();
        processEngine.getRuntimeService()
                .setVariable(executionId, "彙總當日銷售額", 21000);

        /** 向後執行一步,如果流程處於等待狀態,使得流程繼續執行**/
        processEngine.getRuntimeService()
                .signalEventReceived(executionId);

        /** 流程變量中獲取彙總當日銷售額的值 **/
        String variableName = "彙總當日銷售額";
        Integer value = (Integer) processEngine.getRuntimeService()
                .getVariable(executionId, variableName);

        System.out.println("給老闆發送短信:金額是:"+value);

        /**查詢執行對象ID*/
        Execution execution2 = processEngine.getRuntimeService()
                .createExecutionQuery()//創建執行對象查詢
                .processInstanceId(processInstanceId)//使用流程實例ID查詢
                .activityId("_5")//當前活動的id,對應receiveTask.bpmn文件中的活動節點的id的屬性值
                .singleResult();
        /** 向後執行一步,如果流程處於等待狀態,使得流程繼續執行**/
        processEngine.getRuntimeService()
                .signalEventReceived(execution2.getId());
    }

    /**
     * 查詢當前人的個人任務
     */
    @Test
    public void findMyPersonProcessTask() {
        String assignee = "趙六";//張三 李四 趙六
        //任務管理
        List<Task> list = processEngine.getTaskService() //與任務相關的service
                .createTaskQuery()
                .taskAssignee(assignee) //指定個人任務查詢 指定辦理人  act_ru_task
                .list();
        if (list != null && list.size() > 0) {
            for (Task task : list) {
                logger.info("任務id:" + task.getId());//任務id:2505  任務id:5002
                logger.info("任務名稱:" + task.getName());//任務名稱:提交申請  任務名稱:部門審批
                logger.info("任務的創建時間:" + task.getCreateTime());//任務的創建時間:Tue Apr 14 18:08:52 CST 2020  任務的創建時間:Tue Apr 14 18:42:29 CST 20
                logger.info("任務的辦理人:" + task.getAssignee());//任務的辦理人:張三 任務的辦理人:李四
                logger.info("流程實例Id:" + task.getProcessInstanceId());//流程實例Id:2501  流程實例Id:2501
                logger.info("執行對象Id:" + task.getExecutionId());//執行對象Id:2502 執行對象Id:2502
                logger.info("流程定義Id:" + task.getProcessDefinitionId());//流程定義Id:myProcess:1:4 流程定義Id:myProcess:1:4
                logger.info("***********************************************");
            }
        }
    }

    /**
     * 完成我的任務
     */
    @Test
    public void completeMyPersonTask() {
        //任務id
        String taskId = "60004"; //50005  57505  60004
        //完成任務的同時 設置流程變量  使用流程變量用來指定完成任務後 下一個連線,對應sequenceFlow.bpmn 文件中的 #{message=='不重要'}
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("message", "重要");
        processEngine.getTaskService() //與任務相關的service
                .complete(taskId, variables); //完成任務
        logger.info("完成任務,任務id:" + taskId); //完成任務,任務id:5002

    }
}
package com.demo.activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.history.HistoricIdentityLink;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

/**
 * 組任務
 */
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class GroupTaskTest {
    private Logger logger = LoggerFactory.getLogger(GroupTaskTest.class);

    /**
     * 默認方式獲取  流程引擎對象
     */
    @Autowired
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 部署流程定義
     */
    @Test
    public void deployment() {
        //與流程定義和流程部署相關的service
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment() //創建一個部署對象
                .name("組任務") //添加部署的名稱
                .addClasspathResource("workflow/groupTask.bpmn")//從classpath加載資源文件 一次只能加載一個文件
//                .addClasspathResource("workflow/exclusiveGaeWay.png")
                .deploy();//完成部署
        logger.info("id:" + deploy.getId());//1
        logger.info("id:" + deploy.getName());//對應的表act_re_procdef() act_re_deployment(部署表) act_ge_bytearray (二進制表) act_ge_property(版本號控制的)
    }

    /**
     * 啓動流程實例
     */
    @Test
    public void startProcessInstance() {
        //流程頂定義的key
        String processDefinitionKey = "groupTask";
        /** 啓動流程實例的同時,設置流程變量**/
//        Map<String,Object> variables = new HashMap<String,Object>();//userId-->流程變量
//        variables.put("userId","周芷若");
        //返回流程實例對象
        ProcessInstance processInstance = processEngine.getRuntimeService() //正在執行的流程實例和執行對象相關的對象--執行管理 ,包括啓動 推進 刪除流程實例等操作
                .startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key 啓動實例,key 爲bpmn 文件id 的屬性值myProcess  或者 流程定義表:act_re_procdef 表中的key
        //默認使用的最新版本的流程定義啓動
        logger.info("流程實例id:"+processInstance.getId());//流程實例id:2501
        logger.info("流程定義id:"+processInstance.getProcessDefinitionId());//流程定義id:myProcess:1:4
        //act_ru_execution  act_ru_task  act_ru_identitylink  act_ru_execution  act_hi_taskinst  act_hi_procinst  act_hi_identitylink act_hi_actinst
    }

    /**
     * 查詢當前人的個人任務/ 組任務和辦理人查詢
     */
    @Test
    public void findMyPersonProcessTask(){
//        String assignee = "張翠山";//張三丰  周芷若 張翠山
        String candidateUser = "小A";
        //任務管理
        List<Task> list = processEngine.getTaskService() //與任務相關的service
                .createTaskQuery()
//                .taskAssignee(assignee) //指定個人任務查詢 指定辦理人  act_ru_task
                .taskCandidateUser(candidateUser)//組任務和辦理人查詢
                .list();
        if(list!= null && list.size()>0){
            for(Task task:list){
                logger.info("任務id:"+task.getId());//任務id:2505  任務id:5002
                logger.info("任務名稱:"+task.getName());//任務名稱:提交申請  任務名稱:部門審批
                logger.info("任務的創建時間:"+task.getCreateTime());//任務的創建時間:Tue Apr 14 18:08:52 CST 2020  任務的創建時間:Tue Apr 14 18:42:29 CST 20
                logger.info("任務的辦理人:"+task.getAssignee());//任務的辦理人:張三 任務的辦理人:李四
                logger.info("流程實例Id:"+task.getProcessInstanceId());//流程實例Id:2501  流程實例Id:2501
                logger.info("執行對象Id:"+task.getExecutionId());//執行對象Id:2502 執行對象Id:2502
                logger.info("流程定義Id:"+task.getProcessDefinitionId());//流程定義Id:myProcess:1:4 流程定義Id:myProcess:1:4
                logger.info("***********************************************");
            }
        }
    }

    /** 查詢正在執行的辦理人表**/
    @Test
    public void findRunPeronsTask(){
        String taskId = "";
        List<IdentityLink> list = processEngine.getTaskService()
                .getIdentityLinksForTask(taskId);
        if(list!=null && list.size()>0){
            for(IdentityLink d:list){
                System.out.println(d.getTaskId()+" "+d.getType()+" "+d.getProcessInstanceId()+" "+d.getUserId());
            }
        }

    }

    /** 查詢歷史任務的辦理人表**/
    @Test
    public void findHisPeronsTask(){
        //流程實例ID
        String processInstanceId ="";
        List<HistoricIdentityLink> list = processEngine.getHistoryService()
                .getHistoricIdentityLinksForProcessInstance(processInstanceId);
        if(list!=null && list.size()>0){
            for(HistoricIdentityLink h:list){
                System.out.println(h.getTaskId()+" "+h.getType()+ " "+h.getUserId());
            }
        }

    }

    /** 拾取任務,將組任務分給個人任務,指定任務的辦理人字段**/
    @Test
    public void claim(){
        //將組任務分配給個人任務
        //任務id
        String taskId = "165005";//165005
        //分配個人任務,可以是組任務中的成員,也可以是非組任務的成員
        String userId ="大F";
        processEngine.getTaskService()
                .claim(taskId,userId);

    }

    /** 將個人任務回退到組任務,前提之前一定是組任務**/
    @Test
    public void setAssigee(){
//任務id
        String taskId = "165005";//165005
        processEngine.getTaskService()
                .setAssignee(taskId,null);
    }

    /** 向組任務中添加成員**/
    @Test
    public void addGroupUser(){
        //任務ID
        String taskId = "165005";
        //成員ID
        String userId = "大H";
        processEngine.getTaskService()
                .addCandidateUser(taskId,userId);
    }

    /** 從組任務中刪除成員**/
    @Test
    public void deleteGroupUser(){
//任務ID
        String taskId = "165005";
        //成員ID
        String userId = "大H";
        processEngine.getTaskService()
                .deleteCandidateUser(taskId,userId);
    }

    /**
     * 完成我的任務
     */
    @Test
    public void completeMyPersonTask(){
        //任務id
        String taskId = "147505"; //72505  75005   82505  85005 127507  142505 147505
        //完成任務的同時 設置流程變量  使用流程變量用來指定完成任務後 下一個連線,對應sequenceFlow.bpmn 文件中的 #{message=='不重要'}
//        Map<String,Object> variables = new HashMap<String,Object>();
//        variables.put("hahaha","哈哈哈");
        processEngine.getTaskService() //與任務相關的service
                .complete(taskId);
//                .complete(taskId,variables); //完成任務
        logger.info("完成任務,任務id:"+taskId); //完成任務,任務id:5002

    }

    /**
     * 可以分配個人任務從一個人到另一個人(認領任務)
     */
    @Test
    public void setAssigneeTask(){
        /** 任務ID  和指定辦理人ID**/
        String taskId ="147505";
        String userId ="張翠山";
        processEngine.getTaskService()
                .setAssignee(taskId,userId);
    }

    /**
     * 刪除流程定義
     */
    @Test
    public void deleteaProcessDefinition(){
        String deploymentId = "157501";
        //使用部署ID 完成刪除
//        processEngine.getRepositoryService()//
//        .deleteDeployment(deploymentId); //不能級聯刪除,只能刪除沒有啓動的流程,如果流程啓動就會拋異常

        //不管流程是否啓動,都能刪除
        processEngine.getRepositoryService()//

                .deleteDeployment(deploymentId,true);//默認是false  實現級聯刪除。
    }
}

項目源碼連接https://download.csdn.net/download/weixin_39209728/12395117

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章