activiti 選人的實現

activiti默認是不帶有選人的功能的,它默認的是在調用complete 方法的時候自動根據下一個節點的 assignee屬性或者candidate屬性 設置下一節點的候選人或者 assginee。 

因爲項目的緣由咱們須要實如今上一個節點提交的時候設置就要從幾個候選審批人員中選擇一個或者幾個審批人員,下面的代碼寫了個Junit 的demo。 



java

Java代碼   收藏代碼
  1. package test.java.org.activiti.designer.test;  
  2.   
  3. import static org.junit.Assert.*;  
  4.   
  5. import java.util.ArrayList;  
  6. import java.util.Collection;  
  7. import java.util.HashMap;  
  8. import java.util.List;  
  9. import java.util.Map;  
  10. import java.io.FileInputStream;  
  11.   
  12. import org.activiti.bpmn.model.BpmnModel;  
  13. import org.activiti.bpmn.model.FlowElement;  
  14. import org.activiti.bpmn.model.Process;  
  15. import org.activiti.bpmn.model.SequenceFlow;  
  16. import org.activiti.engine.IdentityService;  
  17. import org.activiti.engine.RepositoryService;  
  18. import org.activiti.engine.RuntimeService;  
  19. import org.activiti.engine.TaskService;  
  20. import org.activiti.engine.impl.persistence.entity.TaskEntity;  
  21. import org.activiti.engine.runtime.ProcessInstance;  
  22. import org.activiti.engine.task.Task;  
  23. import org.activiti.engine.test.ActivitiRule;  
  24. import org.junit.Rule;  
  25. import org.junit.Test;  
  26.   
  27. public class ProcessTest {  
  28.   
  29.     private String filename = "E:\\workspace4.3\\kft-activiti-demo-no-maven\\resources\\diagrams\\test2.bpmn";  
  30.   
  31.     @Rule  
  32.     public ActivitiRule activitiRule = new ActivitiRule();  
  33.     static RuntimeService runtimeService;  
  34.     static TaskService taskService;  
  35.     static IdentityService identityService;  
  36.       
  37.     static RepositoryService repositoryService;  
  38.       
  39.       
  40.     //流程定義編號  
  41.     private String processDefinitionId ;  
  42.     //任務編號  
  43.     //private String taskId;  
  44.     //流程實例號  
  45.     private String processInstanceId;  
  46.     @Test  
  47.     public void mainTest() throws Exception {  
  48.           
  49.         repositoryService = activitiRule.getRepositoryService();      
  50.         runtimeService = activitiRule.getRuntimeService();  
  51.         taskService = activitiRule.getTaskService();  
  52.   
  53.         ProcessTest ptm = new ProcessTest();  
  54.         //這裏有個問題,runtimeService.startProcessInstanceByKey 這個方法直接就把流程流轉到任務用戶去了,沒通過選人的操做  
  55.         //這裏就變通一下處理,提交到一個無所謂的人,而後在調用方法修改這我的。  
  56.         String taskId;  
  57.         //返回的usertask的id  
  58.         taskId = ptm.startProcess();  
  59.         //**********流程啓動成功  
  60.         //流程在第一個審批人哪裏  
  61.         //taskId = ptm.getNextNodeId(1,"feng");  
  62.         //選人  
  63.         List<String> userList= ptm.getNextTaskUserByTaskId(taskId);  
  64.         //設置審批人  
  65.         ptm.setApproveUser(taskId, "feng");  
  66.   
  67.         taskId = ptm.getNextNodeId(1,"feng");  
  68.           
  69.         //第一個審批人提交流程  feng 爲當前節點審批人,xiaozhang 爲設置的下一節點審批人  
  70.         ptm.completeByAssignee("feng","xiaozhang");  
  71.         //************第一我的審批成功  
  72.           
  73.   
  74.   
  75.         taskId = ptm.getNextNodeId(1,"xiaozhang");  
  76.         //選人  
  77.         userList= ptm.getNextTaskUserByTaskId(taskId);  
  78.         //第一個審批人提交流程  
  79.         ptm.completeByAssignee("xiaozhang","xiaoming");  
  80.   
  81.         ptm.getNextNodeId(1,"xiaoming");  
  82.           
  83.         //第二個審批人提交流程  
  84.         ptm.completeByAssignee("xiaoming","xiangwang");  
  85.         //************第二我的審批成功  
  86.   
  87.   
  88.   
  89.     }  
  90.     //啓動流程  
  91.     public String startProcess() throws Exception {  
  92.           
  93.         repositoryService.createDeployment().addInputStream("test2.bpmn20.xml",new FileInputStream(filename)).deploy();  
  94.         Map<String, Object> variableMap = new HashMap<String, Object>();  
  95.         variableMap.put("name", "Activiti");  
  96.           
  97.           
  98.         //啓動流程  
  99.         ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("test2", variableMap);  
  100.   
  101.         processDefinitionId = processInstance.getProcessDefinitionId();  
  102.         processInstance.getId();  
  103.         List<TaskEntity> tList =  ((org.activiti.engine.impl.persistence.entity.ExecutionEntity) processInstance).getTasks();  
  104.           
  105.         this.setProcessInstanceId( processInstance.getId() );  
  106.           
  107.         this.setProcessDefinitionId(processDefinitionId);  
  108.           
  109.         if(tList.size()!=1) {  
  110.             System.err.println("start節點的輸出路由不能有多個");  
  111.         }  
  112.         return tList.get(0).getId();  
  113.   
  114.     }  
  115.   
  116.     public void queryProcessInstance() {  
  117.         List<ProcessInstance> instanceList = runtimeService  
  118.                 .createProcessInstanceQuery().processDefinitionKey("test")  
  119.                 .list();  
  120.         //查詢 流程實例  
  121.         for (ProcessInstance queryProcessInstance : instanceList) {  
  122.             queryProcessInstance.getActivityId();  
  123.               
  124.             System.out.print("-----queryProcessInstance:"+queryProcessInstance.getActivityId());  
  125.               
  126.             assertEquals(false, queryProcessInstance.isEnded());  
  127.             System.out.println("id " + queryProcessInstance.getId()  
  128.                     + ", ended=" + queryProcessInstance.isEnded()+",ProcessDefinitionId="+queryProcessInstance.getProcessDefinitionId());  
  129.         }  
  130.     }  
  131.     //根據assignee來查詢用戶  
  132.     public void queryTask(String assignee) {  
  133.         //startProcessInstance();  
  134.           
  135.         // taskService.createTaskQuery().taskCandidateGroup("sales").singleResult();  
  136.           
  137.         Task task= taskService.createTaskQuery().taskAssignee(assignee).singleResult();  
  138.           
  139.           
  140.         System.out.println("審批人爲【"+assignee+"】的任務有:任務編號爲【" + task.getId() + "】"+ task.getTaskDefinitionKey());  
  141.   
  142.     }  
  143.     /**  
  144.      *   
  145.      * @param queryType  查詢類型1 根據 assignee 查詢  2 根據candidateuser查詢  
  146.      * @param str  
  147.      */  
  148.     public String getNextNodeId(int queryType,String str) {  
  149.           
  150.           
  151.         Task task = null;  
  152.         if(queryType==1) {  
  153.             task = taskService.createTaskQuery().taskAssignee(str).singleResult();  
  154.         }else if(queryType==2){  
  155.             task = taskService.createTaskQuery().taskCandidateUser(str).singleResult();  
  156.   
  157.         }else if(queryType==3){  
  158.             task = taskService.createTaskQuery().taskCandidateGroup(str).singleResult();  
  159.   
  160.         }  
  161.           
  162.         List<FlowElement> list = getNextNode(task.getId());  
  163.           
  164.           
  165.         if(task==null) {  
  166.             return null;  
  167.         }  
  168.           
  169.           
  170.         for(FlowElement e :list) {  
  171.             //((org.activiti.bpmn.model.UserTask) e)  
  172.         }  
  173.           
  174.         return task.getId();  
  175.               
  176.     }  
  177.     /** 
  178.      * 獲取流程的下一個節點 且要通過規則引擎判斷後的節點 
  179.      * @param taskId 
  180.      * @return 
  181.      */  
  182.     private List<FlowElement> getNextNode(String taskId) {  
  183.           
  184.         Task task = null;  
  185.         task = taskService.createTaskQuery().taskId(taskId).singleResult();  
  186.         if(task==null) {  
  187.             return null;  
  188.         }  
  189.         List<FlowElement> list = new ArrayList<FlowElement>();  
  190.           
  191.         ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();  
  192.           
  193.         //當前活動節點  
  194.         String activitiId = processInstance.getActivityId();  
  195.           
  196.         System.out.println("當前節點是【"+activitiId+"】");  
  197.   
  198.         //pmmnModel 遍歷節點須要它  
  199.         BpmnModel bpmnModel =  repositoryService.getBpmnModel(task.getProcessDefinitionId());  
  200.   
  201.         List<Process> processList = bpmnModel.getProcesses();  
  202.           
  203.         //循環多個物理流程  
  204.         for(Process process:processList) {  
  205.               
  206.             //返回該流程的全部任務,事件  
  207.             Collection<FlowElement> cColl = process.getFlowElements();  
  208.             //遍歷節點  
  209.             for(FlowElement f :cColl) {  
  210.                   
  211.                   
  212.                 //若是改節點是當前節點 者 輸出該節點的下一個節點  
  213.                 if(f.getId().equals(activitiId)) {  
  214.                   
  215.                     List<SequenceFlow>  sequenceFlowList = new ArrayList<SequenceFlow>();  
  216.                     //經過反射來判斷是哪一種類型  
  217.                     if(f instanceof org.activiti.bpmn.model.StartEvent) {  
  218.                         //開始事件的輸出路由  
  219.                         sequenceFlowList    = ((org.activiti.bpmn.model.StartEvent) f).getOutgoingFlows();  
  220.                     }else if(f instanceof org.activiti.bpmn.model.UserTask) {  
  221.                           
  222.                         sequenceFlowList    = ((org.activiti.bpmn.model.UserTask) f).getOutgoingFlows();  
  223.                           
  224.                           
  225.                         for(SequenceFlow sf :sequenceFlowList)  {  
  226.                               
  227.                             String targetRef = sf.getTargetRef();  
  228.                             FlowElement ref = process.getFlowElement(targetRef);  
  229.                               
  230.                         //  nextActivitiIdList.add(ref.getId());  
  231.                               
  232.                             list.add(ref);  
  233.                         }  
  234.                           
  235.                     }else if(f instanceof org.activiti.bpmn.model.SequenceFlow) {  
  236.                       
  237.                           
  238.                     }else if(f instanceof org.activiti.bpmn.model.EndEvent) {  
  239.                         sequenceFlowList    = ((org.activiti.bpmn.model.EndEvent) f).getOutgoingFlows();  
  240.                     }  
  241.                     break;  
  242.                 }   
  243.                       
  244.             }  
  245.               
  246.         }     
  247.         return list;  
  248.     }   
  249.     //流程流轉到下一步  
  250.     public void completeByAssignee(String assignee,String nextUser) throws Exception {  
  251.           
  252.         HashMap<String,Object> map = new HashMap<String,Object>();  
  253.           
  254.         map.put("nextUser", nextUser);  
  255.         Task task = taskService.createTaskQuery().taskAssignee(assignee).singleResult();  
  256.         taskService.complete(task.getId(),map);  
  257.         System.out.println("完成任務 編號爲【" + task.getId() + "】,名稱爲【"+task.getName()+"】的任務");  
  258.     }  
  259.     /** 
  260.      * 設置某個節點的審批人員 
  261.      * @param taskId 
  262.      * @param user 
  263.      */  
  264.     public void setApproveUser(String taskId,String user) {  
  265.         Task task = taskService.createTaskQuery().taskId(taskId).singleResult();  
  266.         task.setAssignee(user);  
  267.         taskService.saveTask(task);  
  268.     }  
  269.   
  270.     /** 
  271.      * 取下一個節點的審批人 
  272.      * @param taskId 
  273.      * @return 
  274.      */  
  275.     public List<String> getNextTaskUserByTaskId(String taskId) {  
  276.         List<String> list = new ArrayList<String>();  
  277.           
  278.         List<FlowElement> fList = getNextNode(taskId);  
  279.           
  280.           
  281.         for(FlowElement u:fList){  
  282.               
  283.             String str =  ((org.activiti.bpmn.model.UserTask) u).getAssignee();   
  284.             list.add(str);  
  285.         }  
  286.         return list ;  
  287.     }  
  288.       
  289.     /** 
  290.      * 找當前節點的候選審批人  供流程實例start後調用 
  291.      * @param taskId 
  292.      * @return 
  293.      */  
  294.     public List<String> getThisTaskUser(String taskId) {  
  295.         List<String> list = new ArrayList<String>();  
  296.         Task task = taskService.createTaskQuery().taskId(taskId).singleResult();  
  297.         String taskUser = task.getAssignee();  
  298.           
  299.         //*****************************根據taskUser的配置到本身的表裏面去找數據  
  300.           
  301.         list.add(taskUser);  
  302.         return list ;  
  303.     }  
  304.     public String getProcessDefinitionId() {  
  305.         return processDefinitionId;  
  306.     }  
  307.   
  308.     public void setProcessDefinitionId(String processDefinitionId) {  
  309.         this.processDefinitionId = processDefinitionId;  
  310.     }  
  311.   
  312.     public String getProcessInstanceId() {  
  313.         return processInstanceId;  
  314.     }  
  315.   
  316.     public void setProcessInstanceId(String processInstanceId) {  
  317.         this.processInstanceId = processInstanceId;  
  318.     }  
  319. }  


另外再繪製流程圖的時候除了首節點,其他每一個節點要設置listener ,能夠設置一個公共的listener 傳遞不一樣的參數代碼如: sql

Java代碼   收藏代碼
  1. package org.activiti.ext;  
  2.   
  3.   
  4. import java.sql.Connection;  
  5. import java.sql.ResultSet;  
  6. import java.sql.SQLException;  
  7. import java.sql.Statement;  
  8. import java.util.ArrayList;  
  9. import java.util.HashMap;  
  10. import java.util.List;  
  11. import java.util.Map;  
  12.   
  13. import javax.sql.DataSource;  
  14.   
  15. import org.activiti.engine.delegate.DelegateExecution;  
  16. import org.activiti.engine.delegate.DelegateTask;  
  17. import org.activiti.engine.delegate.ExecutionListener;  
  18. import org.activiti.engine.delegate.TaskListener;  
  19. import org.apache.ibatis.annotations.Delete;  
  20. import org.slf4j.Logger;  
  21. import org.slf4j.LoggerFactory;  
  22.   
  23. public class TaskUserQuery implements TaskListener{  
  24.   
  25.       
  26.       /** 
  27.      *  
  28.      */  
  29.     private static final long serialVersionUID = 1L;  
  30.     private static Logger logger = LoggerFactory.getLogger(TaskUserQuery.class);  
  31.   
  32.     protected DataSource dataSource;  
  33.   
  34.       
  35.       
  36.     private org.activiti.engine.impl.el.FixedValue orgLevel ;  
  37.     private org.activiti.engine.impl.el.FixedValue dutyNo ;  
  38.     public DataSource getDataSource() {  
  39.         return dataSource;  
  40.     }  
  41.     public void setDataSource(DataSource dataSource) {  
  42.         this.dataSource = dataSource;  
  43.     }  
  44.     /** 
  45.      * 審批過程當中找人的方法 
  46.      * @param str 組名 
  47.      * @return 
  48.      * @throws SQLException 
  49.      */  
  50.     public String getTaskUser(String str) throws SQLException {  
  51.         logger.debug("-------------------自定義找人----------------------------getTaskUser");  
  52.           
  53.         Connection conn = dataSource.getConnection();  
  54.           
  55.         Statement state = conn.createStatement();  
  56.         String queryTaskUserSql = "select id_ from act_id_user aiu where exists (select 1 from act_id_membership aim where aim.user_id_ = aiu.id_ and  aim.group_id_='"+str+"' )";  
  57.           
  58.         ResultSet rs = state.executeQuery(queryTaskUserSql);  
  59.         rs.next();  
  60.         logger.debug("-------------------自定義找人----------------------------:返回的人是"+rs.getString(1));  
  61.           
  62.         conn.close();  
  63.         state.close();  
  64.         return rs.getString(1);  
  65.           
  66.     }   
  67.       
  68.     public List<String> getTaskUserList(String str) throws SQLException {  
  69.         logger.debug("-------------------自定義找人----------------------------getTaskUserList");  
  70.         List<String> taskUser = new ArrayList<String>();  
  71.           
  72.         Connection conn = dataSource.getConnection();  
  73.           
  74.         Statement state = conn.createStatement();  
  75.         String queryTaskUserSql = "select id_ from act_id_user aiu where exists (select 1 from act_id_membership aim where aim.user_id_ = aiu.id_ and  aim.group_id_='"+str+"' )";  
  76.           
  77.         ResultSet rs = state.executeQuery(queryTaskUserSql);  
  78.         while(rs.next()) {  
  79.             taskUser.add(rs.getString(1));  
  80.         }  
  81.         logger.debug("------------------- 自定義找人----------------------------:返回的人是"+taskUser.toString());  
  82.           
  83.         conn.close();  
  84.         state.close();  
  85.         return taskUser;  
  86.           
  87.     }   
  88.     @Override  
  89.     public void notify(DelegateTask delegateTask) {  
  90.           
  91.           
  92.         Map<String,Object> map = delegateTask.getVariables();  
  93.         String taskId = delegateTask.getId();  
  94.           
  95.         System.out.println("in taskUserQuer class variable is:"+map.toString());  
  96.         System.out.println("in taskUserQuer class taskid is:"+taskId);  
  97.         System.out.println("in taskUserQuer class orgLevel is:"+orgLevel.getExpressionText());  
  98.           
  99.           
  100.           
  101.         String id = delegateTask.getId();  
  102.         String s = delegateTask.getAssignee();  
  103.         //根據流程變量的內容設置下一個節點的審批人  
  104.         delegateTask.setAssignee(map.get("nextUser").toString());  
  105.           
  106.         Map<String,Object> m1 = delegateTask.getExecution().getVariables();  
  107.         Map<String,Object> m2 = delegateTask.getVariablesLocal();  
  108.           
  109.           
  110.           
  111. //      logger.debug("-----------------------------------------id is:"+id);  
  112. //  //  logger.debug("-----------------------------------------arg is:"+dutyNo.getExpressionText());  
  113. //      delegateTask.setAssignee(dutyNo.getExpressionText());  
  114.           
  115.         // TODO Auto-generated method stub  
  116. //      logger.debug("----------------------設置選人 開始--------------------------");  
  117. //      delegateTask.setAssignee("admin");    
  118. //      logger.debug("----------------------設置選人 結束--------------------------");  
  119.     }  
  120.   
  121. }  



整個選人過程的其實比較簡單 是:提交流程的時候將下一審批人做爲流程變量提交到流程引擎,流程引擎會調用如上代碼塊的notify 方法(固然須要在usertask上配置 配置下圖) ,在notify方法內delegateTask.setAssignee設置下一個節點的審批人 

apache

相關文章
相關標籤/搜索