Activiti 學習筆記13:分配組任務
一、流程圖
二、分配組任務方式一(直接指定辦理人)
1:流程圖中任務節點的配置
2:測試程式碼
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//部署流程定義,啟動流程例項
@Test
public void testTask() throws Exception {
// 1 釋出流程
InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn" );
InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png");
processEngine.getRepositoryService()//
.createDeployment()//
.addInputStream("userTask.bpmn", inputStreamBpmn)//
.addInputStream("userTask.png" , inputStreamPng)//
.deploy();
// 2 啟動流程
ProcessInstance pi = processEngine.getRuntimeService()//
.startProcessInstanceByKey("taskProcess");
System.out.println("pid:" + pi.getId());
}
//3 查詢我的個人任務列表
@Test
public void findMyTaskList(){
String userId = "小A" ;
List<Task> list = processEngine.getTaskService()//
.createTaskQuery()//
.taskAssignee(userId)//指定個人任務查詢
.list();
for(Task task:list ){
System.out.println("id="+task.getId());
System.out.println("name="+task.getName());
System.out.println("assinee="+task.getAssignee());
System.out.println("createTime="+task.getCreateTime());
System.out.println("executionId="+task.getExecutionId());
}
}
//4 查詢組任務列表
@Test
public void findGroupList(){
String userId = "小A";
List<Task> list = processEngine.getTaskService()//
.createTaskQuery()//
.taskCandidateUser(userId)//指定組任務查詢
.list();
for(Task task:list ){
System.out.println("id="+task.getId());
System.out.println("name="+task.getName());
System.out.println("assinee="+task.getAssignee());
System.out.println("createTime ="+task.getCreateTime());
System.out.println("executionId="+task.getExecutionId());
System.out.println("##################################");
}
}
//5 查詢組任務成員列表
@Test
public void findGroupUser(){
String taskId = "3709";
List<IdentityLink> list = processEngine.getTaskService()//
.getIdentityLinksForTask(taskId);
//List<IdentityLink> list = processEngine.getRuntimeService()//
// .getIdentityLinksForProcessInstance(instanceId);
for(IdentityLink identityLink:list ){
System.out.println("userId="+identityLink.getUserId());
System.out.println("taskId="+identityLink.getTaskId());
System.out.println("piId="+identityLink.getProcessInstanceId());
System.out.println("######################");
}
}
//6 查詢組任務成員歷史列表
@Test
public void findGroupHisUser(){
String taskId = "3709";
List<HistoricIdentityLink> list = processEngine.getHistoryService()//
.getHistoricIdentityLinksForTask(taskId);
// List<HistoricIdentityLink> list = processEngine.getHistoryService()//
// .getHistoricIdentityLinksForProcessInstance(processInstanceId);
for(HistoricIdentityLink identityLink:list ){
System.out.println("userId="+identityLink.getUserId());
System.out.println("taskId="+identityLink.getTaskId());
System.out.println("piId="+identityLink.getProcessInstanceId());
System.out.println("######################");
}
}
//完成任務
@Test
public void completeTask(){
String taskId = "3709";
processEngine.getTaskService()//
.complete(taskId);//
System.out.println("完成任務");
}
/**將組任務分配給個人任務,拾取任務*/
//由1個人去完成任務
@Test
public void claim(){
//任務ID
String taskId = "5908";
//分配的辦理人
String userId = "小B";
processEngine.getTaskService()//
.claim(taskId, userId);
}
說明:
1)小A,小B,小C,小D是組任務的辦理人
2)但是這樣分配組任務的辦理人不夠靈活,因為專案開發中任務的辦理人不要放置XML檔案中。
3)act_ru_identitylink表存放任務的辦理人,包括個人任務和組任務,表示正在執行的任務
4)act_hi_identitylink表存放任務的辦理人,包括個人任務和組任務,表示歷史任務
區別在於:如果是個人任務TYPE的型別表示participant(參與者)
如果是組任務TYPE的型別表示candidate(候選者)和participant(參與者)
三、分配個人任務方式二(使用流程變數)
1:流程圖中任務節點的配置
2、測試程式碼
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**部署流程定義(從inputStream)*/
@Test
public void deploymentProcessDefinition_inputStream(){
InputStream inputStreamBpmn = this.getClass().getResourceAsStream("task.bpmn");
InputStream inputStreamPng = this.getClass().getResourceAsStream("task.png");
Deployment deployment = processEngine.getRepositoryService()//與流程定義和部署物件相關的Service
.createDeployment()//建立一個部署物件
.name("任務")//新增部署的名稱
.addInputStream("task.bpmn", inputStreamBpmn)//
.addInputStream("task.png", inputStreamPng)//
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());//
System.out.println("部署名稱:"+deployment.getName());//
}
/**啟動流程例項*/
@Test
public void startProcessInstance(){
//流程定義的key
String processDefinitionKey = "task";
/**啟動流程例項的同時,設定流程變數,使用流程變數用來指定任務的辦理人,對應task.pbmn檔案中#{userIDs}*/
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("userIDs", "大大,中中,小小");
ProcessInstance pi = processEngine.getRuntimeService()//與正在執行的流程例項和執行物件相關的Service
.startProcessInstanceByKey(processDefinitionKey,variables);//使用流程定義的key啟動流程例項,key對應helloworld.bpmn檔案中id的屬性值,使用key值啟動,預設是按照最新版本的流程定義啟動
System.out.println("流程例項ID:"+pi.getId());//流程例項ID
System.out.println("流程定義ID:"+pi.getProcessDefinitionId());//流程定義ID
}
/**查詢當前人的個人任務*/
@Test
public void findMyPersonalTask(){
String assignee = "小A";
List<Task> list = processEngine.getTaskService()//與正在執行的任務管理相關的Service
.createTaskQuery()//建立任務查詢物件
/**查詢條件(where部分)*/
.taskAssignee(assignee)//指定個人任務查詢,指定辦理人
// .taskCandidateUser(candidateUser)//組任務的辦理人查詢
/**排序*/
.orderByTaskCreateTime().asc()//使用建立時間的升序排列
/**返回結果集*/
.list();//返回列表
if(list!=null && list.size()>0){
for(Task task:list){
System.out.println("任務ID:"+task.getId());
System.out.println("任務名稱:"+task.getName());
System.out.println("任務的建立時間:"+task.getCreateTime());
System.out.println("任務的辦理人:"+task.getAssignee());
System.out.println("流程例項ID:"+task.getProcessInstanceId());
System.out.println("執行物件ID:"+task.getExecutionId());
System.out.println("流程定義ID:"+task.getProcessDefinitionId());
System.out.println("########################################################");
}
}
}
/**查詢當前人的組任務*/
@Test
public void findMyGroupTask(){
String candidateUser = "大大";
List<Task> list = processEngine.getTaskService()//與正在執行的任務管理相關的Service
.createTaskQuery()//建立任務查詢物件
/**查詢條件(where部分)*/
.taskCandidateUser(candidateUser)//組任務的辦理人查詢
/**排序*/
.orderByTaskCreateTime().asc()//使用建立時間的升序排列
/**返回結果集*/
.list();//返回列表
if(list!=null && list.size()>0){
for(Task task:list){
System.out.println("任務ID:"+task.getId());
System.out.println("任務名稱:"+task.getName());
System.out.println("任務的建立時間:"+task.getCreateTime());
System.out.println("任務的辦理人:"+task.getAssignee());
System.out.println("流程例項ID:"+task.getProcessInstanceId());
System.out.println("執行物件ID:"+task.getExecutionId());
System.out.println("流程定義ID:"+task.getProcessDefinitionId());
System.out.println("########################################################");
}
}
}
/**完成我的任務*/
@Test
public void completeMyPersonalTask(){
//任務ID
String taskId = "6905";
processEngine.getTaskService()//與正在執行的任務管理相關的Service
.complete(taskId);
System.out.println("完成任務:任務ID:"+taskId);
}
/**查詢正在執行的任務辦理人表*/
@Test
public void findRunPersonTask(){
//任務ID
String taskId = "6204";
List<IdentityLink> list = processEngine.getTaskService()//
.getIdentityLinksForTask(taskId);
if(list!=null && list.size()>0){
for(IdentityLink identityLink:list){
System.out.println(identityLink.getTaskId()+" "+identityLink.getType()+" "+identityLink.getProcessInstanceId()+" "+identityLink.getUserId());
}
}
}
/**查詢歷史任務的辦理人表*/
@Test
public void findHistoryPersonTask(){
//流程例項ID
String processInstanceId = "6201";
List<HistoricIdentityLink> list = processEngine.getHistoryService()//
.getHistoricIdentityLinksForProcessInstance(processInstanceId);
if(list!=null && list.size()>0){
for(HistoricIdentityLink identityLink:list){
System.out.println(identityLink.getTaskId()+" "+identityLink.getType()+" "+identityLink.getProcessInstanceId()+" "+identityLink.getUserId());
}
}
}
/**拾取任務,將組任務分給個人任務,指定任務的辦理人欄位*/
@Test
public void claim(){
//將組任務分配給個人任務
//任務ID
String taskId = "6905";
//分配的個人任務(可以是組任務中的成員,也可以是非組任務的成員)
String userId = "大大";
processEngine.getTaskService()//
.claim(taskId, userId);
}
/**將個人任務回退到組任務,前提,之前一定是個組任務*/
@Test
public void setAssigee(){
//任務ID
String taskId = "6204";
processEngine.getTaskService()//
.setAssignee(taskId, null);
}
/**向組任務中新增成員*/
@Test
public void addGroupUser(){
//任務ID
String taskId = "6204";
//成員辦理人
String userId = "大H";
processEngine.getTaskService()//
.addCandidateUser(taskId, userId);
}
/**從組任務中刪除成員*/
@Test
public void deleteGroupUser(){
//任務ID
String taskId = "6204";
//成員辦理人
String userId = "小B";
processEngine.getTaskService()//
.deleteCandidateUser(taskId, userId);
}
說明:
1)大大,中中,小小是組任務的辦理人
2)在開發中,可以在頁面中指定下一個組任務的辦理人,通過流程變數設定下一個任務的辦理人
四、分配個人任務方式三(使用類)
1:流程圖中任務節點的配置
此時流程圖的XML檔案,如圖:
2:TaskListenerImpl類,用來設定任務的辦理人
@SuppressWarnings("serial")
public class TaskListenerImpl implements TaskListener {
/**用來指定任務的辦理人*/
@Override
public void notify(DelegateTask delegateTask) {
//指定個人任務的辦理人,也可以指定組任務的辦理人
//個人任務:通過類去查詢資料庫,將下一個任務的辦理人查詢獲取,然後通過setAssignee()的方法指定任務的辦理人
//delegateTask.setAssignee("滅絕師太");
//組任務:
delegateTask.addCandidateUser("郭靖");
delegateTask.addCandidateUser("黃蓉");
}
}
3:測試程式碼
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**部署流程定義(從inputStream)*/
@Test
public void deploymentProcessDefinition_inputStream(){
InputStream inputStreamBpmn = this.getClass().getResourceAsStream("task.bpmn");
InputStream inputStreamPng = this.getClass().getResourceAsStream("task.png");
Deployment deployment = processEngine.getRepositoryService()//與流程定義和部署物件相關的Service
.createDeployment()//建立一個部署物件
.name("任務")//新增部署的名稱
.addInputStream("task.bpmn", inputStreamBpmn)//
.addInputStream("task.png", inputStreamPng)//
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());//
System.out.println("部署名稱:"+deployment.getName());//
}
/**啟動流程例項*/
@Test
public void startProcessInstance(){
//流程定義的key
String processDefinitionKey = "task";
ProcessInstance pi = processEngine.getRuntimeService()//與正在執行的流程例項和執行物件相關的Service
.startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key啟動流程例項,key對應helloworld.bpmn檔案中id的屬性值,使用key值啟動,預設是按照最新版本的流程定義啟動
System.out.println("流程例項ID:"+pi.getId());//流程例項ID
System.out.println("流程定義ID:"+pi.getProcessDefinitionId());//流程定義ID
}
/**查詢當前人的個人任務*/
@Test
public void findMyPersonalTask(){
String assignee = "郭靖";
List<Task> list = processEngine.getTaskService()//與正在執行的任務管理相關的Service
.createTaskQuery()//建立任務查詢物件
/**查詢條件(where部分)*/
.taskAssignee(assignee)//指定個人任務查詢,指定辦理人
// .taskCandidateUser(candidateUser)//組任務的辦理人查詢
/**排序*/
.orderByTaskCreateTime().asc()//使用建立時間的升序排列
/**返回結果集*/
.list();//返回列表
if(list!=null && list.size()>0){
for(Task task:list){
System.out.println("任務ID:"+task.getId());
System.out.println("任務名稱:"+task.getName());
System.out.println("任務的建立時間:"+task.getCreateTime());
System.out.println("任務的辦理人:"+task.getAssignee());
System.out.println("流程例項ID:"+task.getProcessInstanceId());
System.out.println("執行物件ID:"+task.getExecutionId());
System.out.println("流程定義ID:"+task.getProcessDefinitionId());
System.out.println("########################################################");
}
}
}
/**查詢當前人的組任務*/
@Test
public void findMyGroupTask(){
String candidateUser = "郭靖";
List<Task> list = processEngine.getTaskService()//與正在執行的任務管理相關的Service
.createTaskQuery()//建立任務查詢物件
/**查詢條件(where部分)*/
.taskCandidateUser(candidateUser)//組任務的辦理人查詢
/**排序*/
.orderByTaskCreateTime().asc()//使用建立時間的升序排列
/**返回結果集*/
.list();//返回列表
if(list!=null && list.size()>0){
for(Task task:list){
System.out.println("任務ID:"+task.getId());
System.out.println("任務名稱:"+task.getName());
System.out.println("任務的建立時間:"+task.getCreateTime());
System.out.println("任務的辦理人:"+task.getAssignee());
System.out.println("流程例項ID:"+task.getProcessInstanceId());
System.out.println("執行物件ID:"+task.getExecutionId());
System.out.println("流程定義ID:"+task.getProcessDefinitionId());
System.out.println("########################################################");
}
}
}
/**完成我的任務*/
@Test
public void completeMyPersonalTask(){
//任務ID
String taskId = "7204";
processEngine.getTaskService()//與正在執行的任務管理相關的Service
.complete(taskId);
System.out.println("完成任務:任務ID:"+taskId);
}
/**查詢正在執行的任務辦理人表*/
@Test
public void findRunPersonTask(){
//任務ID
String taskId = "6204";
List<IdentityLink> list = processEngine.getTaskService()//
.getIdentityLinksForTask(taskId);
if(list!=null && list.size()>0){
for(IdentityLink identityLink:list){
System.out.println(identityLink.getTaskId()+" "+identityLink.getType()+" "+identityLink.getProcessInstanceId()+" "+identityLink.getUserId());
}
}
}
/**查詢歷史任務的辦理人表*/
@Test
public void findHistoryPersonTask(){
//流程例項ID
String processInstanceId = "6201";
List<HistoricIdentityLink> list = processEngine.getHistoryService()//
.getHistoricIdentityLinksForProcessInstance(processInstanceId);
if(list!=null && list.size()>0){
for(HistoricIdentityLink identityLink:list){
System.out.println(identityLink.getTaskId()+" "+identityLink.getType()+" "+identityLink.getProcessInstanceId()+" "+identityLink.getUserId());
}
}
}
/**拾取任務,將組任務分給個人任務,指定任務的辦理人欄位*/
@Test
public void claim(){
//將組任務分配給個人任務
//任務ID
String taskId = "7204";
//分配的個人任務(可以是組任務中的成員,也可以是非組任務的成員)
String userId = "郭靖";
processEngine.getTaskService()//
.claim(taskId, userId);
}
/**將個人任務回退到組任務,前提,之前一定是個組任務*/
@Test
public void setAssigee(){
//任務ID
String taskId = "6204";
processEngine.getTaskService()//
.setAssignee(taskId, null);
}
/**向組任務中新增成員*/
@Test
public void addGroupUser(){
//任務ID
String taskId = "6204";
//成員辦理人
String userId = "大H";
processEngine.getTaskService()//
.addCandidateUser(taskId, userId);
}
/**從組任務中刪除成員*/
@Test
public void deleteGroupUser(){
//任務ID
String taskId = "6204";
//成員辦理人
String userId = "小B";
processEngine.getTaskService()//
.deleteCandidateUser(taskId, userId);
}
說明:
1)在類中使用delegateTask.addCandidateUser (userId);的方式分配組任務的辦理人,此時孫悟空和豬八戒是下一個任務的辦理人。
2)通過processEngine.getTaskService().claim (taskId, userId);將組任務分配給個人任務,也叫認領任務,即指定某個人去辦理這個任務,此時由如來去辦理任務。
注意:認領任務的時候,可以是組任務成員中的人,也可以不是組任務成員的人,此時通過Type的型別為participant來指定任務的辦理人
3)addCandidateUser()即向組任務新增成員,deleteCandidateUser()即刪除組任務的成員。
4)在開發中,可以將每一個任務的辦理人規定好,例如張三的領導是李四和王五,這樣張三提交任務,由李四或者王五去查詢組任務,可以看到對應張三的申請,李四或王五再通過認領任務(claim)的方式,由某個人去完成這個任務。
五、總結
組任務及三種分配方式:
1:在taskProcess.bpmn中直接寫 candidate-users=“小A,小B,小C,小D”
2:在taskProcess.bpmn中寫 candidate-users =“#{userIDs}”,變數的值要是String的。
使用流程變數指定辦理人
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("userIDs", "大大,小小,中中");
3,使用TaskListener介面,使用類實現該介面,在類中定義:
//新增組任務的使用者
delegateTask.addCandidateUser(userId1);
delegateTask.addCandidateUser(userId2);
組任務分配給個人任務(認領任務):
processEngine.getTaskService().claim(taskId, userId);
個人任務分配給組任務:
processEngine.getTaskService(). setAssignee(taskId, null);
向組任務新增人員:
processEngine.getTaskService().addCandidateUser(taskId, userId);
向組任務刪除人員:
processEngine.getTaskService().deleteCandidateUser(taskId, userId);
個人任務和組任務存放辦理人對應的表:
act_ru_identitylink表存放任務的辦理人,包括個人任務和組任務,表示正在執行的任務
act_hi_identitylink表存放任務的辦理人,包括個人任務和組任務,表示歷史任務
區別在於:如果是個人任務TYPE的型別表示participant(參與者)
如果是組任務TYPE的型別表示candidate(候選者)和participant(參與者)