Activiti 组任务
Activiti 组任务
在流程定义中任务结点的 assignee 固定设置任务负责人,即在流程定义时将参与者固定设置在.bpmn 文件中,如果临时任务负责人变更则需要修改流程定义,系统可扩展性差
针对这种情况可以给任务设置多个候选人,可以从候选人中选择参与者来完成任务
在流程图中任务节点的配置中设置 candidate-users(候选人),多个候选人之间用逗号分开
流程定义文件 evection-group.bpmn20.xml
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
<process id="evection-group" name="evection-group" isExecutable="true">
<userTask id="sid-d5588667-efce-4d63-ba3f-bbae814c57dd" name="申请出差" activiti:assignee="zhangsan"/>
<userTask id="sid-0a45a736-a70d-4905-984c-ff8f4f39e39f" name="经理审批" activiti:candidateUsers="wuwang,lisi"/>
<userTask id="sid-9e862bd2-b604-4ad0-b27b-53cd0c296257" name="总经理审批"/>
<userTask id="sid-78032273-7e32-4107-97d3-72245e266ed3" name="财务审批"/>
<endEvent id="sid-3d1c7515-08c4-45e1-aedd-115e85d89a2f" name="出差申请流程结束"/>
<sequenceFlow id="sid-eb631295-3baa-4051-a17e-56830feeb8da" sourceRef="sid-d5588667-efce-4d63-ba3f-bbae814c57dd" targetRef="sid-0a45a736-a70d-4905-984c-ff8f4f39e39f"/>
<sequenceFlow id="sid-3ae6a5b1-f980-4ce0-b228-6f02dab203b0" sourceRef="sid-0a45a736-a70d-4905-984c-ff8f4f39e39f" targetRef="sid-9e862bd2-b604-4ad0-b27b-53cd0c296257"/>
<sequenceFlow id="sid-00e3bdff-cf7a-4ff7-a2c2-8f806fafb44b" sourceRef="sid-9e862bd2-b604-4ad0-b27b-53cd0c296257" targetRef="sid-78032273-7e32-4107-97d3-72245e266ed3"/>
<sequenceFlow id="sid-3bf87c83-3630-4aab-a182-abd91814d545" sourceRef="sid-78032273-7e32-4107-97d3-72245e266ed3" targetRef="sid-3d1c7515-08c4-45e1-aedd-115e85d89a2f"/>
<startEvent id="sid-c5cd9561-a619-41b5-890c-bad9ef4d756c" name="出差申请流程开始"/>
<sequenceFlow id="sid-d63e59cf-e855-4d50-ab22-57eebd2530bf" sourceRef="sid-c5cd9561-a619-41b5-890c-bad9ef4d756c" targetRef="sid-d5588667-efce-4d63-ba3f-bbae814c57dd"/>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_evection-group">
<bpmndi:BPMNPlane bpmnElement="evection-group" id="BPMNPlane_evection-group">
<bpmndi:BPMNShape id="shape-93c48233-401d-4e34-a3f1-c1f7626dad4c" bpmnElement="sid-d5588667-efce-4d63-ba3f-bbae814c57dd">
<omgdc:Bounds x="-188.7126" y="-150.33601" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-97a42e11-9ac5-4391-bee9-eeee71d1dd37" bpmnElement="sid-0a45a736-a70d-4905-984c-ff8f4f39e39f">
<omgdc:Bounds x="17.625605" y="-134.78401" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-857fa9fd-05b2-45db-b1bb-e38b1038b80c" bpmnElement="sid-9e862bd2-b604-4ad0-b27b-53cd0c296257">
<omgdc:Bounds x="17.62561" y="13.478401" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-7ffa7ab8-af50-4591-a688-2314e275fef3" bpmnElement="sid-78032273-7e32-4107-97d3-72245e266ed3">
<omgdc:Bounds x="204.24963" y="13.478401" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-e63d0ace-cb04-4162-a86e-8481c740f7da" bpmnElement="sid-3d1c7515-08c4-45e1-aedd-115e85d89a2f">
<omgdc:Bounds x="239.24963" y="166.92485" width="30.0" height="30.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-7da3539b-4460-4d85-84df-b1029361baec" bpmnElement="sid-eb631295-3baa-4051-a17e-56830feeb8da">
<omgdi:waypoint x="-88.71261" y="-110.33602"/>
<omgdi:waypoint x="17.625607" y="-114.78401"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-c18d191f-6289-4705-9db5-0edb5bb39617" bpmnElement="sid-3ae6a5b1-f980-4ce0-b228-6f02dab203b0">
<omgdi:waypoint x="67.6256" y="-54.78401"/>
<omgdi:waypoint x="67.62561" y="13.478401"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-62623800-6848-4f80-be5d-010c0c7e3ce0" bpmnElement="sid-00e3bdff-cf7a-4ff7-a2c2-8f806fafb44b">
<omgdi:waypoint x="117.625595" y="53.478394"/>
<omgdi:waypoint x="204.24963" y="53.47841"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-f67f4ac2-8eef-498b-8179-0c8866c6c02d" bpmnElement="sid-3bf87c83-3630-4aab-a182-abd91814d545">
<omgdi:waypoint x="254.24963" y="93.4784"/>
<omgdi:waypoint x="254.24963" y="166.92485"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="shape-6cdd0991-6953-4f89-ada4-e9c81ab7a484" bpmnElement="sid-c5cd9561-a619-41b5-890c-bad9ef4d756c">
<omgdc:Bounds x="-340.8253" y="-125.33601" width="30.0" height="30.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-a01ce54f-ca60-47d5-ab8a-2292e747274a" bpmnElement="sid-d63e59cf-e855-4d50-ab22-57eebd2530bf">
<omgdi:waypoint x="-310.8253" y="-110.33601"/>
<omgdi:waypoint x="-188.7126" y="-110.33601"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
可以看到部门经理的审核人已经设置为 lisi,wangwu 这样的一组候选人,启动流程后候选人相关信息记录在 act_ru_identitylink 表中
流程图如下:
查询组任务
根据候选人查询当前的待办任务,候选人不能立即完成任务
/**
* 查询组任务
*/
@Test
public void findGroupTaskList() {
// 流程定义key
String processDefinitionKey = "evection-group";
// 任务候选人
String candidateUser = "lisi";
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
// 根据任务候选人查询组任务
List<Task> list = taskService.createTaskQuery()
.processDefinitionKey(processDefinitionKey)
.taskCandidateUser(candidateUser)
.list();
for (Task task : list) {
System.out.println("----------------------------");
System.out.println("流程实例id:" + task.getProcessInstanceId());
System.out.println("任务id:" + task.getId());
System.out.println("任务负责人:" + task.getAssignee());
System.out.println("任务名称:" + task.getName());
}
}
拾取任务
将候选人的组任务通过拾取任务变成个人任务,原来候选人就变成了该任务的负责人,然后就可以完成(处理)任务
/**
* 拾取组任务
*/
@Test
public void claimTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
// 要拾取的任务id,对应act_ru_task表ID字段
String taskId = "87502";
// 任务候选人
String user = "lisi";
// 根据任务id和任务候选人查询任务(即使用户不是候选人也能拾取任务所以建议拾取时根据任务候选人查询任务校验是否有资格)
Task task = taskService.createTaskQuery()
.taskId(taskId)
.taskCandidateUser(user)
.singleResult();
if(!ObjectUtils.isEmpty(task)){
// 拾取任务
taskService.claim(taskId, user);
System.out.println("任务拾取成功");
}
}
归还组任务
如果个人不想办理该组任务,可以归还组任务,归还后该用户不再是该任务的负责人
/**
* 归还组任务,由个人任务变为组任务,还可以进行任务交接
*/
@Test
public void setAssigneeToGroupTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
String taskId = "87502";
// 任务负责人
String user = "lisi";
// 根据任务负责人和任务id查询任务
Task task = taskService
.createTaskQuery()
.taskId(taskId)
.taskAssignee(user)
.singleResult();
if (!ObjectUtils.isEmpty(task)) {
// 如果设置为null,归还组任务,该任务没有负责人
taskService.setAssignee(taskId, null);
}
}
任务交接
任务负责人将任务交给其它候选人办理该任务,类似拾取任务
/**
* 任务交接
*/
@Test
public void setAssigneeToCandidateUser() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
// 任务id
String taskId = "87502";
// 任务负责人
String user = "lisi";
// 任务交接人
String candidateuser = "经理";
// 根据任务负责人和任务id查询任务
Task task = taskService
.createTaskQuery()
.taskId(taskId)
.taskAssignee(user)
.singleResult();
if (!ObjectUtils.isEmpty(task)) {
taskService.setAssignee(taskId, candidateuser);
}
}
记得快乐