activiti5學習筆記(二)僞審批匯總流程

僞彙總審批,就是每一條流程都是獨立的,這些獨立的流程在走到某個節點的時候,這個節點的審批人可以一次性進行多個任務的審批。
 
開發環境
JDK1.6
Activiti5.13
Eclipse
MYSQL5
簡單起見,這裏沒有做一個web的項目,只是一個Java程序。
 
業務場景
預算填報員填寫本單位的預算,預算提交到本單位的上級進行審批,上級審批後提交到總公司進行審批。
有多少個預算到了總公司審批人處,就可以對多少的預算同時進行審批,這些流程都是相對獨立的。
業務數據存儲在單獨的報表系統中,節點可以配置打開報表的方式,表單ID,及節點是否彙總審批。
 
程序模擬
爲方便起見
1)所有單位的預算員,審批人,彙總審批人都用三個人,kermit, fozzie,admin直接配在流程圖中,實際上kermit和fozzie應會是不同的人,可以動態傳入流程啓動流程
2)節點是否需要彙總,可以根據在節點的參數isSum來進行動態的判定,是否執行彙總審批,程序只是展示效果,具體沒有實現動態的,實現起來並不困難。
3)爲了直觀,節點參數都使用了中文,實際開發中肯定是編碼形式
 
流程參數說明:
流程實例級別的參數有兩個,一個填報期間period一個填報單位fillAccount
節點級別的配置參數有四個,三個固定的報表唯一編碼sheetId,報表打開方式fillType和是否彙總isSum,一個在流程實例中動態生成的,當前節點的操作單位accountCode
 
1. 繪製流程圖

總體配置
 
填寫預算配置



審批預算配置


彙總審批預算配置
 

2. 測試程序
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.engine.FormService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.task.Task;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestFormData {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // 加載spring配置
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        RuntimeService runtimeService = (RuntimeService) ctx
                .getBean("runtimeService");
        ProcessEngine processEngine = (ProcessEngine) ctx
                .getBean("processEngine");
        FormService formService = (FormService) ctx.getBean("formService");
        TaskService taskService = (TaskService) ctx.getBean("taskService");
        // 發佈流程
        RepositoryService repositoryService = processEngine
                .getRepositoryService();
        repositoryService.createDeployment()
                .addClasspathResource("diagrams/formDataTest.bpmn").deploy();
        fill(runtimeService, formService, taskService);
        singleCheck(formService, taskService);
        sum(taskService, formService);
    }
    /**
     * 填報預算
     *
     * @param runtimeService
     * @param formService
     * @param taskService
     */
    private static void fill(RuntimeService runtimeService,
            FormService formService, TaskService taskService) {
        // 流程開始參數,設置填報期間
        Map<String, Object> p = new HashMap<String, Object>();
        p.put("period", "2013-07");
        // 生成3家單位填報
        for (int i = 0; i < 3; i++) {
            // 開始流程
            runtimeService.startProcessInstanceByKey("formDataTest", p);
            System.out
                    .println("=====================kermit開始填報=======================");
            // query kermit's tasks;
            List<Task> tasks = taskService.createTaskQuery()
                    .taskAssignee("kermit").list();
            for (Task task : tasks) {
                if ("fill".equals(task.getTaskDefinitionKey())) {
                    // 設置填報人單位編碼記錄在節點
                    taskService.setVariableLocal(task.getId(), "accoutCode",
                            "A110" + i);
                    // 設置該流程實例的填報單位
                    taskService.setVariable(task.getId(), "fillAccount", "A110"
                            + i);
                    Map<String, FormProperty> propMap = createMap(formService
                            .getTaskFormData(task.getId()).getFormProperties());
                    // 獲取節點報表打開類型
                    String fillType = (String) propMap.get("fillType")
                            .getValue();
                    // 獲取節點報表表單ID
                    String sheetId = (String) propMap.get("sheetId").getValue();
                    // 獲取節點是否需要彙總參數
                    String isSum = (String) propMap.get("isSum").getValue();
                    // 獲取節點填報單位編碼
                    String accoutCode = (String) taskService.getVariableLocal(
                            task.getId(), "accoutCode");
                    // 獲取流程填報單位編碼
                    String fillAccount = (String) taskService.getVariable(
                            task.getId(), "fillAccount");
                    // 獲取流程填報期間
                    String period = (String) taskService.getVariable(
                            task.getId(), "period");
                    // 打印填報信息
                    System.out.println("\t打開報表類型:" + fillType);
                    System.out.println("\t填報表單:" + sheetId);
                    System.out.println("\t填報期間:" + period);
                    System.out.println("\t是否彙總:" + isSum);
                    System.out.println("\t當前節點賬號:" + accoutCode);
                    System.out.println("\t提交審批表單填報單位:" + fillAccount);
                    // 節點任務結束
                    taskService.complete(task.getId());
                    System.out
                            .println("=============kermit填寫預算單任務已完成=====================");
                    System.out.println();
                }
            }
        }
    }
    /**
     * 單個審覈
     *
     * @param formService
     * @param taskService
     */
    private static void singleCheck(FormService formService,
            TaskService taskService) {
        System.out
                .println("=====================fozzie開始單個審覈=======================");
        // query fozzie's tasks;
        List<Task> tasks2 = taskService.createTaskQuery()
                .taskAssignee("fozzie")
                .processVariableValueEquals("period", "2013-07")
                .processDefinitionKey("formDataTest").list();
        int count = 1;
        for (Task task : tasks2) {
            if ("check".equals(task.getTaskDefinitionKey())) {
                System.out.println("\t審覈第" + count + "個");
                // 設置節點審批人單位編碼
                taskService.setVariableLocal(task.getId(), "accoutCode",
                        "A1199");
                Map<String, FormProperty> propMap = createMap(formService
                        .getTaskFormData(task.getId()).getFormProperties());
                // 獲取節點報表打開類型
                String fillType = (String) propMap.get("fillType").getValue();
                // 獲取節點報表表單ID
                String sheetId = (String) propMap.get("sheetId").getValue();
                // 獲取節點是否需要彙總參數
                String isSum = (String) propMap.get("isSum").getValue();
                // 獲取節點填報單位編碼
                String accoutCode = (String) taskService.getVariableLocal(
                        task.getId(), "accoutCode");
                // 獲取流程填報單位編碼
                String fillAccount = (String) taskService.getVariable(
                        task.getId(), "fillAccount");
                // 獲取流程填報期間
                String period = (String) taskService.getVariable(task.getId(),
                        "period");
                // 打印填報信息
                System.out.println("\t報表打開類型:" + fillType);
                System.out.println("\t填報表單:" + sheetId);
                System.out.println("\t填報期間:" + period);
                System.out.println("\t是否彙總:" + isSum);
                System.out.println("\t當前節點賬號:" + accoutCode);
                System.out.println("\t提交審批表單填報單位:" + fillAccount);
                // 節點任務結束
                taskService.complete(task.getId());
                System.out.println("\t審覈第" + count + "個完成");
                System.out.println();
                count++;
            }
        }
        System.out
                .println("===================fozzie審批預算單任務已完成===================");
        System.out.println();
    }
    /**
     * 彙總審覈
     *
     * @param taskService
     * @param formService
     */
    private static void sum(TaskService taskService, FormService formService) {
        System.out
                .println("=======================admin開始彙總審覈=====================");
        List<Task> tasks3 = taskService.createTaskQuery()
                .taskAssignee("admin")
                .processVariableValueEquals("period", "2013-07")
                .processDefinitionKey("formDataTest").list();
        // 批量審批列表
        List<String> completeTaskIdList = new ArrayList<String>();
        // 獲取節點報表打開類型
        String fillType = "";
        // 獲取節點報表表單ID
        String sheetId = "";
        // 獲取節點是否需要彙總參數
        String isSum = "";
        // 獲取流程填報期間
        String period = "";
        for (Task task : tasks3) {
            if ("sum".equals(task.getTaskDefinitionKey())) {
                // 設置節點審批人單位編碼
                taskService.setVariableLocal(task.getId(), "accoutCode",
                        "A1199");
                // 獲取流程填報單位編碼
                String fillAccount = (String) taskService.getVariable(
                        task.getId(), "fillAccount");
                Map<String, FormProperty> propMap = createMap(formService
                        .getTaskFormData(task.getId()).getFormProperties());
                // 獲取節點報表打開類型
                fillType = (String) propMap.get("fillType").getValue();
                // 獲取節點報表表單ID
                sheetId = (String) propMap.get("sheetId").getValue();
                // 獲取節點是否需要彙總參數
                isSum = (String) propMap.get("isSum").getValue();
                // 獲取流程填報期間
                period = (String) taskService.getVariable(task.getId(),
                        "period");
                // 打印填報信息
                System.out.println("\t提交匯總審批表單填報單位:" + fillAccount);
                // 加入批量審批列表
                completeTaskIdList.add(task.getId());
            }
        }
        System.out.println("\t報表打開類型:" + fillType);
        System.out.println("\t填報表單:" + sheetId);
        System.out.println("\t填報期間:" + period);
        System.out.println("\t是否彙總:" + isSum);
        System.out.println("\t全部審批通過");
        for (String t : completeTaskIdList) {
            taskService.complete(t);
        }
        System.out.println("=========admin彙總預算單任務已完成,彙總審批"
                + completeTaskIdList.size() + "個單位=======");
    }
    private static Map<String, FormProperty> createMap(List<FormProperty> props) {
        Map<String, FormProperty> re = new HashMap<String, FormProperty>();
        for (FormProperty p : props) {
            re.put(p.getId(), p);
        }
        return re;
    }
}


 
3. 運行結果
=====================kermit開始填報=======================
    打開報表類型:普通填報
    填報表單:1
    填報期間:2013-07
    是否彙總:不彙總
    當前節點賬號:A1100
    提交審批表單填報單位:A1100
=============kermit填寫預算單任務已完成=====================
=====================kermit開始填報=======================
    打開報表類型:普通填報
    填報表單:1
    填報期間:2013-07
    是否彙總:不彙總
    當前節點賬號:A1101
    提交審批表單填報單位:A1101
=============kermit填寫預算單任務已完成=====================
=====================kermit開始填報=======================
    打開報表類型:普通填報
    填報表單:1
    填報期間:2013-07
    是否彙總:不彙總
    當前節點賬號:A1102
    提交審批表單填報單位:A1102
=============kermit填寫預算單任務已完成=====================
 
=====================fozzie開始單個審覈=======================
    審覈第1個
    報表打開類型:普通打開
    填報表單:2
    填報期間:2013-07
    是否彙總:不彙總
    當前節點賬號:A1199
    提交審批表單填報單位:A1100
    審覈第1個完成
 
    審覈第2個
    報表打開類型:普通打開
    填報表單:2
    填報期間:2013-07
    是否彙總:不彙總
    當前節點賬號:A1199
    提交審批表單填報單位:A1101
    審覈第2個完成
 
    審覈第3個
    報表打開類型:普通打開
    填報表單:2
    填報期間:2013-07
    是否彙總:不彙總
    當前節點賬號:A1199
    提交審批表單填報單位:A1102
    審覈第3個完成
===================fozzie審批預算單任務已完成===================
 
=======================admin開始彙總審覈=====================
    提交匯總審批表單填報單位:A1100
    提交匯總審批表單填報單位:A1101
    提交匯總審批表單填報單位:A1102
    報表打開類型:彙總到一張表打開
    填報表單:3
    填報期間:2013-07
    是否彙總:彙總
    全部審批通過
=========admin彙總預算單任務已完成,彙總審批3個單位=======
 
附applicationContext.xml,數據庫使用MYSQL5
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/test_activiti" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- Activiti begin -->
    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
        <property name="dataSource" ref="dataSource" />
        <property name="transactionManager" ref="transactionManager" />
        <property name="databaseSchemaUpdate" value="true" />
        <property name="jobExecutorActivate" value="false" />
        <property name="history" value="full" />
        <property name="processDefinitionCacheLimit" value="10" />
    </bean>
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration" />
    </bean>
    <bean id="repositoryService" factory-bean="processEngine"
        factory-method="getRepositoryService" />
    <bean id="runtimeService" factory-bean="processEngine"
        factory-method="getRuntimeService" />
    <bean id="formService" factory-bean="processEngine"
        factory-method="getFormService" />
    <bean id="identityService" factory-bean="processEngine"
        factory-method="getIdentityService" />
    <bean id="taskService" factory-bean="processEngine"
        factory-method="getTaskService" />
    <bean id="historyService" factory-bean="processEngine"
        factory-method="getHistoryService" />
    <bean id="managementService" factory-bean="processEngine"
        factory-method="getManagementService" />
    <!-- Activiti end -->
 
</beans>


 
項目引用jar包就是activiti-explorer裏用的所有jar包+mysql的驅動
 
END
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章