上一章流程启动后,根据流程图,会到达用户任务userTask1上。通常实际应用中,流程使用userTask比较多。因此本章就讲讲userTask提交。
首先我们新建一个bpmn图,secondBPM.bpmn
<?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/test">
<process id="secondBPM" name="second BPM" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<userTask id="usertask1" name="User Task1" activiti:assignee="张三"></userTask>
<userTask id="usertask2" name="User Task2" activiti:assignee="李四"></userTask>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_secondBPM">
<bpmndi:BPMNPlane bpmnElement="secondBPM" id="BPMNPlane_secondBPM">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="500.0" y="30.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="466.0" y="103.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="466.0" y="181.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="500.0" y="260.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="517.0" y="65.0"></omgdi:waypoint>
<omgdi:waypoint x="518.0" y="103.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="518.0" y="158.0"></omgdi:waypoint>
<omgdi:waypoint x="518.0" y="181.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="518.0" y="236.0"></omgdi:waypoint>
<omgdi:waypoint x="517.0" y="260.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
大概是这样的图,有两个userTask任务节点:
注意bpmn文件中,userTask标签中activiti:assignee的属性,它表示该任务节点分配给哪个人处理。可以看到,目前userTask1分配给张三,userTask2分配给李四。
接着按照前面文章的方式进行部署和启动流程,查看act_ru_execution,可以看到流程目前运行到userTask1上面:
再查看act_ru_task表,可以看到当前任务分配到“张三”那里:
任务查询
在一套有流程的系统中,例如OA系统,对一般用户来讲,最常见的操作就是查看自己的待办,然后选择待办,最后进行提交操作。查看自己的待办,本质就是查询act_ru_task表下任务哪些分配给了某个用户。当然activiti不需要我们直接去查底层表,它有提供api进行查询
public void taskQuery() {
TaskService taskService = pe.getTaskService();
TaskQuery taskQuery = taskService.createTaskQuery();
List<Task> resultList = taskQuery.taskAssignee("张三").list();
for(Task task : resultList) {
System.out.println("任务ID:" + task.getId());
}
}
调用查询之后,可以看到输出分配到“张三”名下的任务有哪些。TaskQuery提供了非常多查询的接口,这里就不一一去演示了。任务查询出来之后,可以看到输出任务的ID是“2504”,下一步就是处理具体的任务。
任务提交
当我们在OA系统上提交流程的时候,系统会做很多业务数据的处理,而在底层,实际上就是对这个任务调用“complete”的API:
public void completeTask() {
TaskService taskService = pe.getTaskService();
taskService.complete("2504");
System.out.println("完成提交");
}
查看act_ru_execution表,可以看到当前流程已经执行到了userTask2:
查看 act_ru_task表,可以看到当前的任务分配给“李四”:
除了这些表之外,act_ru_identitylink、act_hi_actinst、act_hi_taskinst、act_hi_identitylink都有更新记录,可以查看。
之后用之前的代码稍作修改后,通过李四查找出任务的ID,然后再次完成提交操作。最后可以看到act_ru_XXX表里的记录已经没了,因为流程已经结束。查看act_hi_procinst表,流程结束后会更新这里流程的结束时间和总耗时:
以上的操作是activiti流程提交最简单和普遍的操作。通过前四章的入门学习,相信读者已经可以完成从初始化、到部署、到启动流程、最后提交并完成流程这一系列的操作。当然这个API是无法完成中国式流程的需求(撤回、加签、跳转)。要处理中国式流程,需要对activiti的运行有更深入的认识,才能实现这些功能。