目录
一、前言
上文SpringBoot已经与Activiti做了基本整合,所有流程需要的数据表也都已生成,下面就先来实现一个最简单的请假流程来感受下工作流的大概步骤。
二、实现请假流程
1、制作流程图
如果只是自己玩的话可以使用Activiti6自带的Activiti-app绘制流程图,这里就直接使用系列一绘制的请假流程图:
2、导出xml流程文件
导出步骤也在系列一中详细介绍过,这里直接贴请假流程的详细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="vocation" name="请假流程" isExecutable="true">
<startEvent id="startEvent1"></startEvent>
<userTask id="sid-EA9C8B20-4BA6-47D4-86D3-B21EBF0BD990" name="直属经理审批" activiti:assignee="test">
<extensionElements>
<modeler:activiti-idm-assignee xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-assignee>
<modeler:assignee-info-email xmlns:modeler="http://activiti.com/modeler"><![CDATA[test@qq.com]]></modeler:assignee-info-email>
<modeler:assignee-info-firstname xmlns:modeler="http://activiti.com/modeler"><![CDATA[test]]></modeler:assignee-info-firstname>
<modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
</extensionElements>
</userTask>
<userTask id="sid-926AAE81-063A-4D88-B509-362C3D96481E" name="总经理审批" activiti:assignee="test">
<extensionElements>
<modeler:activiti-idm-assignee xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-assignee>
<modeler:assignee-info-email xmlns:modeler="http://activiti.com/modeler"><![CDATA[test@qq.com]]></modeler:assignee-info-email>
<modeler:assignee-info-firstname xmlns:modeler="http://activiti.com/modeler"><![CDATA[test]]></modeler:assignee-info-firstname>
<modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
</extensionElements>
</userTask>
<endEvent id="sid-24F3BD99-87CC-4F2F-940A-062AC90838DD"></endEvent>
<sequenceFlow id="sid-ACE554C1-6250-44D2-95CC-49200E2E943F" sourceRef="startEvent1" targetRef="sid-EA9C8B20-4BA6-47D4-86D3-B21EBF0BD990"></sequenceFlow>
<sequenceFlow id="sid-8C609B42-C142-4C96-93A3-484818E67A8A" sourceRef="sid-EA9C8B20-4BA6-47D4-86D3-B21EBF0BD990" targetRef="sid-926AAE81-063A-4D88-B509-362C3D96481E"></sequenceFlow>
<sequenceFlow id="sid-8E6039BD-0943-4D40-A6DE-3BD09A5A3008" sourceRef="sid-926AAE81-063A-4D88-B509-362C3D96481E" targetRef="sid-24F3BD99-87CC-4F2F-940A-062AC90838DD"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_vocation">
<bpmndi:BPMNPlane bpmnElement="vocation" id="BPMNPlane_vocation">
<bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
<omgdc:Bounds height="30.0" width="30.0" x="100.0" y="155.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-EA9C8B20-4BA6-47D4-86D3-B21EBF0BD990" id="BPMNShape_sid-EA9C8B20-4BA6-47D4-86D3-B21EBF0BD990">
<omgdc:Bounds height="80.0" width="100.0" x="199.0" y="130.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-926AAE81-063A-4D88-B509-362C3D96481E" id="BPMNShape_sid-926AAE81-063A-4D88-B509-362C3D96481E">
<omgdc:Bounds height="80.0" width="100.0" x="420.0" y="130.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-24F3BD99-87CC-4F2F-940A-062AC90838DD" id="BPMNShape_sid-24F3BD99-87CC-4F2F-940A-062AC90838DD">
<omgdc:Bounds height="28.0" width="28.0" x="645.0" y="156.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sid-ACE554C1-6250-44D2-95CC-49200E2E943F" id="BPMNEdge_sid-ACE554C1-6250-44D2-95CC-49200E2E943F">
<omgdi:waypoint x="130.0" y="170.0"></omgdi:waypoint>
<omgdi:waypoint x="199.0" y="170.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-8E6039BD-0943-4D40-A6DE-3BD09A5A3008" id="BPMNEdge_sid-8E6039BD-0943-4D40-A6DE-3BD09A5A3008">
<omgdi:waypoint x="520.0" y="170.0"></omgdi:waypoint>
<omgdi:waypoint x="645.0" y="170.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-8C609B42-C142-4C96-93A3-484818E67A8A" id="BPMNEdge_sid-8C609B42-C142-4C96-93A3-484818E67A8A">
<omgdi:waypoint x="299.0" y="170.0"></omgdi:waypoint>
<omgdi:waypoint x="420.0" y="170.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
3、流程部署及运行
首先将第二步获得的xml文件上传到系列二的项目中,放于resource目录下,如下:
然后新建一个demo类开始部署并运行,这里需要引入SpringBoo的Test依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
测试类代码如下:
@SpringBootTest
@RunWith(SpringRunner.class)
public class VocationDemo {
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Test
public void demoTest() {
// 1、发布流程
Deployment deployment = repositoryService.createDeployment().name("请假小流程").addClasspathResource("processes/vocationDemo.bpmn20.xml").deploy();
// 2、启动一个流程实例,由于两个环节审批的人都是写死的test,所以这边在启动流程的时候未透传下一环节处理人
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("vocation");
// 3、查询所有任务
List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).list();
// 4、提交到总经理审批即完成任务,同样不需要传递变量
Task task = tasks.get(0);
taskService.complete(task.getId());
}
}
4、流程部署时数据库表变化
这是一个最简单的纯人工节点串行的流程,上面的代码也并没有完全走完整个流程,只完成了直属经理审批环节的任务,下面我们来看下每个步骤部分数据表发生的变化:
1):发布流程时Activiti首先会将xml资源文件部署到ACT_GE_BYTEARRAY资源表中
然后将流程的部署信息发布到ACT_RE_DEPLOYMENT表中
将流程具体的信息发布到ACT_RE_PROCDEF表中
2):启动流程后,ACT_RU_EXECUTION表会生成两条记录,流程启动和用户任务,可以看到PROC_INST_ID_是一样的,说明是同一个流程实例
同时各任务表即运行时任务表ACT_RU_TASK和历史任务表ACT_HI_TASKINST中数据也同时增加
ACT_RU_TASK表如下,由于当前流程流转到总经理审批,因此运行任务则在当下
ACT_HI_TASKINST表如下,保存了上一环节的已完成的任务