先利用eclipse安装好的流程图绘制插件绘制一个审批流程
分别设置assignee(分配到任务的人) 为张三,李四,王五
这是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: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="myProcess" name="My process" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<userTask id="usertask1" name="提交申请" activiti:assignee="张三"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<userTask id="usertask2" name="审批【部门经理】" activiti:assignee="李四"></userTask>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
<userTask id="usertask3" name="审批【总经理】" activiti:assignee="王五"></userTask>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>
</process>
开发步骤
一、部署流程定义
ProcessDefinition 流程定义
解析.bpmn后得到的流程定义规则的信息,工作流系统就是按照流程定义的规则执行的
/*
* 部署发布流程
*/
@Test
public void deploy(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取流程仓库服务,定义和部署流程有关
RepositoryService repositoryService = processEngine.getRepositoryService();
//创建流程部署发布对象
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
deploymentBuilder.name("hello流程");
//添加流程
deploymentBuilder.addClasspathResource("diagrams/MyProcess.bpmn");
deploymentBuilder.addClasspathResource("diagrams/MyProcess.png");
//发布
Deployment deployment =deploymentBuilder.deploy();
System.out.println(deployment.getName());
}
数据库仓库相关表产生数据
(使用ZIP压缩文件部署)
将
压缩成zip格式的文件,使用zip的输入流用作部署流程定义
-
流程定义条件查询
/*
* 查询流程定义
*/
@Test
public void queryProcessDefinition(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取流程仓库服务,定义和部署流程有关
RepositoryService repositoryService = processEngine.getRepositoryService();
//部署查询对象
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//查询条件
// processDefinitionQuery.deploymentId(id); //根据ID查询
// processDefinitionQuery.deploymentName(name); //根据名称查询
// processDefinitionQuery.deploymentNameLike(name);
processDefinitionQuery.processDefinitionKey("myProcess");
List<ProcessDefinition> list = processDefinitionQuery.list();
long count = processDefinitionQuery.count(); //查询数量
// Deployment deployment =deploymentQuery.singleResult();
System.out.println("流程定义数量为"+count);
for (ProcessDefinition processDefinition : list) {
System.out.println("流程定义ID:"+processDefinition.getId());
System.out.println("流程定义name:"+processDefinition.getName());
System.out.println("流程定义key:"+processDefinition.getKey());
System.out.println("流程定义version:"+processDefinition.getVersion());
System.out.println("流程定义部署ID:"+processDefinition.getDeploymentId());
System.out.println("流程定义resource_name:"+processDefinition.getResourceName());
}
}
-
查询最新版本的流程定义
/*
* 查询最新版本流程定义
*/
@Test
public void queryLastProcessDefinition(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取流程仓库服务,定义和部署流程有关
RepositoryService repositoryService = processEngine.getRepositoryService();
//部署查询对象
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//查询条件 通过key 升序排列查询 版本最大的在最后面
List<ProcessDefinition> list = processDefinitionQuery
.processDefinitionKey("myProcess")
.orderByProcessDefinitionVersion()
.asc()
.list();
//筛选出最大版本号的数据 key相同 map后加入的会覆盖前面的值
Map<String,ProcessDefinition> map= new LinkedHashMap<>();
for (ProcessDefinition processDefinition : list) {
map.put(processDefinition.getKey(),processDefinition);
}
ProcessDefinition processDefinition = map.get("myProcess");
System.out.println("流程定义ID:"+processDefinition.getId());
System.out.println("流程定义name:"+processDefinition.getName());
System.out.println("流程定义key:"+processDefinition.getKey());
System.out.println("流程定义version:"+processDefinition.getVersion());
System.out.println("流程定义部署ID:"+processDefinition.getDeploymentId());
System.out.println("流程定义resource_name:"+processDefinition.getResourceName());
}
-
删除流程定义
@Test
public void delDeployment(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取流程仓库服务,定义和部署流程有关
RepositoryService repositoryService = processEngine.getRepositoryService();
/*非级联删除,只能删除没有启动的流程。如果流程已经启动则会删除失败,并且抛出异常*/
// repositoryService.deleteDeployment("1");
/*级联删除,不管有没有启动都会删除和该流程相关的数据*/
repositoryService.deleteDeployment("1",true);
}
如果该流程定义下没有正在运行的流程,则可以用普通删除。如果是有关联的信息,用级联删除。项目开发中使用级联删除的情况比较多,删除操作一般只开放给超级管理员使用。
-
查看流程附件,查看流程图
@Test
public void viewImg(){
String deploymentID = "10001";
//获取流程引擎对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//根据流程引擎获取仓库服务对象
RepositoryService repositoryService = processEngine.getRepositoryService();
//通过部署ID查询资源集合
List<String> resourceNames = repositoryService.getDeploymentResourceNames(deploymentID);
String imgName=null;
for (String name : resourceNames) {
if(name.indexOf("png")!=-1){
imgName=name;
}
}
if(imgName!=null){
//获取资源输入流
InputStream in = repositoryService.getResourceAsStream(deploymentID, imgName);
File file = new File("E://img/"+imgName);
try {
FileUtils.copyInputStreamToFile(in, file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
其中resourceNames为act_ge_bytearray表中NAME_列的值
使用repositoryService的getDeploymentResourceNames方法可以获取指定部署下得所有文件的名称
使用repositoryService的getResourceAsStream方法传入部署ID和资源图片名称可以获取部署下指定名称文件的输入流
二、启动流程
@Test
public void startProcess(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//通过流程引擎获取流程执行服务类
RuntimeService runtimeService = processEngine.getRuntimeService();
//使用流程定义的key启动实例,key是流程bpmn文件中定义的流程ID,默认最新版本
ProcessInstance instance = runtimeService.startProcessInstanceByKey("myProcess");
System.out.println("流程实例ID:"+instance.getId()+";流程定义ID:"+instance.getProcessDefinitionId());
}
数据库运行时相关表产生数据 运行启动几次就产生几个实例
-
查询流程状态(判断流程正在执行,还是结束)
/*
* 查询流程状态(判断流程正在执行,还是结束)
*/
@Test
public void queryProcessStatus(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//通过流程引擎获取流程执行服务类
RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
ProcessInstance processInstance=processInstanceQuery
.processInstanceId("15002")
.singleResult();
if(processInstance!=null){
System.out.println("流程没有执行完毕");
}else{
System.out.println("流程执行完毕");
}
}
三、查询当前人的个人任务
@Test
public void queryCurrentUserTask(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//流程引擎获取流程任务服务类
TaskService taskService = processEngine.getTaskService();
//创建任务查询对象
TaskQuery taskQuery = taskService.createTaskQuery();
//指定任务办理人
taskQuery.taskAssignee("张三");
List<Task> tasks = taskQuery.list();
for (Task task : tasks) {
System.out.println("任务ID:"+task.getId());
System.out.println("任务执行人:"+task.getAssignee());
System.out.println("任务名称:"+task.getName());
System.out.println("任务创建时间:"+task.getCreateTime());
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("执行对象ID:"+task.getExecutionId());
System.out.println("流程定义ID:"+task.getProcessDefinitionId());
}
}
四、完成任务
张三完成任务
@Test
public void completeTask(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//流程引擎获取流程任务服务类
TaskService taskService = processEngine.getTaskService();
//完成任务 任务ID是12504
taskService.complete("12504");
System.out.println("完成任务 任务ID是12504");
}
张三选择任务完成以后 流程继续执行 到达部门经理李四
此时再次调用之前查询张三任务的方法 发现查询不到任务 调用李四查询任务方法得到以下结果
继续执行完成任务操作
查询王五的任务,并完成
此时数据库任务表中该任务消失
此时历史表中