SpringBoot 整合Activiti(二)——流程审批完整示例

前两天做了一个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,业务表id
		System.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 {
	@Resource
	private ActivityDemoServiceImpl activityDemoServiceImpl;
	@Autowired  
	private TaskService taskService;  
	@Autowired  
	private HistoryService historyService;  

	//启动流程---215001
	@Test
	public void startPro() {
		activityDemoServiceImpl.startProcesses("123456");
	}

	//获取受理员任务列表
	@Test
	public void findTasksForSL() {
		List<Task> lists = activityDemoServiceImpl.findTasksByUserId("sly1");
		System.out.println("任务列表:"+lists);//任务列表:[Task[id=210028, name=受理], Task[id=215005, name=受理]]
	}

	//受理员受理数据
	@Test
	public void completeTasksForSL() {
		activityDemoServiceImpl.completeTask("210028", "sly1", "true");//受理后,任务列表数据减少
	}

	//获取审批员任务列表
	@Test
	public void findTasksForSP() {
		List<Task> lists = activityDemoServiceImpl.findTasksByUserId("spy1");
		System.out.println("任务列表:"+lists);//任务列表:[Task[id=220004, name=审批]]
	}

	//审批员通过审核
	@Test
	public void completeTasksForSP() {
		activityDemoServiceImpl.completeTask("220004", "spy1", "true");//审批后,任务列表数据减少
	}


	//设置流程变量
	//设置流程变量【基本类型】  
	@Test
	public 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());  
		}
	}

	//获取流程变量
	@Test
	public 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+"||");
		}
	}

	//设置流程变量【实体】  
	@Test
	public 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("设置流程变量成功!");  
		}
	}

	//获取流程变量【实体】  实体必须序列化
	@Test
	public 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
	@Test
	public void queryProImg() throws Exception {
		activityDemoServiceImpl.queryProImg("232501");
	}

	//生成流程图(高亮)---232501
	@Test
	public 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
	 */
	@Test
	public 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 
	 */
	@Test
	public 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 
	 */
	@Test
	public 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 
	 */
	@Test
	public 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>

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页