前两天做了一个SpringBoot整合Activiti的完整示例,功能包括:退回/通过(节点条件)、指定办理人、生成流程图、高亮显示已办节点、查询任务列表(办理人)等,下面先简单记录(含完整代码),十六上班后再详细补充。

1、画流程图:

高亮生成的流程图(流程已至办理):

这个流程图比较简单,这里不介绍如何画的了(记得让文件名称与id相同),下面有最终的流程图源码。

2、设置业户提交、资料不全、已签发的事件触发代码:

点击选择事件节点,下方properties里选择如下图:

找不到properties的话 要选择Activiti模式就可以:

#{activityDemoServiceImpl.updateBizStatus(execution,"tj")} 表示将使用activityDemoServiceImpl服务的updateBizStatus方法,里面有两个参数,execution是当前流程节点对象,可获取流程信息及业务key等,"tj"字符串参数。(这里设置的服务名是小写开头,实际服务名是大写开头,否则找不到——不知道是不是因为我用的5.22)

3、指定受理/审批 办理人员:

也是选中,然后如下图操作:

${activityDemoServiceImpl.findUsersForSL(execution)}跟上面一样,不过注意,事件监听是以#开头,这里是以$符号。

4、增加2、3设置的服务方法(ActivityDemoServiceImpl)

SpringBoot的好处是默认会配置和注入很多服务,所以我们使用起来非常方便,流程图不需要单独部署,直接到服务根据流程名称或id就可以直接获取到想要的内容。

直接上代码了:

package com.example.service.impl;import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.annotation.Resource;
import javax.imageio.ImageIO;import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class ActivityDemoServiceImpl { @Autowired  private RuntimeService runtimeService;  @Autowired  private TaskService taskService;  @Autowired  private HistoryService historyService;  @Autowired  private RepositoryService repositoryService;  @Autowired  private ProcessEngineConfigurationImpl processEngineConfiguration;  /*** 启动流程* @param bizId 业务id*/public void startProcesses(String bizId) { ProcessInstance pi = runtimeService.startProcessInstanceByKey("demo5", bizId);//流程图id,业务表idSystem.out.println("流程启动成功,流程id:"+pi.getId());}  /*** * <p>描述: 根据用户id查询待办任务列表</p>  * @author 范相如  * @date 2018年2月25日*/public List<Task> findTasksByUserId(String userId) {List<Task> resultTask = taskService.createTaskQuery().processDefinitionKey("demo5").taskCandidateOrAssigned(userId).list();return resultTask;}/*** * <p>描述:任务审批   (通过/拒接) </p>  * @author 范相如  * @date 2018年2月25日  * @param taskId 任务id* @param userId 用户id* @param result false OR true*/public void completeTask(String taskId,String userId,String result) {//获取流程实例taskService.claim(taskId, userId);Map<String,Object> vars = new HashMap<String,Object>();vars.put("sign", "true");taskService.complete(taskId, vars);}/*** 更改业务流程状态#{ActivityDemoServiceImpl.updateBizStatus(execution,"tj")}* @param execution* @param status*/public void updateBizStatus(DelegateExecution execution,String status) {String bizId = execution.getProcessBusinessKey();//根据业务id自行处理业务表System.out.println("业务表["+bizId+"]状态更改成功,状态更改为:"+status);}//流程节点权限用户列表${ActivityDemoServiceImpl.findUsers(execution,sign)}public List<String> findUsersForSL(DelegateExecution execution){return Arrays.asList("sly1","sly2");}//流程节点权限用户列表${ActivityDemoServiceImpl.findUsers(execution,sign)}public List<String> findUsersForSP(DelegateExecution execution){return Arrays.asList("spy1","uspy2");}/*** * <p>描述:  生成流程图* 首先启动流程,获取processInstanceId,替换即可生成</p>  * @author 范相如  * @date 2018年2月25日  * @param processInstanceId* @throws Exception*/public void queryProImg(String processInstanceId) throws Exception {//获取历史流程实例  HistoricProcessInstance processInstance =  historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();  //根据流程定义获取输入流InputStream is = repositoryService.getProcessDiagram(processInstance.getProcessDefinitionId());BufferedImage bi = ImageIO.read(is);File file = new File("demo2.png");if(!file.exists()) file.createNewFile();FileOutputStream fos = new FileOutputStream(file);ImageIO.write(bi, "png", fos);fos.close();is.close();System.out.println("图片生成成功");List<Task> tasks = taskService.createTaskQuery().taskCandidateUser("userId").list();for(Task t : tasks) {System.out.println(t.getName());}}/*** 流程图高亮显示* 首先启动流程,获取processInstanceId,替换即可生成* @throws Exception*/public void queryProHighLighted(String processInstanceId) throws Exception {//获取历史流程实例  HistoricProcessInstance processInstance =  historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();  //获取流程图  BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());  ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();  ProcessDefinitionEntity definitionEntity = (ProcessDefinitionEntity)repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId());  List<HistoricActivityInstance> highLightedActivitList =  historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();  //高亮环节id集合  List<String> highLightedActivitis = new ArrayList<String>();  //高亮线路id集合  List<String> highLightedFlows = getHighLightedFlows(definitionEntity,highLightedActivitList);  for(HistoricActivityInstance tempActivity : highLightedActivitList){  String activityId = tempActivity.getActivityId();  highLightedActivitis.add(activityId);  }  //配置字体InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivitis, highLightedFlows,"宋体","微软雅黑","黑体",null,2.0);BufferedImage bi = ImageIO.read(imageStream);File file = new File("demo2.png");if(!file.exists()) file.createNewFile();FileOutputStream fos = new FileOutputStream(file);ImageIO.write(bi, "png", fos);fos.close();imageStream.close();System.out.println("图片生成成功");}  /**  * 获取需要高亮的线  * @param processDefinitionEntity  * @param historicActivityInstances  * @return  */  private List<String> getHighLightedFlows(  ProcessDefinitionEntity processDefinitionEntity,  List<HistoricActivityInstance> historicActivityInstances) {  List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId  for (int i = 0; i < historicActivityInstances.size() - 1; i++) {// 对历史流程节点进行遍历  ActivityImpl activityImpl = processDefinitionEntity  .findActivity(historicActivityInstances.get(i)  .getActivityId());// 得到节点定义的详细信息  List<ActivityImpl> sameStartTimeNodes = new ArrayList<ActivityImpl>();// 用以保存后需开始时间相同的节点  ActivityImpl sameActivityImpl1 = processDefinitionEntity  .findActivity(historicActivityInstances.get(i + 1)  .getActivityId());  // 将后面第一个节点放在时间相同节点的集合里  sameStartTimeNodes.add(sameActivityImpl1);  for (int j = i + 1; j < historicActivityInstances.size() - 1; j++) {  HistoricActivityInstance activityImpl1 = historicActivityInstances  .get(j);// 后续第一个节点  HistoricActivityInstance activityImpl2 = historicActivityInstances  .get(j + 1);// 后续第二个节点  if (activityImpl1.getStartTime().equals(  activityImpl2.getStartTime())) {  // 如果第一个节点和第二个节点开始时间相同保存  ActivityImpl sameActivityImpl2 = processDefinitionEntity  .findActivity(activityImpl2.getActivityId());  sameStartTimeNodes.add(sameActivityImpl2);  } else {  // 有不相同跳出循环  break;  }  }  List<PvmTransition> pvmTransitions = activityImpl  .getOutgoingTransitions();// 取出节点的所有出去的线  for (PvmTransition pvmTransition : pvmTransitions) {  // 对所有的线进行遍历  ActivityImpl pvmActivityImpl = (ActivityImpl) pvmTransition  .getDestination();  // 如果取出的线的目标节点存在时间相同的节点里,保存该线的id,进行高亮显示  if (sameStartTimeNodes.contains(pvmActivityImpl)) {  highFlows.add(pvmTransition.getId());  }  }  }  return highFlows;
}
} 

5、测试:(ActivitiDemoTest)

package com.example.test;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;import javax.annotation.Resource;import org.activiti.engine.HistoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricDetail;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;import com.example.Application;
import com.example.entity.Person;
import com.example.service.impl.ActivityDemoServiceImpl;//这是JUnit的注解,通过这个注解让SpringJUnit4ClassRunner这个类提供Spring测试上下文。
@RunWith(SpringJUnit4ClassRunner.class)
//这是Spring Boot注解,为了进行集成测试,需要通过这个注解加载和配置Spring应用上下
@SpringBootTest(classes = Application.class)
@WebAppConfiguration
public class ActivitiDemoTest {@Resourceprivate ActivityDemoServiceImpl activityDemoServiceImpl;@Autowired  private TaskService taskService;  @Autowired  private HistoryService historyService;  //启动流程---215001@Testpublic void startPro() {activityDemoServiceImpl.startProcesses("123456");}//获取受理员任务列表@Testpublic void findTasksForSL() {List<Task> lists = activityDemoServiceImpl.findTasksByUserId("sly1");System.out.println("任务列表:"+lists);//任务列表:[Task[id=210028, name=受理], Task[id=215005, name=受理]]}//受理员受理数据@Testpublic void completeTasksForSL() {activityDemoServiceImpl.completeTask("210028", "sly1", "true");//受理后,任务列表数据减少}//获取审批员任务列表@Testpublic void findTasksForSP() {List<Task> lists = activityDemoServiceImpl.findTasksByUserId("spy1");System.out.println("任务列表:"+lists);//任务列表:[Task[id=220004, name=审批]]}//审批员通过审核@Testpublic void completeTasksForSP() {activityDemoServiceImpl.completeTask("220004", "spy1", "true");//审批后,任务列表数据减少}//设置流程变量//设置流程变量【基本类型】  @Testpublic void setTasksVar() {List<Task> lists = activityDemoServiceImpl.findTasksByUserId("sly1");for(Task task : lists) {//不知为何,变量保存成功,但数据表只有请假天数含有任务id,单获取流程变量时,根据任务id均可获取到(如下一测试)taskService.setVariable(task.getId(), "请假人", "sly1");  taskService.setVariableLocal(task.getId(), "请假天数",3);  taskService.setVariable(task.getId(), "请假日期", new Date());  }}//获取流程变量@Testpublic void getTasksVar() {List<Task> lists = activityDemoServiceImpl.findTasksByUserId("sly1");for(Task task : lists) {//获取流程变量【基本类型】  String person = (String) taskService.getVariable(task.getId(), "请假人");  Integer day = (Integer) taskService.getVariableLocal(task.getId(), "请假天数");  Date date = (Date) taskService.getVariable(task.getId(), "请假日期");   System.out.println("流程变量:"+person+"||"+day+"||"+date+"||");}}//设置流程变量【实体】  @Testpublic void setTasksVarEntity() {List<Task> lists = activityDemoServiceImpl.findTasksByUserId("sly1");for(Task task : lists) {Person p = new Person();  p.setName("翠花");  p.setId(20);  p.setDate();;  p.setNote("回去探亲,一起吃个饭123");  taskService.setVariable(task.getId(), "人员信息(添加固定版本)", p);  System.out.println("设置流程变量成功!");  }}//获取流程变量【实体】  实体必须序列化@Testpublic void getTasksVarEntity() {List<Task> lists = activityDemoServiceImpl.findTasksByUserId("sly1");for(Task task : lists) {// 2.获取流程变量,使用javaBean类型  Person p = (Person)taskService.getVariable(task.getId(), "人员信息(添加固定版本)");  System.out.println(" 请假人:  "+p.getName()+"  请假天数:  "+p.getId()+"   请假时间:"+ p.getDate()+ "   请假原因: "+p.getNote());  }}//生成流程图---232501@Testpublic void queryProImg() throws Exception {activityDemoServiceImpl.queryProImg("232501");}//生成流程图(高亮)---232501@Testpublic void queryProHighLighted() throws Exception {activityDemoServiceImpl.queryProHighLighted("232501");}/** * 查询流程变量的历史表,可以根据变量名称查询该变量的所有历史信息  */  @Test  public void findHistoryProcessVariables(){List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery()//创建一个历史的流程变量查询对象  .variableName("请假天数")  .list();  if (list!=null &&list.size()>0) {  for (HistoricVariableInstance hvi : list) {  System.out.println(hvi.getId()+"     "+hvi.getProcessInstanceId()+"   "+hvi.getVariableName()  +"   "+hvi.getVariableTypeName()+"    "+hvi.getValue());  System.out.println("########################################");  }  }  }/***  历史流程实例查询*  http://blog.csdn.net/luckyzhoustar/article/details/48652783*/@Testpublic void findHistoricProcessInstance() {// 查询已完成的流程  List<HistoricProcessInstance> datas = historyService  .createHistoricProcessInstanceQuery().finished().list();  System.out.println("使用finished方法:" + datas.size());  // 根据流程定义ID查询  datas = historyService.createHistoricProcessInstanceQuery()  .processDefinitionId("processDefinitionId").list();  System.out.println("使用processDefinitionId方法: " + datas.size());  // 根据流程定义key(流程描述文件的process节点id属性)查询  datas = historyService.createHistoricProcessInstanceQuery()  .processDefinitionKey("processDefinitionKey").list();  System.out.println("使用processDefinitionKey方法: " + datas.size());  // 根据业务主键查询  datas = historyService.createHistoricProcessInstanceQuery()  .processInstanceBusinessKey("processInstanceBusinessKey").list();  System.out.println("使用processInstanceBusinessKey方法: " + datas.size());  // 根据流程实例ID查询  datas = historyService.createHistoricProcessInstanceQuery()  .processInstanceId("processInstanceId").list();  System.out.println("使用processInstanceId方法: " + datas.size());  // 查询没有完成的流程实例  historyService.createHistoricProcessInstanceQuery().unfinished().list();  System.out.println("使用unfinished方法: " + datas.size()); }/***  历史任务查询* @throws ParseException */@Testpublic void findHistoricTasks() throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  //历史数据查询  List<HistoricTaskInstance> datas = historyService.createHistoricTaskInstanceQuery()  .finished().list();  System.out.println("使用finished方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .processDefinitionId("processDefinitionId").list();  System.out.println("使用processDefinitionId方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .processDefinitionKey("testProcess").list();  System.out.println("使用processDefinitionKey方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .processDefinitionName("testProcess2").list();  System.out.println("使用processDefinitionName方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .processFinished().list();  System.out.println("使用processFinished方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .processInstanceId("processInstanceId").list();  System.out.println("使用processInstanceId方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .processUnfinished().list();  System.out.println("使用processUnfinished方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .taskAssignee("crazyit").list();  System.out.println("使用taskAssignee方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .taskAssigneeLike("%zy%").list();  System.out.println("使用taskAssigneeLike方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .taskDefinitionKey("usertask1").list();  System.out.println("使用taskDefinitionKey方法查询:" + datas.size()); datas = historyService.createHistoricTaskInstanceQuery()  .taskDueAfter(sdf.parse("2020-10-11 06:00:00")).list();  System.out.println("使用taskDueAfter方法查询:" + datas.size()); datas = historyService.createHistoricTaskInstanceQuery()  .taskDueBefore(sdf.parse("2022-10-11 06:00:00")).list();  System.out.println("使用taskDueBefore方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .taskDueDate(sdf.parse("2020-10-11 06:00:00")).list();  System.out.println("使用taskDueDate方法查询:" + datas.size());datas = historyService.createHistoricTaskInstanceQuery()  .unfinished().list();  System.out.println("使用unfinished方法查询:" + datas.size());}/***  历史行为查询*  流程在进行过程中,每每走一个节点,都会记录流程节点的信息,包括节点的id,名称、类型、时间等,保存到ACT_HI_ACTINST表中。* @throws ParseException */@Testpublic void findHistoricActivityInstance() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  //查询数据  List<HistoricActivityInstance> datas = historyService.createHistoricActivityInstanceQuery()  .activityId("endevent1").list();  System.out.println("使用activityId查询:" + datas.size());datas = historyService.createHistoricActivityInstanceQuery()  .activityInstanceId(datas.get(0).getId()).list();  System.out.println("使用activityInstanceId查询:" + datas.size());datas = historyService.createHistoricActivityInstanceQuery()  .activityType("intermediateSignalCatch").list();  System.out.println("使用activityType查询:" + datas.size());datas = historyService.createHistoricActivityInstanceQuery()  .executionId("executionId").list();  System.out.println("使用executionId查询:" + datas.size());  datas = historyService.createHistoricActivityInstanceQuery().finished().list();  System.out.println("使用finished查询:" + datas.size());  datas = historyService.createHistoricActivityInstanceQuery()  .processInstanceId("processInstanceId").list();  System.out.println("使用processInstanceId查询:" + datas.size());datas = historyService.createHistoricActivityInstanceQuery()  .taskAssignee("crazyit").list();  System.out.println("使用taskAssignee查询:" + datas.size()); datas = historyService.createHistoricActivityInstanceQuery().unfinished().list();  System.out.println("使用unfinished查询:" + datas.size());  }/***  历史流程明细查询*  在流程进行的过程中,会产生许多明细数据,只有将History设置为最高级别的时候,才会被记录到ACT_HI_DETAIL表中。* @throws ParseException */@Testpublic void findHistoricDetail() {// 查询历史行为  HistoricActivityInstance act = historyService.createHistoricActivityInstanceQuery()  .activityName("First Task").finished().singleResult();  List<HistoricDetail> datas = historyService.createHistoricDetailQuery()  .activityInstanceId(act.getId()).list();  System.out.println("使用activityInstanceId方法查询:" + datas.size());datas = historyService.createHistoricDetailQuery().excludeTaskDetails().list();  System.out.println("使用excludeTaskDetails方法查询:" + datas.size());  datas = historyService.createHistoricDetailQuery().formProperties().list();  System.out.println("使用formProperties方法查询:" + datas.size()); datas = historyService.createHistoricDetailQuery().processInstanceId("processInstanceId").list();  System.out.println("使用processInstanceId方法查询:" + datas.size());datas = historyService.createHistoricDetailQuery().taskId("taskId").list();  System.out.println("使用taskId方法查询:" + datas.size());  datas = historyService.createHistoricDetailQuery().variableUpdates().list();  System.out.println("使用variableUpdates方法查询:" + datas.size());}}

流程图源码:

<?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="demo5" name="My process" isExecutable="true"><startEvent id="startevent1" name="Start"></startEvent><serviceTask id="servicetask1" name="业户提交" activiti:expression="#{activityDemoServiceImpl.updateBizStatus(execution,"tj")}"></serviceTask><sequenceFlow id="flow1" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow><userTask id="usertask1" name="受理" activiti:candidateUsers="${activityDemoServiceImpl.findUsersForSL(execution)}"></userTask><sequenceFlow id="flow2" sourceRef="servicetask1" targetRef="usertask1"></sequenceFlow><exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway><sequenceFlow id="flow3" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow><userTask id="usertask2" name="审批" activiti:candidateUsers="${activityDemoServiceImpl.findUsersForSP(execution)}"></userTask><sequenceFlow id="flow4" sourceRef="exclusivegateway1" targetRef="usertask2"></sequenceFlow><serviceTask id="servicetask2" name="已签发" activiti:expression="#{activityDemoServiceImpl.updateBizStatus(execution,"yqf")}"></serviceTask><endEvent id="endevent1" name="End"></endEvent><sequenceFlow id="flow6" sourceRef="servicetask2" targetRef="endevent1"></sequenceFlow><serviceTask id="servicetask3" name="资料不全" activiti:expression="#{activityDemoServiceImpl.updateBizStatus(execution,"zlbq")}"></serviceTask><sequenceFlow id="flow8" sourceRef="exclusivegateway1" targetRef="servicetask3"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${sign=="false"}]]></conditionExpression></sequenceFlow><sequenceFlow id="flow9" sourceRef="servicetask3" targetRef="endevent1"></sequenceFlow><exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway><sequenceFlow id="flow10" sourceRef="usertask2" targetRef="exclusivegateway2"></sequenceFlow><sequenceFlow id="flow11" sourceRef="exclusivegateway2" targetRef="servicetask2"></sequenceFlow><sequenceFlow id="flow12" sourceRef="exclusivegateway2" targetRef="servicetask3"></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_demo5"><bpmndi:BPMNPlane bpmnElement="demo5" id="BPMNPlane_demo5"><bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"><omgdc:Bounds height="35.0" width="35.0" x="-95.0" y="179.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="servicetask1" id="BPMNShape_servicetask1"><omgdc:Bounds height="55.0" width="105.0" x="5.0" y="169.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"><omgdc:Bounds height="55.0" width="105.0" x="155.0" y="169.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1"><omgdc:Bounds height="40.0" width="40.0" x="305.0" y="177.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2"><omgdc:Bounds height="55.0" width="105.0" x="390.0" y="170.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="servicetask2" id="BPMNShape_servicetask2"><omgdc:Bounds height="55.0" width="105.0" x="630.0" y="169.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"><omgdc:Bounds height="35.0" width="35.0" x="780.0" y="179.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="servicetask3" id="BPMNShape_servicetask3"><omgdc:Bounds height="55.0" width="105.0" x="508.0" y="30.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2"><omgdc:Bounds height="40.0" width="40.0" x="540.0" y="177.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"><omgdi:waypoint x="-60.0" y="196.0"></omgdi:waypoint><omgdi:waypoint x="5.0" y="196.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"><omgdi:waypoint x="110.0" y="196.0"></omgdi:waypoint><omgdi:waypoint x="155.0" y="196.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"><omgdi:waypoint x="260.0" y="196.0"></omgdi:waypoint><omgdi:waypoint x="305.0" y="197.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"><omgdi:waypoint x="345.0" y="197.0"></omgdi:waypoint><omgdi:waypoint x="390.0" y="197.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6"><omgdi:waypoint x="735.0" y="196.0"></omgdi:waypoint><omgdi:waypoint x="780.0" y="196.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8"><omgdi:waypoint x="325.0" y="177.0"></omgdi:waypoint><omgdi:waypoint x="325.0" y="56.0"></omgdi:waypoint><omgdi:waypoint x="508.0" y="57.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9"><omgdi:waypoint x="613.0" y="57.0"></omgdi:waypoint><omgdi:waypoint x="797.0" y="56.0"></omgdi:waypoint><omgdi:waypoint x="797.0" y="179.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10"><omgdi:waypoint x="495.0" y="197.0"></omgdi:waypoint><omgdi:waypoint x="540.0" y="197.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11"><omgdi:waypoint x="580.0" y="197.0"></omgdi:waypoint><omgdi:waypoint x="630.0" y="196.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12"><omgdi:waypoint x="560.0" y="177.0"></omgdi:waypoint><omgdi:waypoint x="560.0" y="85.0"></omgdi:waypoint></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>

SpringBoot 整合Activiti(二)——流程审批完整示例相关推荐

  1. Springboot 整合activiti及使用案例

    Springboot整合activiti 6.0 下载源码请点击这里 一 导入依赖 <dependencies><!--Activiti工作流 start--><depe ...

  2. Activiti工作流使用之SpringBoot整合Activiti

    Activiti工作流使用之SpringBoot整合Activiti 文章目录 Activiti工作流使用之SpringBoot整合Activiti 一.springboot整合Activiti环境依 ...

  3. # SpringBoot 整合 Activiti 工作流框架

    SpringBoot 整合 Activiti 工作流框架 Activiti 介绍 Activiti是一个开源的工作流引擎,它实现了BPMN 2.0规范,可以发布设计好的流程定义,并通过api进行流程调 ...

  4. springboot整合activiti报错[processes/]不存在解决方案

    springboot整合activiti时,启动抛异常 nested exception is java.io.FileNotFoundException: class path resource [ ...

  5. 三分钟springboot整合dubbo3(二)(Triple协议流式调用)

    三分钟springboot整合dubbo3(二)(Triple协议与流式调用) 1.Triple协议(粘贴官网) 2.流式调用绍 3.使用方式 新增依赖 配置文件 代码演示 3.1.ServerStr ...

  6. SpringBoot整合Activiti工作流

    依赖: 新建springBoot项目时勾选activiti,或者在已建立的springBoot项目添加以下依赖: <dependency><groupId>org.activi ...

  7. SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)

    准备工作# 环境准备# JAVA版本 Copy java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1. ...

  8. springBoot(idea)整合activiti简单流程完整示例

    最近公司在做一个带审核流程的功能,部门leader指出要集成activiti流程,而且后续的需求里也会用到.之前没有接触过经过查阅资料,自己尝试,最终走完了整个流程,记录一下自己的学习过程,如有不足之 ...

  9. SpringBoot 整合activiti5.22 实现一个完整的请假流程

    最近在熟悉activiti的使用,翻阅了很多资料,自己也整理了一点出来方便以后自己使用 一.引入依赖 <dependencies><dependency><groupId ...

最新文章

  1. amazeui页面分析5
  2. Android中的拍照camera和camera2
  3. 事物Spring boot @Transactional
  4. 前端学习(2794):实现拨打电话功能
  5. Linux运行级别介绍
  6. Python技术知识清单(数据分析)
  7. arcgis里面怎么截图_ArcGIS在变更调查中影像截图批量制作的统一方法
  8. soapUI工具使用方法、简介、接口测试
  9. 王码五笔98版forwin10_王码五笔98版-王码五笔98版64位 兼容王码五笔86版 - 快盘下载...
  10. struts2拦截器实现登录控制
  11. 如何用IDEA打包jar包
  12. HTML表格制作学习提示
  13. HTML多人联机游戏,前端实现双人联机版俄罗斯方块小游戏2(实现双人联机)
  14. Unity通过鼠标或者手势实现拉进拉远,旋转等操作的常用方法
  15. 银行家算法的实验报告
  16. 重磅 | 《2020年度中国计算机视觉人才调研报告》正式出炉
  17. Ubuntu解压命令集
  18. mac定时执行python_mac下定时执行python程序(附不执行解决方案).md
  19. Vue3 - filters 过滤器为什么被移除放弃?取而代之的解决方案又是什么?
  20. LINUX 查看CUP温度

热门文章

  1. 树莓派家用NAS解决方案
  2. 洋哥线下见面会,小姐姐都问了什么?
  3. 拍手游戏Python
  4. 队列、堆、栈、堆栈的区别?
  5. 离散时间信号和系统的时域分析
  6. Latex中如何使用中文?
  7. 【网络】网络层协议——IP
  8. 【控制系统的微分方程】
  9. 深度强化学习(DRL)简介与常见算法(DQN,DDPG,PPO,TRPO,SAC)分类
  10. Qt Quick实现的文件传输工具(TCP传输篇)