成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Activiti工作流從入門到入土:完整Hello World大比拼(Activiti工作流 API

ghnor / 1539人閱讀

摘要:通過流程引擎獲取了一個(gè)對(duì)象倉(cāng)庫(kù)對(duì)象由倉(cāng)庫(kù)的服務(wù)對(duì)象產(chǎn)生一個(gè)部署對(duì)象配置對(duì)象,用來(lái)封裝部署操作的相關(guān)配置。輔導(dǎo)員審批的審批人員是歐陽(yáng)思海。部署流程定義從與流程定義和部

文章源碼托管:https://github.com/OUYANGSIHA...
歡迎 star !??!

本來(lái)想著閑來(lái)無(wú)事,前面在項(xiàng)目中剛剛用到了工作流 Activiti 框架,寫寫博客的,但是,事情總是紛紛雜雜,一直拖延到現(xiàn)在,這一節(jié)原本想要寫一下關(guān)于 Activiti 的 API ,但是,想著太多這樣的博客了,而且顯得太生硬,難以理解,所以,這些 API 就在實(shí)際的 demo 中來(lái)講解。

一、建立流程圖

在開始做工作流之前,我們首先應(yīng)該把具體的業(yè)務(wù)在工作流的部署流程圖體現(xiàn)出來(lái),并且都測(cè)試通過,這樣就相當(dāng)于成功了一半,后面的具體業(yè)務(wù)的開發(fā)就相對(duì)輕松一些了。

首先,我們先看一看在 idea 中有哪些控件,常用的控件進(jìn)行了標(biāo)注。

下面我們講一下建立一個(gè)流程圖的具體過程。

首先,我們需要拉入一個(gè)開始節(jié)點(diǎn)bpmn 文件中,這是圖像化的界面,只需要拉入即可。

然后,我們從控件中拉入一個(gè) UserTask 用戶任務(wù)節(jié)點(diǎn)到 bpmn 文件中。

這樣子就有了兩個(gè)審批節(jié)點(diǎn)了,如果還需要其他的一些業(yè)務(wù)需求,我們還可以加入一些網(wǎng)關(guān),這里就暫時(shí)不加了。

最后,我們只需要一個(gè)結(jié)束節(jié)點(diǎn) EndEvent 就完成了這個(gè)工作流的部署圖的繪制。

我們最后看一下完整的例子。

看似已經(jīng)完成了整個(gè)流程圖的繪制,但美中不足的是我們目前并沒有設(shè)置導(dǎo)師審批輔導(dǎo)員審批到底由誰(shuí)來(lái)審批,所以,我們還是需要來(lái)瞅一瞅怎么設(shè)置審批人員。

首先,我們需要選中一個(gè)審批節(jié)點(diǎn),例如,選中導(dǎo)師審批這個(gè)節(jié)點(diǎn)。

其次,我們就顯而易見的可以在 idea 編輯器的左側(cè)看到一個(gè)名為 BPMN editor 的屬性框,里面包括一個(gè)用戶任務(wù)節(jié)點(diǎn)的可以設(shè)置的所有屬性

注意:候選用戶、候選組、任務(wù)監(jiān)聽器,這三個(gè)屬性這里暫時(shí)不講,后面再補(bǔ)充。

由于,這一步我們需要設(shè)置審批人,所以,我們需要在 Assignee 這個(gè)屬性中設(shè)置我們的審批人。

如上圖,這里設(shè)置導(dǎo)師審批這個(gè)節(jié)點(diǎn)的審批人為 sihai 。設(shè)置審批人除了直接設(shè)置之外,還有兩種方式設(shè)置,后面再補(bǔ)充。

另外一個(gè)審批節(jié)點(diǎn)也通過這種方式設(shè)置就可以完成審批人的設(shè)置了。

very good,這樣就基本完成了一個(gè)流程圖的創(chuàng)建。接下來(lái),我們將通過實(shí)例來(lái)具體講解Activiti 的 API 的講解

二、實(shí)例講解 API

在上面這個(gè)流程圖的創(chuàng)建中,我們還沒有生成 png 圖片,所以,如果不知道如何生成的,可以參考之前的這篇文章:Activiti工作流從入門到入土:整合spring。

既然是講解 API ,那么還是先看一下主要有哪些 API 吧,這樣才有一個(gè)整體把握。

這些 API 具體怎么用,接下來(lái)一一道來(lái)。

2.1 流程定義

既然是流程定義,那肯定少不了如何部署流程定義了。

2.1.1 部署流程定義方法1
 @Autowired
    private ProcessEngine processEngine;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private HistoryService historyService;

    /**
     * 部署流程定義(從classpath)
     */
    @Test
    public void deploymentProcessDefinition_classpath(){
        Deployment deployment = processEngine.getRepositoryService()//與流程定義和部署對(duì)象相關(guān)的Service
                .createDeployment()//創(chuàng)建一個(gè)部署對(duì)象
                .name("流程定義")//添加部署的名稱
                .addClasspathResource("bpmn/hello.bpmn")//從classpath的資源中加載,一次只能加載一個(gè)文件
                .addClasspathResource("bpmn/hello.png")//從classpath的資源中加載,一次只能加載一個(gè)文件
                .deploy();//完成部署
        System.out.println("部署ID:"+deployment.getId());
        System.out.println("部署名稱:"+deployment.getName());
    }

注意:這里用的是整合 spring 之后的 junit 測(cè)試環(huán)境,如何整合 spring 請(qǐng)看這篇文章:Activiti工作流從入門到入土:整合spring。

輸出結(jié)果:

這樣,我們就部署了這個(gè)流程。那么具體是怎么操作的呢,我們?cè)賮?lái)看看整個(gè)過程。

獲取流程引擎對(duì)象:這個(gè)跟 spring 整合了。

通過流程引擎獲取了一個(gè) RepositoryService 對(duì)象(倉(cāng)庫(kù)對(duì)象)

由倉(cāng)庫(kù)的服務(wù)對(duì)象產(chǎn)生一個(gè)部署對(duì)象配置對(duì)象,用來(lái)封裝部署操作的相關(guān)配置。

這是一個(gè)鏈?zhǔn)骄幊?,在部署配置?duì)象中設(shè)置顯示名,上傳流程定義規(guī)則文件

向數(shù)據(jù)庫(kù)表中存放流程定義的規(guī)則信息。

其實(shí),這一步操作,用到了 Activiti 數(shù)據(jù)庫(kù)中的三張表,分別是:act_re_deployment(部署對(duì)象表),act_re_procdef(流程定義表),act_ge_bytearray(資源文件表)。

我們看看這三張表的變化:
1)act_re_deployment

可以看到,部署ID和部署名稱就存在這張表中。

2)act_re_procdef

這張表中,存放了部署的Deployment_ID部署流程的id、bpmn資源文件名稱、png圖片名稱等信息。

3)act_ge_bytearray

存儲(chǔ)流程定義相關(guān)的部署信息。即流程定義文檔的存放地。每部署一次就會(huì)增加兩條記錄,一條是關(guān)于 bpmn 規(guī)則文件的,一條是圖片的(如果部署時(shí)只指定了 bpmn 一個(gè)文件,activiti 會(huì)在部署時(shí)解析 bpmn 文件內(nèi)容自動(dòng)生成流程圖)。兩個(gè)文件不是很大,都是以二進(jìn)制形式存儲(chǔ)在數(shù)據(jù)庫(kù)中。

2.1.2 部署流程定義方法2
 /**
     * 部署流程定義(從zip)
     */
    @Test
    public void deploymentProcessDefinition_zip(){
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("bpmn/hello.zip");
        ZipInputStream zipInputStream = new ZipInputStream(in);
        Deployment deployment = processEngine.getRepositoryService()//與流程定義和部署對(duì)象相關(guān)的Service
                .createDeployment()//創(chuàng)建一個(gè)部署對(duì)象
                .name("流程定義")//添加部署的名稱
                .addZipInputStream(zipInputStream)//指定zip格式的文件完成部署
                .deploy();//完成部署
        System.out.println("部署ID:"+deployment.getId());//
        System.out.println("部署名稱:"+deployment.getName());//
    }

項(xiàng)目結(jié)構(gòu)如下:

輸出結(jié)果:

如此看來(lái),也是沒有任何問題的,唯一的區(qū)別只是壓縮成zip格式的文件,使用zip的輸入流用作部署流程定義,其他使用并無(wú)區(qū)別。

部署了流程定義之后,我們應(yīng)該想查看一下流程定義的一些信息。

2.1.3 查看流程定義
/**
     * 查詢流程定義
     */
    @Test
    public void findProcessDefinition(){
        List list = processEngine.getRepositoryService()//與流程定義和部署對(duì)象相關(guān)的Service
                .createProcessDefinitionQuery()//創(chuàng)建一個(gè)流程定義的查詢
                /**指定查詢條件,where條件*/
//                        .deploymentId(deploymentId)//使用部署對(duì)象ID查詢
//                        .processDefinitionId(processDefinitionId)//使用流程定義ID查詢
//                        .processDefinitionKey(processDefinitionKey)//使用流程定義的key查詢
//                        .processDefinitionNameLike(processDefinitionNameLike)//使用流程定義的名稱模糊查詢

                /**排序*/
                .orderByProcessDefinitionVersion().asc()//按照版本的升序排列
//                        .orderByProcessDefinitionName().desc()//按照流程定義的名稱降序排列

                /**返回的結(jié)果集*/
                .list();//返回一個(gè)集合列表,封裝流程定義
//                        .singleResult();//返回惟一結(jié)果集
//                        .count();//返回結(jié)果集數(shù)量
//                        .listPage(firstResult, maxResults);//分頁(yè)查詢
        if(list!=null && list.size()>0){
            for(ProcessDefinition pd:list){
                System.out.println("流程定義ID:"+pd.getId());//流程定義的key+版本+隨機(jī)生成數(shù)
                System.out.println("流程定義的名稱:"+pd.getName());//對(duì)應(yīng)hello.bpmn文件中的name屬性值
                System.out.println("流程定義的key:"+pd.getKey());//對(duì)應(yīng)hello.bpmn文件中的id屬性值
                System.out.println("流程定義的版本:"+pd.getVersion());//當(dāng)流程定義的key值相同的相同下,版本升級(jí),默認(rèn)1
                System.out.println("資源名稱bpmn文件:"+pd.getResourceName());
                System.out.println("資源名稱png文件:"+pd.getDiagramResourceName());
                System.out.println("部署對(duì)象ID:"+pd.getDeploymentId());
                System.out.println("*********************************************");
            }
        }
    }

輸出結(jié)果:

查詢流程定義小結(jié):

流程定義和部署對(duì)象相關(guān)的Service都是 RepositoryService ,后面會(huì)發(fā)現(xiàn)關(guān)于流程定義的都是 RepositoryService

通過這個(gè) createProcessDefinitionQuery() 方法來(lái)設(shè)置一些查詢參數(shù),比如通過條件、降序升序等。

2.1.4 刪除流程定義

通過刪除部署 ID 為2501的信息。

/**
     * 刪除流程定義
     */
    @Test
    public void deleteProcessDefinition(){
        //使用部署ID,完成刪除,指定部署對(duì)象id為2501刪除
        String deploymentId = "2501";
        /**
         * 不帶級(jí)聯(lián)的刪除
         *    只能刪除沒有啟動(dòng)的流程,如果流程啟動(dòng),就會(huì)拋出異常
         */
//        processEngine.getRepositoryService()//
//                        .deleteDeployment(deploymentId);

        /**
         * 級(jí)聯(lián)刪除
         *       不管流程是否啟動(dòng),都能可以刪除
         */
        processEngine.getRepositoryService()//
                .deleteDeployment(deploymentId, true);
        System.out.println("刪除成功!");
    }

輸出結(jié)果:

到數(shù)據(jù)庫(kù)查看,發(fā)現(xiàn) act_re_deployment 中的數(shù)據(jù)已經(jīng)不存在了。

這里還是通過 getRepositoryService() 方法獲取部署定義對(duì)象,然后指定 ID 刪除信息。

2.1.5 獲取流程定義文檔的資源

這里的作用主要是查詢圖片,通過圖片可以在后面做流程展示用的。我們看看具體怎么查看。

/**
     * 查看流程圖
     *
     * @throws IOException
     */
    @Test
    public void viewPic() throws IOException {
        /**將生成圖片放到文件夾下*/
        String deploymentId = "5001";
        //獲取圖片資源名稱
        List list = processEngine.getRepositoryService()//
                .getDeploymentResourceNames(deploymentId);
        //定義圖片資源的名稱
        String resourceName = "";
        if (list != null && list.size() > 0) {
            for (String name : list) {
                if (name.indexOf(".png") >= 0) {
                    resourceName = name;
                }
            }
        }

        //獲取圖片的輸入流
        InputStream in = processEngine.getRepositoryService()//
                .getResourceAsStream(deploymentId, resourceName);

        //將圖片生成到F盤的目錄下
        File file = new File("F:/" + resourceName);

        //將輸入流的圖片寫到磁盤
        FileUtils.copyInputStreamToFile(in, file);
    }

在F盤下,可以找到圖片。

2.1.6 查詢最新版本的流程定義
 /**
     * 查詢最新版本的流程定義
     */
    @Test
    public void findLastVersionProcessDefinition() {
        List list = processEngine.getRepositoryService()//
                .createProcessDefinitionQuery()//
                .orderByProcessDefinitionVersion().asc()//使用流程定義的版本升序排列
                .list();
        /**
         map集合的特點(diǎn):當(dāng)map集合key值相同的情況下,后一次的值將替換前一次的值
         */
        Map map = new LinkedHashMap();
        if (list != null && list.size() > 0) {
            for (ProcessDefinition pd : list) {
                map.put(pd.getKey(), pd);
            }
        }
        List pdList = new ArrayList(map.values());
        if (pdList != null && pdList.size() > 0) {
            for (ProcessDefinition pd : pdList) {
                System.out.println("流程定義ID:" + pd.getId());//流程定義的key+版本+隨機(jī)生成數(shù)
                System.out.println("流程定義的名稱:" + pd.getName());//對(duì)應(yīng)hello.bpmn文件中的name屬性值
                System.out.println("流程定義的key:" + pd.getKey());//對(duì)應(yīng)hello.bpmn文件中的id屬性值
                System.out.println("流程定義的版本:" + pd.getVersion());//當(dāng)流程定義的key值相同的相同下,版本升級(jí),默認(rèn)1
                System.out.println("資源名稱bpmn文件:" + pd.getResourceName());
                System.out.println("資源名稱png文件:" + pd.getDiagramResourceName());
                System.out.println("部署對(duì)象ID:" + pd.getDeploymentId());
                System.out.println("*********************************************************************************");
            }
        }
    }

輸出結(jié)果:

2.1.7 流程定義總結(jié)

1、部署流程定義用到了 Activiti 的下面的幾張表。

act_re_deployment:部署對(duì)象表

act_re_procdef:流程定義表

act_ge_bytearray:資源文件表

act_ge_property:主鍵生成策略表

2、我們發(fā)現(xiàn)部署流程定義的操作都是在 RepositoryService 這個(gè)類下進(jìn)行操作的,我們只需要通過 getRepositoryService() 拿到對(duì)象,通過鏈?zhǔn)揭?guī)則就可以進(jìn)行部署流程定義的所有操作。

2.2 工作流完整實(shí)例的使用

這一節(jié),我們通過一個(gè)完整的例子,來(lái)總結(jié)一下前面講過的一些基本的知識(shí),這樣能夠更好的學(xué)習(xí)前面以及后面的知識(shí)點(diǎn),這也算是一個(gè)過渡的章節(jié)。

回到第一節(jié)的建立流程圖,我們已經(jīng)將基本的 bpmn 圖已經(jīng)建立好了,但是,需要做一個(gè)完整的實(shí)例,我們還是需要補(bǔ)充一些內(nèi)容的,這樣才能夠把這樣的一個(gè)實(shí)例做好,我們先把第一節(jié)的那個(gè) bpmn 圖拿過來(lái)。

首先,我們需要明確:這個(gè)圖到目前為止,我們只是簡(jiǎn)簡(jiǎn)單單的把流程給畫出來(lái)了,比如,我們需要審核的時(shí)候,是需要具體到某一個(gè)具體的人員去審核的,所以,我們需要給每個(gè)節(jié)點(diǎn)設(shè)置審核的具體人員。

注意:設(shè)置節(jié)點(diǎn)的審核人員后面還會(huì)分一節(jié)細(xì)講,這里只是做一個(gè)簡(jiǎn)單的實(shí)例,所以,只需要這里能夠看懂,做好就ok了。

設(shè)置審核人員步驟

首先,我們需要選中一個(gè)節(jié)點(diǎn),例如,下圖中的“導(dǎo)師審批”節(jié)點(diǎn)。

接下來(lái),在左邊的工具欄,我們會(huì)看到好多選項(xiàng),有一項(xiàng)為 Assignee ,我們需要在這個(gè)選項(xiàng)中設(shè)置我們這個(gè)節(jié)點(diǎn)需要設(shè)置的審批人。

Assignee設(shè)置格式:直接使用英文或者中文都可以,例如,sihai,更復(fù)雜的設(shè)置后面再講。

下面的節(jié)點(diǎn)設(shè)置也是跟上面一模一樣。

輔導(dǎo)員審批的審批人員是:歐陽(yáng)思海。

perfect,這樣流程圖的任務(wù)就完成了,下面我們就可以進(jìn)行這個(gè)實(shí)例的測(cè)試階段了。

1)部署流程定義
部署流程定義,在前面的章節(jié)已經(jīng)講過了,有兩種方式進(jìn)行處理,一種是加載 bpmn 文件和 png 文件,還有一種是將這兩個(gè)文件壓縮成 zip 格式的壓縮文件,然后加載。這里我們使用第一種方式進(jìn)行處理。

/**
     * 部署流程定義(從classpath)
     */
    @Test
    public void deploymentProcessDefinition_classpath() {
        Deployment deployment = processEngine.getRepositoryService()//與流程定義和部署對(duì)象相關(guān)的Service
                .createDeployment()//創(chuàng)建一個(gè)部署對(duì)象
                .name("hello")//添加部署的名稱
                .addClasspathResource("bpmn/hello.bpmn")//從classpath的資源中加載,一次只能加載一個(gè)文件
                .addClasspathResource("bpmn/hello.png")//從classpath的資源中加載,一次只能加載一個(gè)文件
                .deploy();//完成部署
        log.info("部署ID:" + deployment.getId());
        log.info("部署名稱:" + deployment.getName());
    }

現(xiàn)在流程定義已經(jīng)有了,下面我們就需要啟動(dòng)這個(gè)流程實(shí)例。

關(guān)于關(guān)于這一步做了什么事情,可以在前面的章節(jié)查看。

2)啟動(dòng)流程實(shí)例

 /**
     * 啟動(dòng)流程實(shí)例
     */
    @Test
    public void startProcessInstance(){
        //1、流程定義的key,通過這個(gè)key來(lái)啟動(dòng)流程實(shí)例
        String processDefinitionKey = "hello";
        //2、與正在執(zhí)行的流程實(shí)例和執(zhí)行對(duì)象相關(guān)的Service
        // startProcessInstanceByKey方法還可以設(shè)置其他的參數(shù),比如流程變量。
        ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key啟動(dòng)流程實(shí)例,key對(duì)應(yīng)helloworld.bpmn文件中id的屬性值,使用key值啟動(dòng),默認(rèn)是按照最新版本的流程定義啟動(dòng)
        log.info("流程實(shí)例ID:"+pi.getId());//流程實(shí)例ID
        log.info("流程定義ID:"+pi.getProcessDefinitionId());//流程定義ID
    }


注意: processDefinitionKey 是 bpmn 文件的名稱。

步驟
1 獲取到 runtimeService 實(shí)例。
2 通過 bpmn 文件的名稱,也就是 processDefinitionKey 來(lái)啟動(dòng)流程實(shí)例。
3 啟動(dòng)流程后,流程的任務(wù)就走到了導(dǎo)師審批節(jié)點(diǎn)。

下面就是查詢個(gè)人任務(wù)了,我們可以查詢導(dǎo)師審批節(jié)點(diǎn)的任務(wù)。

3)查詢個(gè)人任務(wù)

/**
     * 查詢當(dāng)前人的個(gè)人任務(wù)
     */
    @Test
    public void findPersonalTask(){
        String assignee = "sihai";
        List list = processEngine.getTaskService()//與正在執(zhí)行的任務(wù)管理相關(guān)的Service
                .createTaskQuery()//創(chuàng)建任務(wù)查詢對(duì)象
                /**查詢條件(where部分)*/
                .taskAssignee(assignee)//指定個(gè)人任務(wù)查詢,指定辦理人
//                        .taskCandidateUser(candidateUser)//組任務(wù)的辦理人查詢
//                        .processDefinitionId(processDefinitionId)//使用流程定義ID查詢
//                        .processInstanceId(processInstanceId)//使用流程實(shí)例ID查詢
//                        .executionId(executionId)//使用執(zhí)行對(duì)象ID查詢
                /**排序*/
                .orderByTaskCreateTime().asc()//使用創(chuàng)建時(shí)間的升序排列
                /**返回結(jié)果集*/
//                        .singleResult()//返回惟一結(jié)果集
//                        .count()//返回結(jié)果集的數(shù)量
//                        .listPage(firstResult, maxResults);//分頁(yè)查詢
                .list();//返回列表
        if(list!=null && list.size()>0){
            for(Task task:list){
                log.info("任務(wù)ID:"+task.getId());
                log.info("任務(wù)名稱:"+task.getName());
                log.info("任務(wù)的創(chuàng)建時(shí)間:"+task.getCreateTime());
                log.info("任務(wù)的辦理人:"+task.getAssignee());
                log.info("流程實(shí)例ID:"+task.getProcessInstanceId());
                log.info("執(zhí)行對(duì)象ID:"+task.getExecutionId());
                log.info("流程定義ID:"+task.getProcessDefinitionId());
                log.info("********************************************");
            }
        }
    }

通過 sihai 這個(gè)審批人,查詢到了下面的信息。

分析步驟
1 首先通過 getTaskService 方法,獲取到 TaskService 對(duì)象。
2 通過 createTaskQuery 方法創(chuàng)建查詢對(duì)象。
3 通過 taskAssignee 方法設(shè)置審核人。
4 對(duì)于結(jié)果的返回,我們可以通過 orderByTaskCreateTime().asc() 設(shè)置排序等其他信息。

這里需要注意一點(diǎn),查詢到的一個(gè)重要的信息是:任務(wù) id(taskId),下一步,我們需要通過這個(gè)任務(wù) id ,來(lái)完成任務(wù)。

4)辦理個(gè)人任務(wù)

/**
     * 完成我的任務(wù)
     */
    @Test
    public void completePersonalTask() {
        //任務(wù)ID,上一步查詢得到的。
        String taskId = "7504";
        processEngine.getTaskService()//與正在執(zhí)行的任務(wù)管理相關(guān)的Service
                .complete(taskId);
        log.info("完成任務(wù):任務(wù)ID:" + taskId);
    }

通過上一步的任務(wù) id :7504,完成任務(wù)。

步驟
1 首先,通過 getTaskService 方法拿到 TaskService 對(duì)象。
2 調(diào)用 complete 方法,給定具體的任務(wù) id 完成任務(wù)。

5)查詢流程狀態(tài)(判斷流程走到哪一個(gè)節(jié)點(diǎn))
這個(gè)接口還是十分需要的,當(dāng)我們?cè)诰唧w的業(yè)務(wù)中,我們需要判斷我們的流程的狀態(tài)是什么狀態(tài),或者說(shuō)我們的流程走到了哪一個(gè)節(jié)點(diǎn)的時(shí)候,這一個(gè)接口就讓我們實(shí)現(xiàn)業(yè)務(wù)省了非常多的事情。

/**
     * 查詢流程狀態(tài)(判斷流程走到哪一個(gè)節(jié)點(diǎn))
     */
    @Test
    public void isProcessActive() {
        String processInstanceId = "7501";
        ProcessInstance pi = processEngine.getRuntimeService()//表示正在執(zhí)行的流程實(shí)例和執(zhí)行對(duì)象
                .createProcessInstanceQuery()//創(chuàng)建流程實(shí)例查詢
                .processInstanceId(processInstanceId)//使用流程實(shí)例ID查詢
                .singleResult();
        if (pi == null) {
            log.info("流程已經(jīng)結(jié)束");
        } else {
            log.info("流程沒有結(jié)束");
            //獲取任務(wù)狀態(tài)
            log.info("節(jié)點(diǎn)id:" + pi.getActivityId());
        }
    }

步驟:
1 獲取到流程實(shí)例 ProcessInstance 對(duì)象。
2 通過 getActivityId 方法獲取到實(shí)例 Id(節(jié)點(diǎn) id )。

那么拿到了節(jié)點(diǎn) Id 有什么作用呢?
其實(shí),有了這個(gè) Id 之后,我們就可以判斷流程走到哪一步了。例如,上面的輸出的節(jié)點(diǎn) id 是 _4,這個(gè) _4 就是對(duì)應(yīng) 輔導(dǎo)員審批節(jié)點(diǎn)的 id,所以,我們就可以判讀流程其實(shí)是已經(jīng)走到這個(gè)節(jié)點(diǎn)了,后期需要在頁(yè)面顯示流程狀態(tài)的時(shí)候就發(fā)揮作用了。

6)查詢流程執(zhí)行的歷史信息
通過查看 activiti 5 的官方 API 接口,發(fā)現(xiàn)查看歷史信息有下面的查詢接口。

下面我們通過上面的實(shí)例對(duì)下面的方法一一進(jìn)行測(cè)試。

歷史活動(dòng)實(shí)例查詢接口

/**
     * 歷史活動(dòng)查詢接口
     */
    @Test
    public void findHistoryActivity() {
        String processInstanceId = "7501";
        List hais = processEngine.getHistoryService()//
                .createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .list();
        for (HistoricActivityInstance hai : hais) {
            log.info("活動(dòng)id:" + hai.getActivityId()
                    + "   審批人:" + hai.getAssignee()
                    + "   任務(wù)id:" + hai.getTaskId());
            log.info("************************************");
        }
    }

通過這個(gè)接口不僅僅查到這些信息,還有其他的方法,可以獲取更多的關(guān)于歷史活動(dòng)的其他信息。

歷史流程實(shí)例查詢接口

/**
     * 查詢歷史流程實(shí)例
     */
    @Test
    public void findHistoryProcessInstance() {
        String processInstanceId = "7501";
        HistoricProcessInstance hpi = processEngine.getHistoryService()// 與歷史數(shù)據(jù)(歷史表)相關(guān)的Service
                .createHistoricProcessInstanceQuery()// 創(chuàng)建歷史流程實(shí)例查詢
                .processInstanceId(processInstanceId)// 使用流程實(shí)例ID查詢
                .orderByProcessInstanceStartTime().asc().singleResult();
        log.info(hpi.getId() + "    " + hpi.getProcessDefinitionId() + "    " + hpi.getStartTime() + "    "
                + hpi.getEndTime() + "     " + hpi.getDurationInMillis());
    }

這個(gè)接口可以查詢到關(guān)于歷史流程實(shí)例的所有信息。

歷史任務(wù)實(shí)例查詢接口

 /**
     * 查詢歷史任務(wù)
     */
    @Test
    public void findHistoryTask() {
        String processInstanceId = "7501";
        List list = processEngine.getHistoryService()// 與歷史數(shù)據(jù)(歷史表)相關(guān)的Service
                .createHistoricTaskInstanceQuery()// 創(chuàng)建歷史任務(wù)實(shí)例查詢
                .processInstanceId(processInstanceId)//
                .orderByHistoricTaskInstanceStartTime().asc().list();
        if (list != null && list.size() > 0) {
            for (HistoricTaskInstance hti : list) {
                log.info("
 任務(wù)Id:" + hti.getId() + "    任務(wù)名稱:" + hti.getName() + "    流程實(shí)例Id:" + hti.getProcessInstanceId() + "
 開始時(shí)間:"
                        + hti.getStartTime() + "   結(jié)束時(shí)間:" + hti.getEndTime() + "   持續(xù)時(shí)間:" + hti.getDurationInMillis());
            }
        }
    }

這個(gè)查詢接口可以查詢到歷史任務(wù)信息。

歷史流程變量查詢接口

/**
     * 查詢歷史流程變量
     */
    @Test
    public void findHistoryProcessVariables() {
        String processInstanceId = "7501";
        List list = processEngine.getHistoryService()//
                .createHistoricVariableInstanceQuery()// 創(chuàng)建一個(gè)歷史的流程變量查詢對(duì)象
                .processInstanceId(processInstanceId)//
                .list();
        if (list != null && list.size() > 0) {
            for (HistoricVariableInstance hvi : list) {
                log.info("
" + hvi.getId() + "   " + hvi.getProcessInstanceId() + "
" + hvi.getVariableName()
                        + "   " + hvi.getVariableTypeName() + "    " + hvi.getValue());
            }
        }
    }

在這個(gè)實(shí)例中沒有設(shè)置流程變量,所以,這里是查詢不到任何歷史信息的。

這個(gè)接口主要是關(guān)于歷史流程變量的設(shè)置的一些信息。

歷史本地接口查詢接口

/**
     * 通過執(zhí)行sql來(lái)查詢歷史數(shù)據(jù),由于activiti底層就是數(shù)據(jù)庫(kù)表。
     */
    @Test
    public void findHistoryByNative() {
        HistoricProcessInstance hpi = processEngine.getHistoryService()
                .createNativeHistoricProcessInstanceQuery()
                .sql("查詢底層數(shù)據(jù)庫(kù)表的sql語(yǔ)句")
                .singleResult();
        log.info("
" + hpi.getId() + "    " + hpi.getProcessDefinitionId() + "    " + hpi.getStartTime()
                + "
" + hpi.getEndTime() + "     " + hpi.getDurationInMillis());
    }

這個(gè)接口是提供直接通過 sql 語(yǔ)句來(lái)查詢歷史信息的,我們只需要在 sql() 方法中寫原生的 sql 語(yǔ)句就可以進(jìn)行數(shù)據(jù)查詢。

寫到這里,我想應(yīng)該通過這樣的一個(gè)完整的實(shí)例將 Activiti 工作流的 API 都介紹的差不多了,這一節(jié)到這里也就要說(shuō)拜拜了。再回看一下文章開頭的 API 接口,這也算是這一節(jié)的總結(jié)。

文章有不當(dāng)之處,歡迎指正,如果喜歡微信閱讀,你也可以關(guān)注我的微信公眾號(hào)好好學(xué)java,獲取優(yōu)質(zhì)學(xué)習(xí)資源。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74853.html

相關(guān)文章

  • Activiti作流入門入土:整合spring

    摘要:文章源碼托管歡迎一前言在上一節(jié)中,通過一個(gè)入門程序,把的環(huán)境準(zhǔn)備好了,這一節(jié),將整合,并且部署一個(gè)最簡(jiǎn)單的流程圖。測(cè)試結(jié)果四總結(jié)這一節(jié)通過整合,繪制簡(jiǎn)單的文件,然后成功部署了文件。 文章源碼托管:https://github.com/OUYANGSIHA...歡迎 star !?。?一、前言 在上一節(jié)中,通過一個(gè)入門程序,把a(bǔ)ctiviti的環(huán)境準(zhǔn)備好了,這一節(jié),將整合spring,并...

    piglei 評(píng)論0 收藏0
  • Activiti作流入門入土入門實(shí)例

    摘要:二環(huán)境準(zhǔn)備編譯器選擇這里我們使用進(jìn)行工作流開發(fā),雖然對(duì)于工作流的友好度不是很好,因?yàn)闀?huì)有一些小的,但是,對(duì)于的開發(fā)還是非常的好的。新建后出現(xiàn)下面的編輯頁(yè)面到現(xiàn)在,編輯插件就準(zhǔn)備好了。 文章源碼托管:https://github.com/OUYANGSIHA...歡迎 star ?。?! 一、前言 在上一節(jié)中我們對(duì)activiti進(jìn)行了基本的介紹activiti進(jìn)行了基本的介紹,同時(shí)介紹了...

    SwordFly 評(píng)論0 收藏0
  • Activiti作流入門入土作流簡(jiǎn)介

    摘要:基于許可的開源平臺(tái),創(chuàng)始人是的項(xiàng)目架構(gòu)師,它特色是提供了插件,開發(fā)人員可以通過插件直接繪畫出業(yè)務(wù)流程圖。二工作流引擎對(duì)象,這是工作的核心。五總結(jié)工作流的概念就先介紹這么多了,更多的去官網(wǎng)查看,下一節(jié)將用一個(gè)入門的實(shí)例來(lái)對(duì)工作流進(jìn)行講解。 文章源碼托管:https://github.com/OUYANGSIHA...歡迎 star !?。?一、activiti介紹 Activiti5是由...

    Mr_houzi 評(píng)論0 收藏0
  • Activiti指南(介紹)

    摘要:介紹這個(gè)快速入門假定熟悉和使用的開發(fā)環(huán)境本教程將引用以下變量變量描述項(xiàng)目的根位置從下載的解壓縮文件的根位置。的名稱建議將其作為。 介紹 這個(gè)快速入門假定: 熟悉Maven和Java 使用Java的開發(fā)環(huán)境 本教程將引用以下變量: 變量 描述 $mvnProject maven項(xiàng)目的根位置. $actUnzipedPack 從http://www.activiti.or...

    skinner 評(píng)論0 收藏0
  • Activiti就是這么簡(jiǎn)單

    摘要:介紹什么是是由軟件在年月日發(fā)布的業(yè)務(wù)流程管理框架,它是覆蓋了業(yè)務(wù)流程管理工作流服務(wù)協(xié)作等領(lǐng)域的一個(gè)開源的靈活的易擴(kuò)展的可執(zhí)行流程語(yǔ)言框架。第二部分是表示表的用途的兩個(gè)字母標(biāo)識(shí)。 Activiti介紹 什么是Activiti? Activiti5是由Alfresco軟件在2010年5月17日發(fā)布的業(yè)務(wù)流程管理(BPM)框架,它是覆蓋了業(yè)務(wù)流程管理、工作流、服務(wù)協(xié)作等領(lǐng)域的一個(gè)開源的、靈...

    everfly 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<