国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

activiti7入門教程

這篇具有很好參考價值的文章主要介紹了activiti7入門教程。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、相關概念

  1. 工作流概念

    工作流是指業(yè)務過程的部分或整體在計算機應用環(huán)境下的自動化。是對工作流程及其各操作步驟之間業(yè)務規(guī)則的抽象、概括描述。

  2. activiti介紹

    activiti是一個工作流引擎,可以將業(yè)務系統(tǒng)中復雜的業(yè)務流程抽取出來,使用專門的建模語言BPMN進行定義,業(yè)務流程按照預先定義的流程進行執(zhí)行。實現(xiàn)了系統(tǒng)的流程由activiti進行管理,減少業(yè)務系統(tǒng)由于流程變更進行系統(tǒng)升級改造的工作流量,從而提高系統(tǒng)的健壯性,同時也減少了系統(tǒng)開發(fā)維護成本。

  3. BPM(Business Process Management)

    業(yè)務流程管理

  4. BPM軟件

    通過BPM軟件可以實現(xiàn)對業(yè)務流程的整個生命周期進行建模、自動化、管理監(jiān)控和優(yōu)化。

  5. BPMN(Business Process MOdel And Notation 業(yè)務流程模型和符號)

    業(yè)務流程模型和符號,是由BPMI開發(fā)的一套標準的業(yè)務流程建模符號,使用BPMN提供的符號可以創(chuàng)建業(yè)務流程。

  6. ProcessDefinition:流程定義

  7. ProcessInstance:流程實例

二、使用步驟

  1. 部署activiti

    activiti是一個工作流程,業(yè)務系統(tǒng)訪問activiti的接口,就可以方便操作流程間的相關數(shù)據(jù),這樣就可以把工作流環(huán)境和業(yè)務系統(tǒng)的環(huán)境集成在一起。

  2. 流程定義

    使用activiti建模工具定義業(yè)務流程,生成.bpmn文件(通過xml定義業(yè)務流程)。

  3. 流程定義部署

    使用activiti提供的api把流程定義的內(nèi)容存儲起來,再Activiti執(zhí)行過中可以查詢的內(nèi)容。activiti執(zhí)行把流程定內(nèi)容存儲在數(shù)據(jù)庫中。

  4. 啟動一個流程實例

    流程實例也叫ProcessInstance

    啟動一個流程實例表示開始一次業(yè)務流程的執(zhí)行

    比如同一個流程,張三可以啟動,李四也可以啟動,但是兩次流程實例是互不影響的。

  5. 用戶查詢待辦任務

    由于集成了activiti,所有的任務都可以直接通過activiti提供的api進行查詢,不需要我們自己查庫。

  6. 用戶辦理任務

    流程辦理等操作,也是可以直接使用activiti提供的api即可。

  7. 流程結束

    當沒有下一個需要辦理的節(jié)點,說明任務就結束了。

三、activiti配置生成表

  1. idea軟件安裝actiBPM插件,若idea找不到插件,可去官網(wǎng)下載,導入即可,可參考

    https://blog.csdn.net/weixin_40496191/article/details/125097860

  2. pom配置

    <!-- springboot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- 工作流 -->
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-spring-boot-starter</artifactId>
        <version>7.1.0.M1</version>
    </dependency>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-json-converter</artifactId>
        <version>7.1.0.M1</version>
    </dependency>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-image-generator</artifactId>
        <version>7.1.0.M1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>batik-all</artifactId>
        <version>1.10</version>
    </dependency>
    
    <!-- 數(shù)據(jù)庫 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.2</version>
    </dependency>
    
  3. 配置文件配置activiti相關參數(shù)和數(shù)據(jù)庫信息

    server:
      port: 8080
    
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: tiger
        url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf-8 &allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8&nullCatalogMeansCurrent=true
        type: com.alibaba.druid.pool.DruidDataSource
        servlet:
          multipart:
            max-file-size: 100MB
            max-request-size: 100MB
      activiti:
        #    false:默認,數(shù)據(jù)庫表不變,但是如果版本不對或者缺失表會拋出異常(生產(chǎn)使用)
        #    true:表不存在,自動創(chuàng)建(開發(fā)使用)
        #    create_drop: 啟動時創(chuàng)建,關閉時刪除表(測試使用)
        #    drop_create: 啟動時刪除表,在創(chuàng)建表 (不需要手動關閉引擎)
        database-schema-update: true
        #監(jiān)測歷史表是否存在,activities7默認不開啟歷史表
        db-history-used: true
        #none:不保存任何歷史數(shù)據(jù),流程中這是最高效的
        #activity:只保存流程實例和流程行為
        #audit:除了activity,還保存全部的流程任務以及其屬性,audit為history默認值
        #full:除了audit、還保存其他全部流程相關的細節(jié)數(shù)據(jù),包括一些流程參數(shù)
        history-level: full
        #校驗流程文件,默認校驗resources下的process 文件夾的流程文件
        check-process-definitions: true
    
  4. 啟動項目,即可生成相關表

    activiti7,新手,數(shù)據(jù)庫,運維,大數(shù)據(jù)

  5. 相關表關系

    re表:流程定義和流程相關屬性

    ru表:運行時產(chǎn)生的數(shù)據(jù)

    hi表:歷史信息

    ge表:通用信息

activiti7,新手,數(shù)據(jù)庫,運維,大數(shù)據(jù)

四、簡單畫一個流程

  1. 畫圖

    創(chuàng)建demo.bpmn文件,簡單實現(xiàn)流程圖,id為“myLeave“,流程名稱為“員工請假審批流程”,責任人從上往下依次為worker、manager、financer。
    activiti7,新手,數(shù)據(jù)庫,運維,大數(shù)據(jù)

  2. 畫完圖后,可以將流程圖導出來

    1)復制一份新的文件,以xml結尾

    2)右鍵顯示圖標

    activiti7,新手,數(shù)據(jù)庫,運維,大數(shù)據(jù)
    3)導出png圖片
    activiti7,新手,數(shù)據(jù)庫,運維,大數(shù)據(jù)

五、activiti接口基礎api示例

1. 代碼創(chuàng)建流程

/**
 * 部署流程
 */
@RequestMapping("createProcesses")
@ResponseBody
public void createProcesses() {
    //使用獲取RepositoryService進行部署
    Deployment deployment = repositoryService.createDeployment()
        .addClasspathResource("static/bpmn/demo.bpmn")//添加bpmn資源
        .addClasspathResource("static/bpmn/demo.png")//添加png資源
        .name("員工請假審批流程")
        .deploy();//部署流程
    //輸出流程部署的信息
    System.out.println("流程部署id:" + deployment.getId());
    System.out.println("流程部署名稱:" + deployment.getName());
}

//結果:
//流程部署id:1fb480d0-0773-11ed-8dc3-005056c00001
//流程部署名稱:員工請假審批流程

執(zhí)行后可以去數(shù)據(jù)庫查看相關的表數(shù)據(jù)

act_re_deployment:查看相關的流程的創(chuàng)建

act_re_procdef:查看流程的定義

act_ge_bytearray:流程文件存儲

2. 查詢流程的定義

/**
 * 查詢流程的定義
 */
@RequestMapping("searchProcess")
@ResponseBody
public void searchProcess() {
    String key= "myLeave";
    //獲取ProcessDefinitionQuery對象,用來查詢操作
    ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
    List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey(key)
        .orderByProcessDefinitionVersion()//安裝版本信息
        .desc()//倒序
        .list();
    //輸出流程定義的信息
    for (ProcessDefinition processDefinition : list) {
        System.out.println("流程定義的id:" + processDefinition.getId());
        System.out.println("流程定義的name:" + processDefinition.getName());
        System.out.println("流程定義的key:" + processDefinition.getKey());
        System.out.println("流程定義的version:" + processDefinition.getVersion());
        System.out.println("流程部署的id:" + processDefinition.getDeploymentId());
        System.out.println("--------------------------------------------------");
    }

}

//結果
//相同key,則自動提升版本
//流程定義的id:myLeave:2:f6844e42-0774-11ed-96b3-005056c00001
//流程定義的name:員工請假審批流程
//流程定義的key:myLeave
//流程定義的version:2
//流程部署的id:f66888df-0774-11ed-96b3-005056c00001
//--------------------------------------------------
//流程定義的id:myLeave:1:fc307169-0773-11ed-9b87-005056c00001
//流程定義的name:員工請假審批流程
//流程定義的key:myLeave
//流程定義的version:1
//流程部署的id:fc1a2a46-0773-11ed-9b87-005056c00001
//--------------------------------------------------

3. 刪除流程

/**
 * 刪除流程
 */
@RequestMapping("deleteProcess")
@ResponseBody
public void deleteProcess() {
    String id = "f66888df-0774-11ed-96b3-005056c00001";
    //設置true,擇優(yōu)級聯(lián)刪除的效果。false如果已有實例,則會刪除錯誤
    repositoryService.deleteDeployment(id, true);
}

4. 獲取流程里面的資源文件

/**
 * 讀取數(shù)據(jù)庫中的資源文件
 */
@RequestMapping("searchProcesslFile")
@ResponseBody
public void searchProcesslFile() throws IOException {
    String id = "myLeave";
    //查詢器
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey(id)
        .singleResult();
    //獲取流程部署id
    String deploymentId = processDefinition.getDeploymentId();
    //通過repositoryService對象的相關方法來獲取圖片信息和bpmn信息
    //png圖片
    InputStream pngInput = repositoryService
        .getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
    //bpmn 文件的流
    InputStream bpmnInput = repositoryService
        .getResourceAsStream(deploymentId, processDefinition.getResourceName());
    //文件的保存
    File filePng = new File("E:/學習/activiti/evection.png");
    File fileBpmn = new File("E:/學習/activiti/evection.bpmn");
    OutputStream pngOut = new FileOutputStream(filePng);
    OutputStream bpmnOut = new FileOutputStream(fileBpmn);

    //輸入流和輸出流的轉化 
    IOUtils.copy(pngInput, pngOut);
    IOUtils.copy(bpmnInput, bpmnOut);
    pngInput.close();
    pngOut.close();
    bpmnInput.close();
    bpmnOut.close();

}

5. 創(chuàng)建流程實例

/**
 * 創(chuàng)建流程實例
 */
@RequestMapping("addApplication")
@ResponseBody
public void addApplication() {
    String businessKey = "myLeave";
    //啟動一個流程實例
    //ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(businessKey);
    //啟動一個流程實例,設置業(yè)務id,長度最大255,通過processInstance.getBusinessKey()獲取
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(businessKey,"businessKey");
    System.out.println("流程定義id:" + processInstance.getProcessDefinitionId());
    System.out.println("流程實例id:" + processInstance.getId());
    System.out.println("當前活動id:" + processInstance.getActivityId());
}

//結果:
//流程定義id:myLeave:2:a07c05cb-076f-11ed-afa5-005056c00001
//流程實例id:f6f5bf5a-0772-11ed-8dc3-005056c00001
//當前活動id:null

6. 查看流程底下存在哪些實例

/**
 * 查詢流程下存在哪些實例
 * 可通過.processInstanceId等相關屬性過濾
 */
@RequestMapping("searchProcessRunInstance")
@ResponseBody
public void searchProcessRunInstance() {
    String key = "myLeave";
    List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processDefinitionKey(key).list();
    //輸出流程定義的信息
    for (ProcessInstance processInstance : list) {
        System.out.println("流程實例id:" + processInstance.getProcessInstanceId());
        System.out.println("所屬流程定義id:" + processInstance.getProcessDefinitionId());
        System.out.println("是否完成:" + processInstance.isEnded());
        System.out.println("是否暫停:" + processInstance.isSuspended());
        System.out.println("當前活動標識:" + processInstance.getActivityId());
        System.out.println("業(yè)務關鍵字:" + processInstance.getBusinessKey());
        System.out.println("------------" );
    }

}

//結果:
//流程實例id:906f1e33-0776-11ed-96b3-005056c00001
//所屬流程定義id:myLeave:2:f6844e42-0774-11ed-96b3-005056c00001
//是否完成:false
//是否暫停:false
//當前活動標識:null
//業(yè)務關鍵字:null
//------------
//流程實例id:fece74da-0773-11ed-9b87-005056c00001
//所屬流程定義id:myLeave:1:fc307169-0773-11ed-9b87-005056c00001
//是否完成:false
//是否暫停:false
//當前活動標識:null
//業(yè)務關鍵字:null
//------------

7. 根據(jù)流程和負責人查詢?nèi)蝿?/h4>
/**
 * 查詢?nèi)蝿詹樵? * 也可以不加過濾條件,查詢出全部
 */
@RequestMapping("searchTask")
@ResponseBody
public void searchTask() {
    String assignee = "worker";
    String key = "myLeave";
    //根據(jù)流程的key和任務負責人 查詢?nèi)蝿?/span>
    List<Task> list = taskService.createTaskQuery()
        .processDefinitionKey(key)
        .taskAssignee(assignee)
        .list();
    //輸出當前用戶具有的任務
    for (Task task : list) {
        System.out.println("流程實例id:" + task.getProcessDefinitionId());
        System.out.println("任務id:" + task.getId());
        System.out.println("任務負責人:" + task.getAssignee());
        System.out.println("任務名稱:" + task.getName());
    }

}

//結果:
//流程實例id:myLeave:2:a07c05cb-076f-11ed-afa5-005056c00001
//任務id:2da138fa-0772-11ed-a901-005056c00001
//任務負責人:worker
//任務名稱:創(chuàng)建請假流程

8. 處理流程

/**
 * 根據(jù)流程的key和任務負責人 處理任務
 */
@RequestMapping("solveTask")
@ResponseBody
public void solveTask() {
    String assignee = "worker";
    String key = "myLeave";
    //根據(jù)流程的key和任務負責人 查詢?nèi)蝿?/span>
    Task task = taskService.createTaskQuery()
        .processDefinitionKey(key)
        .taskAssignee(assignee)
        .singleResult();
    //完成任務,跳到下一個流程
    taskService.complete(task.getId());
}

act_ru_execution:任務操作

act_ru_task:目前需要處理的任務表

9. 流程歷史信息查看

/**
 * 流程歷史信息查看
 * 即時刪除了流程,但是流程的歷史信息還是會被保存下來,存在hi**表中
 * 也可以不加過濾條件,查詢出全部
 */
@RequestMapping("searchHistoricActivityInstance")
@ResponseBody
public void searchHistoricActivityInstance() {
    String id = "myLeave:1:fc307169-0773-11ed-9b87-005056c00001";
    //獲取actinst表的查詢對象
    HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
    //查詢actinst表,根據(jù)流程id查詢
    HistoricActivityInstanceQuery historicActivityInstanceQuery1 = historicActivityInstanceQuery.processDefinitionId(id);
    //查詢actinst表,根據(jù)流程實例id查詢
    //historicActivityInstanceQuery.processInstanceId(流程實例id);
    //排序
    historicActivityInstanceQuery1.orderByHistoricActivityInstanceStartTime().desc();
    //獲取查詢結果
    List<HistoricActivityInstance> list = historicActivityInstanceQuery1.list();
    //輸出查詢結果
    for (HistoricActivityInstance hi : list) {
        System.out.println(hi.getActivityId());
        System.out.println(hi.getActivityName());
        System.out.println(hi.getActivityType());
        System.out.println(hi.getAssignee());
        System.out.println(hi.getProcessDefinitionId());
        System.out.println(hi.getProcessInstanceId());
    }
}

//結果:
//_4
//部門經(jīng)理審批
//userTask
//manager
//myLeave:1:fc307169-0773-11ed-9b87-005056c00001
//fece74da-0773-11ed-9b87-005056c00001
//_3
//創(chuàng)建請假流程
//userTask
//worker
//myLeave:1:fc307169-0773-11ed-9b87-005056c00001
//fece74da-0773-11ed-9b87-005056c00001
//_2
//StartEvent
//startEvent
//null
//myLeave:1:fc307169-0773-11ed-9b87-005056c00001
//fece74da-0773-11ed-9b87-005056c00001

10. 單個流程全部實例掛起

/**
  * 全部流程實例掛起和激活
 */
@RequestMapping("allLockOrOpenPeocess")
@ResponseBody
public void allLockOrOpenPeocess() {
    String id = "myLeave";
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey(id)
        .singleResult();
    //獲取流程的狀態(tài)
    boolean suspended = processDefinition.isSuspended();
    String pdId = processDefinition.getId();
    //如果激活就掛起,掛起就激活
    if (suspended) {
        //表示當前是掛起的,需要激活。
        //參數(shù):流程定義id、是否激活、激活時間
        repositoryService.activateProcessDefinitionById(pdId, true, null);
        System.out.println("流程定義:" + pdId + ",已激活");
    } else {
        //激活狀態(tài),則需要掛起
        //參數(shù):流程定義id、是否掛起、掛起時間
        repositoryService.suspendProcessDefinitionById(pdId, true, null);
        System.out.println("流程定義:" + pdId + ",已掛起");
    }
}

11. 單個實例掛起和激活

/**
  * 單個流程實例掛起和激活
  */
@RequestMapping("singleLockOrOpenPeocess")
@ResponseBody
public void singleLockOrOpenPeocess() {
    //task表的proc_inst_id
    String id = "dc609b81-082e-11ed-a65d-005056c00001";
    //獲取實例對象
    ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
        .processInstanceId(id)
        .singleResult();
    //獲取狀態(tài)
    boolean suspended = processInstance.isSuspended();
    String pdId = processInstance.getId();
    if (suspended) {
        //表示當前是掛起的,需要激活
        runtimeService.activateProcessInstanceById(pdId);
        System.out.println("流程定義:" + pdId + ",已激活");
    } else {
        //激活狀態(tài),則需要掛起
        runtimeService.suspendProcessInstanceById(pdId);
        System.out.println("流程定義:" + pdId + ",已掛起");
    }
}

六、activiti接口進階(變量啟動)

  1. 流程變量

    Global變量:這個是流程變量的默認作用域,表示是一個完整的流程實例。Global變量名不能重復,如果重復則會被后面的覆蓋。

    Local變量:Local變量只針對一個任務或者一個執(zhí)行實例,變量名可相同,互不影響。

    ps1:如果設置了流程變量,就必須復制,否則將會報錯導致流程結束。

    ps2:如果連線分支不設置條件,默認走sequenceFlow id(可在xml查看)小的那條線。

  2. 畫分支圖,并且設置流程審批人變量,依次設置為 a s s i g n e e 0 、 {assignee0}、 assignee0、{assignee1}、 a s s i g n e e 2 、 {assignee2}、 assignee2、{assignee3}
    activiti7,新手,數(shù)據(jù)庫,運維,大數(shù)據(jù)

  3. 啟動流程,并且創(chuàng)建實例(帶變量)

    /**
      * 啟動流程(創(chuàng)建新的申請流程實例列表)
      */
    @RequestMapping("addApplication")
    @ResponseBody
    public void addApplication() {
        Map<String,Object> variables=new HashMap<>();
        Map<String ,Object>  evention=new HashMap<>();
        evention.put("num",2);
    
        variables.put("evention",evention);
        variables.put("assignee0","申請人");
        variables.put("assignee1","部門經(jīng)理");
        variables.put("assignee2","總經(jīng)理");
        variables.put("assignee3","財務人事");
    
        String key = "myLeave1";
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key,variables);
    }
    
  4. 依次調(diào)用solveTask方法,可以發(fā)現(xiàn)最終走的分支是num小于3的分支,即不經(jīng)過總經(jīng)理審批。

  5. 也可以在每次執(zhí)行時,重新設置本地變量

    ps:這里需要留意,7.1.0.M1版本的activiti無法直接在complete時覆蓋全局和本地變量,只能通過設置本地變量覆蓋。

    /**
     * 啟動流程(創(chuàng)建新的申請流程實例列表)
     */
    @RequestMapping("addApplication")
    @ResponseBody
    public void addApplication() {
        Map<String,Object> variables=new HashMap<>();
        Map<String ,Object>  evention=new HashMap<>();
        evention.put("num",2);
    
        variables.put("evention",evention);
        variables.put("assignee0","申請人");
        variables.put("assignee1","部門經(jīng)理");
        variables.put("assignee2","總經(jīng)理");
        variables.put("assignee3","財務人事");
    
        String key = "myLeave1";
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key,variables);
    }
    
    /**
     * 根據(jù)流程的key和任務負責人 處理任務
     */
    @RequestMapping("solveTask")
    @ResponseBody
    public void solveTask() {
        String assignee = "申請人";
        String id = "myLeave1";
        //根據(jù)流程的key和任務負責人 查詢?nèi)蝿?/span>
        Task task = taskService.createTaskQuery()
            .processDefinitionKey(id)
            .taskAssignee(assignee)
            .singleResult();
    
        //完成任務,跳到下一個流程
        Map<String,Object> variables=new HashMap<>();
        Map<String ,Object>  evention=new HashMap<>();
        evention.put("num",2);
    
        variables.put("evention",evention);
        variables.put("assignee0","申請人1");
        variables.put("assignee1","部門經(jīng)理1");
        variables.put("assignee2","總經(jīng)理1");
        variables.put("assignee3","財務人事1");
    
        taskService.setVariablesLocal(task.getId(),variables);
        taskService.complete(task.getId());
    }
    
    /**
     * 根據(jù)流程的key和任務負責人 處理任務
     */
    @RequestMapping("solveTaskForVariables")
    @ResponseBody
    public void solveTaskForVariables() {
        String assignee = "部門經(jīng)理1";
        String id = "myLeave1";
        //根據(jù)流程的key和任務負責人 查詢?nèi)蝿?/span>
        Task task = taskService.createTaskQuery()
            .processDefinitionKey(id)
            .taskAssignee(assignee)
            .singleResult();
        //完成任務,跳到下一個流程
        Map<String,Object> variables=new HashMap<>();
        Map<String ,Object>  evention=new HashMap<>();
        evention.put("num",2);
    
        variables.put("evention",evention);
        variables.put("assignee0","申請人2");
        variables.put("assignee1","部門經(jīng)理2");
        variables.put("assignee2","總經(jīng)理2");
        variables.put("assignee3","財務人事2");
    
        taskService.setVariablesLocal(task.getId(),variables);
        taskService.complete(task.getId());
    }
    

    然后查詢當前任務

    /**
     * 根據(jù)流程的key查詢存在哪些任務
     */
    @RequestMapping("searchTaskByKey")
    @ResponseBody
    public void searchTaskByKey() {
        String key = "myLeave1";
        //根據(jù)流程的key和任務負責人 查詢?nèi)蝿?/span>
        List<Task> tasks = taskService.createTaskQuery()
            .processDefinitionKey(key)
            .list();
    
        for (Task task : tasks) {
            System.out.println(task.getId());
            System.out.println(task.getName());
            System.out.println(task.getAssignee());
            System.out.println("--------------");
        }
    }
    
    //結果
    //3c18d52e-0841-11ed-b1d5-005056c00001
    //財務部審批
    //財務人事2
    //--------------
    

七、activiti網(wǎng)關

1. 排他網(wǎng)關

  1. 概念:用來在流程中實現(xiàn)決策。 當流程執(zhí)行到這個網(wǎng)關,所有分支都會判斷是否為true,如果為ture則執(zhí)行。如果多個為true,則執(zhí)行id值小的。如果沒 有位true的,則拋出異常

  2. 流程圖
    activiti7,新手,數(shù)據(jù)庫,運維,大數(shù)據(jù)

2. 并行網(wǎng)關

  1. 概念:并行網(wǎng)關允許將流程分成多條分支,也可以把多條分支匯聚到一起。并行網(wǎng)關的線上面,寫上條件也沒有用,在并行網(wǎng)關的后面分支都要執(zhí)行完成之后,才會走下一個任務,不然,只要有一個分支沒有完成,后面的任務就不會走

  2. 流程圖
    activiti7,新手,數(shù)據(jù)庫,運維,大數(shù)據(jù)

3. 包含網(wǎng)關

  1. 概念:包含網(wǎng)關可以看做是排他網(wǎng)關和并行網(wǎng)關的結合體。和排他網(wǎng)關一樣,你可以在外出順序流上定義條件,包含網(wǎng)關會解析它們,不定義則默認放行。 但是主要的區(qū)別是包含網(wǎng)關可以選擇多于一條順序流,這和并行網(wǎng)關一樣。這也是用的最多的網(wǎng)關。

  2. 流程圖 activiti7,新手,數(shù)據(jù)庫,運維,大數(shù)據(jù)

八、組任務流程

  1. 概念

    即任務的下一個處理人不再是一個具體的人員,而是一組候選人。候選人可以主動拾取任務,然后辦理。

  2. 流程圖,即再流程的第二步,經(jīng)理或總經(jīng)理需要拾取任務才能進行處理
    activiti7,新手,數(shù)據(jù)庫,運維,大數(shù)據(jù)

  3. 代碼實現(xiàn)

    由于activiti需要整合Security框架,所以需要做好權限配置,這里是簡單做了個lisi用戶的配置

    package activiti.config;
    
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.core.context.SecurityContextImpl;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.stereotype.Component;
    
    import java.util.Collection;
    
    @Component
    public class SecurityUtil {
        private Logger logger = LoggerFactory.getLogger(SecurityUtil.class);
    
        @Autowired
        @Qualifier("myUserDetailsService")
        private UserDetailsService userDetailsService;
    
        public void logInAs(String username) {
            UserDetails user = userDetailsService.loadUserByUsername(username);
    
            if (user == null) {
                throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");
            }
            logger.info("> Logged in as: " + username);
    
            SecurityContextHolder.setContext(
                    new SecurityContextImpl(
                            new Authentication() {
                                @Override
                                public Collection<? extends GrantedAuthority> getAuthorities() {
                                    return user.getAuthorities();
                                }
    
                                @Override
                                public Object getCredentials() {
                                    return user.getPassword();
                                }
    
                                @Override
                                public Object getDetails() {
                                    return user;
                                }
    
                                @Override
                                public Object getPrincipal() {
                                    return user;
                                }
    
                                @Override
                                public boolean isAuthenticated() {
                                    return true;
                                }
    
                                @Override
                                public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
                                }
    
                                @Override
                                public String getName() {
                                    return user.getUsername();
                                }
                            }));
            org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
        }
    }
    
    package activiti.config;
    
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.provisioning.InMemoryUserDetailsManager;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    @Configuration
    public class SpringSecurityConfiguration {
        private Logger logger = LoggerFactory.getLogger(SpringSecurityConfiguration.class);
        @Bean
        public UserDetailsService myUserDetailsService() {
            InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
            //這里添加用戶,后面處理流程時用到的任務負責人,需要添加在這里
            String[][] usersGroupsAndRoles = {
                    {"lisi", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
                    {"system", "password", "ROLE_ACTIVITI_USER"},
                    {"admin", "password", "ROLE_ACTIVITI_ADMIN"},
            };
    
            for (String[] user : usersGroupsAndRoles) {
                List<String> authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user, 2, user.length));
                logger.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]");
                inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]),
                        authoritiesStrings.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList())));
            }
    
            return inMemoryUserDetailsManager;
        }
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }
    

    查找并且拾取任務

    /**
     * 根據(jù)流程的key和候選人拾取任務
     * 由于是測試,所以返回單個任務。正常應該是列表展示所有候選任務,然后選擇拾取。
     */
    @RequestMapping("claimTask")
    @ResponseBody
    public void claimTask() {
        String taskCandidateUser = "lisi";
        String id = "myLeave5";
        //根據(jù)流程的key和任務負責人 查詢?nèi)蝿?/span>
        Task task = taskService.createTaskQuery()
            .processDefinitionKey(id)
            .taskCandidateUser(taskCandidateUser)
            .singleResult();
    
        if(task!=null){
            taskService.claim(task.getId(),taskCandidateUser);
        }
    }	
    

    lisi處理任務文章來源地址http://www.zghlxwxcb.cn/news/detail-645863.html

    /**
     * 根據(jù)流程的key和任務負責人 處理任務
     */
    @RequestMapping("solveTask")
    @ResponseBody
    public void solveTask() {
        String assignee = "lisi";
        String id = "myLeave5";
        //根據(jù)流程的key和任務負責人 查詢?nèi)蝿?/span>
        Task task = taskService.createTaskQuery()
            .processDefinitionKey(id)
            .taskAssignee(assignee)
            .singleResult();
        //完成任務,跳到下一個流程
        taskService.complete(task.getId());
    }
    

到了這里,關于activiti7入門教程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 新手入門Jenkins自動化部署入門詳細教程

    新手入門Jenkins自動化部署入門詳細教程

    在實際開發(fā)中,我們經(jīng)常要一邊開發(fā)一邊測試,當然這里說的測試并不是程序員對自己代碼的單元測試,而是同組程序員將代碼提交后,由測試人員測試; 或者前后端分離后,經(jīng)常會修改接口,然后重新部署; 這些情況都會涉及到頻繁的打包部署; 手動打包常規(guī)步驟: 1.提

    2024年02月13日
    瀏覽(31)
  • StarkNet新手入門教程:教你用bitget 錢包入門

    StarkNet新手入門教程:教你用bitget 錢包入門

    理想的Starknet (web3.bitget.com/zh/assets/starknet-wallet) 錢包取決于個人喜好,同時考慮安全性、用戶友好性、帳戶恢復選項和多通證支持等因素。盡管如此,無論您使用 Starknet (STRK) 的目的是持有還是交易,Bitget Wallet 都是您管理 STRK 以及其他以太坊和 Optimism 加密資產(chǎn)的理想錢包選擇

    2024年03月12日
    瀏覽(28)
  • 【Jmeter】壓力測試新手入門教程

    【Jmeter】壓力測試新手入門教程

    壓力測試是每一個Web應用程序上線之前都需要做的一個測試,他可以幫助我們發(fā)現(xiàn)系統(tǒng)中的瓶頸問題,減少發(fā)布到生產(chǎn)環(huán)境后出問題的幾率;預估系統(tǒng)的承載能力,使我們能根據(jù)其做出一些應對措施。所以壓力測試是一個非常重要的步驟,下面我?guī)Т蠹襾硎褂靡豢顗毫y試工

    2024年04月15日
    瀏覽(22)
  • 電腦黑客技術新手入門,自學黑客技術入門教程

    電腦黑客技術新手入門,自學黑客技術入門教程

    最近經(jīng)常有小伙伴聯(lián)系我說要學黑客技術,當然目的各種各樣,有的就是覺得黑客很酷,單純想要學技術,還有的就是想找人幫忙攻擊賭博網(wǎng)站或者監(jiān)聽別人的電話(以女朋友的電話居多),對于想要單純學技術的朋友我很歡迎他們問我問題,但對于那些想做違法事情的人我

    2024年02月10日
    瀏覽(24)
  • 小程序注冊安裝以及新手快速入門教程

    小程序注冊安裝以及新手快速入門教程

    一、注冊并安裝微信小程序 1.打開? https://mp.weixin.qq.com/? 網(wǎng)址,點擊立即注冊即可進入小程序開發(fā)賬號的注冊流程,注冊的賬號類型選擇 小程序 。 2.根據(jù)注冊要求注冊,發(fā)送郵箱信息,接收到微信團隊發(fā)送的郵箱信息后,點擊鏈接進行激活,如果出現(xiàn) 紅色感嘆號 可參考下

    2024年02月09日
    瀏覽(22)
  • 你好,uv變換(新手入門向聊天教程)

    你好,uv變換(新手入門向聊天教程)

    溫馨提示:本文只是一篇入門聊天,不涉及代碼教程,看不懂代碼就跳過,沒關系! 1、uv其實就是一個二維坐標系啊,就倆軸,就跟xy軸一樣。 那為什么不叫xy,反而叫uv呢? 不知道,應該是為了跟空間坐標系xyz區(qū)別開來,以免在工作流程中產(chǎn)生誤解吧吧吧。 2、uv坐標用于采

    2024年02月12日
    瀏覽(19)
  • Python電商爬蟲保姆級入門教程(純新手向)

    Python電商爬蟲保姆級入門教程(純新手向)

    圖靈Python課堂 長沙圖靈教育于2001年開始進入教育行業(yè),立足泛IT類職業(yè)教育,以打造高新技術人才為宗旨,專注于提供多層次、個性化的職業(yè)技能培訓課程,為各行業(yè)培養(yǎng)技術開發(fā)、應用和管理等崗位的中高端人才,致力于成為優(yōu)質(zhì)的職業(yè)教育內(nèi)容提供商。 0 1 Python優(yōu)勢 1、

    2024年02月15日
    瀏覽(25)
  • Python 安裝教程,新手入門(超詳細)含Pycharm開發(fā)環(huán)境安裝教程

    Python 安裝教程,新手入門(超詳細)含Pycharm開發(fā)環(huán)境安裝教程

    目錄 一、Python介紹 二、Python安裝教程 (一)Python的下載 (二)Python的安裝 三、Pycharm開發(fā)工具的安裝 (一)Pycharm介紹 (二)Pycharm的下載 (三)Pycharm的安裝 ?????????Python由荷蘭數(shù)學和計算機科學研究學會的吉多·范羅蘇姆于1990年代初設計,作為一門叫做ABC語言的替

    2024年01月20日
    瀏覽(28)
  • MUI框架從新手入門【webapp開發(fā)教程】

    MUI框架從新手入門【webapp開發(fā)教程】

    性能和體驗的差距,一直是mobile app開發(fā)者放棄HTML5的首要原因。 瀏覽器天生的切頁白屏、不忍直視的轉頁動畫、浮動元素的抖動、無法流暢下拉刷新等問題,這些都讓HTML5開發(fā)者倍感挫敗,尤其拿到Android低端機運行,摔手機的心都有; 另一方面,瀏覽器默認控件樣式又少又

    2024年02月04日
    瀏覽(50)
  • 微信小程序新手入門教程一:零基礎上手

    微信小程序新手入門教程一:零基礎上手

    小程序是一種全新的連接用戶與服務的方式,它可以在微信內(nèi)被便捷地獲取和傳播,同時具有出色的使用體驗。它提供了一個簡單、高效的應用開發(fā)框架和豐富的組件及API,幫助開發(fā)者在微信中開發(fā)具有原生 APP 體驗的服務。 1.開發(fā)環(huán)境不同。 網(wǎng)頁運行在瀏覽器環(huán)境中,而小

    2024年03月18日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包