1创建请假的流程图(画流程图的过程与jbpm一样)
图一
图二
图三
askForLeave.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="askForLeave" name="askForLeaveProcess" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="请假申请" activiti:assignee="小黄"></userTask>
<userTask id="usertask2" name="部门经理审批" activiti:assignee="陈经理"></userTask>
<userTask id="usertask3" name="总经理审批" activiti:assignee="陈总裁"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>
<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_askForLeave">
<bpmndi:BPMNPlane bpmnElement="askForLeave" id="BPMNPlane_askForLeave">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="375.0" y="40.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="375.0" y="460.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="340.0" y="120.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="340.0" y="220.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
<omgdc:Bounds height="55.0" width="105.0" x="340.0" y="340.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="392.0" y="75.0"></omgdi:waypoint>
<omgdi:waypoint x="392.0" y="120.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="392.0" y="175.0"></omgdi:waypoint>
<omgdi:waypoint x="392.0" y="220.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="392.0" y="275.0"></omgdi:waypoint>
<omgdi:waypoint x="392.0" y="340.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="392.0" y="395.0"></omgdi:waypoint>
<omgdi:waypoint x="392.0" y="460.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
bpmn文件
流程规则文件。在部署后,每次系统启动时都会被解析,把内容封装成流程定义放入项目缓存中。Activiti框架结合这个xml文件自动管理流程,流程的执行就是按照bpmn文件定义的规则执行的,
2请假流程的简单案列
步骤1:员工小黄,提交请假申请单
01:小黄部署请假申请的流程定义
02:启动流程实例,相当于小黄填写了请假申请单,但是还没有交给领导
03:查询当前人的个人任务:相当于小黄查看自己的请假申请单,查询当前人的个人任务
04:完成我的任务:相当于小黄把请假单给部门经理。这个时候小黄的个人任务就完成了,这个时候在个人任务中查不到对应的任务,因为任务已经提交给部门经理了。
public class HelloWorld {
//默认读取activiti.cfg.xml文件,且是单例模式
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**部署流程定义*/
@Test
public void deploymentProcessDefinition(){
//该方法与jbpm完全一样
// 这一步在数据库中将操作三张表:
// act_re_deployment(部署对象表):存放流程定义的显示名和部署时间,每部署一次增加一条记录
// act_re_procdef(流程定义表):存放流程定义的属性信息,部署每个新的流程定义都会在这张表中增加一条记录。
//注意:当流程定义的key相同的情况下,使用的是版本升级
// act_ge_bytearray(资源文件表):存储流程定义相关的部署信息。即流程定义文档的存放地。
//每部署一次就会增加两条记录,一条是关于bpmn规则文件的,一条是图片的
//注意:如果部署时只指定了bpmn一个文件,activiti会在部署时解析bpmn文件内容自动生成流程图,以二进制形式存储在数据库中。
InputStream inputStreamBpmn = this.getClass().getResourceAsStream("askForLeave.bpmn");
InputStream inputStreamPng = this.getClass().getResourceAsStream("askForLeave.png");
Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
.createDeployment()//创建一个部署对象
.name("请假流程")//添加部署的名称
.addInputStream("askForLeave.bpmn", inputStreamBpmn)//从classpath的资源中加载,一次只能加载一个文件
.addInputStream("askForLeave.png", inputStreamPng)//从classpath的资源中加载,一次只能加载一个文件
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署名称:"+deployment.getName());
System.out.println("部署时间:"+deployment.getDeploymentTime());
// 输出:
// 部署ID:201
// 部署名称:请假流程
// 部署时间:Tue Sep 05 16:04:17 CST 2017
}
/**启动流程实例*/
@Test
public void startProcessInstance(){
//流程定义的key
String processDefinitionKey = "askForLeave";//key对应askForLeave.bpmn文件中id的属性值
ProcessInstance pi = processEngine.getRuntimeService()//与正在执行的流程实例和执行对象相关的Service
.startProcessInstanceByKey(processDefinitionKey);//使用流程定义的key启动流程实例,使用key值启动,默认是按照最新版本的流程定义启动
System.out.println("流程实例ID:"+pi.getId());//流程实例ID
System.out.println("流程定义ID:"+pi.getProcessDefinitionId());//流程定义ID
// 输出:
// 流程实例ID:301
// 流程定义ID:askForLeave:2:204
}
/**查询当前人的个人任务*/
@Test
public void findMyPersonalTask(){
String assignee = "小黄";
List<Task> list = processEngine.getTaskService()//与正在执行的任务管理相关的Service
.createTaskQuery()//创建任务查询对象
.taskAssignee(assignee)//指定个人任务查询,指定办理人
.list();
if(list!=null && list.size()>0){
for(Task task:list){
System.out.println("--------"+task.getAssignee()+"任务:"+task.getName()+"-----------------");
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());
}
}
// 输出:
// --------小黄任务:请假申请-----------------
// 任务ID:304
// 任务名称:请假申请
// 任务的创建时间:Tue Sep 05 16:04:33 CST 2017
// 任务的办理人:小黄
// 流程实例ID:301
// 执行对象ID:301
// 流程定义ID:askForLeave:2:204
}
/**完成我的任务*/
@Test
public void completeMyPersonalTask(){
//任务ID
String taskId = "304";
processEngine.getTaskService()//与正在执行的任务管理相关的Service
.complete(taskId);
System.out.println("完成任务:任务ID:"+taskId);
// 输出:
// 完成任务:任务ID:304
}
}
步骤2:陈经理查看小黄提交给陈经理的任务,并同意,把该任务给陈总裁
01:查看自己的任务:看到小黄的请假单(需要陈经理审批)
02:完成我的任务:同意小黄的请假申请,并把该请假单传递给陈总裁
/**查询当前人的个人任务*/
@Test
public void findMyPersonalTask(){
String assignee = "陈经理";
List<Task> list = processEngine.getTaskService()//与正在执行的任务管理相关的Service
.createTaskQuery()//创建任务查询对象
.taskAssignee(assignee)//指定个人任务查询,指定办理人
.list();
if(list!=null && list.size()>0){
for(Task task:list){
System.out.println("--------"+task.getAssignee()+"任务:"+task.getName()+"-----------------");
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());
}
}
// 输出:
// --------陈经理任务:部门经理审批-----------------
// 任务ID:402
// 任务名称:部门经理审批
// 任务的创建时间:Tue Sep 05 16:06:38 CST 2017
// 任务的办理人:陈经理
// 流程实例ID:301
// 执行对象ID:301
// 流程定义ID:askForLeave:2:204
}
/**完成我的任务*/
@Test
public void completeMyPersonalTask(){
//任务ID
String taskId = "402";
processEngine.getTaskService()//与正在执行的任务管理相关的Service
.complete(taskId);
System.out.println("完成任务:任务ID:"+taskId);
// 输出:
// 完成任务:任务ID:402
}
步骤3:陈总裁查看自己的任务,看到陈经理传递过来的请假申请单,陈总裁同意了
01:查看个人任务:陈总裁查看自己的任务,看到陈经理传递过来的请假申请单
02:完成我的任务:同意陈经理传递过来的请假申请单
/**查询当前人的个人任务*/
@Test
public void findMyPersonalTask(){
String assignee = "陈总裁";
List<Task> list = processEngine.getTaskService()//与正在执行的任务管理相关的Service
.createTaskQuery()//创建任务查询对象
.taskAssignee(assignee)//指定个人任务查询,指定办理人
.list();
if(list!=null && list.size()>0){
for(Task task:list){
System.out.println("--------"+task.getAssignee()+"任务:"+task.getName()+"-----------------");
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());
}
}
// 输出:
// --------陈总裁任务:总经理审批-----------------
// 任务ID:502
// 任务名称:总经理审批
// 任务的创建时间:Tue Sep 05 16:17:54 CST 2017
// 任务的办理人:陈总裁
// 流程实例ID:301
// 执行对象ID:301
// 流程定义ID:askForLeave:2:204
}
/**完成我的任务*/
@Test
public void completeMyPersonalTask(){
//任务ID
String taskId = "502";
processEngine.getTaskService()//与正在执行的任务管理相关的Service
.complete(taskId);
System.out.println("完成任务:任务ID:"+taskId);
// 输出:
// 完成任务:任务ID:502
}