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

9 篇文章 0 订阅
8 篇文章 0 订阅

https://blog.csdn.net/fanxiangru999/article/details/79381966

前两天做了一个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>

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot是一个开源的Java开发框架,旨在简化Spring应用程序的开发过程。Activiti是一个开源的工作流和业务流程管理系统,它提供了一个用于设计、执行和监控业务流程的平台。 Spring Boot整合Activiti可以实现流程审批功能。首先,我们需要在pom.xml文件中添加Activiti的依赖。然后,在Spring Boot的配置文件中配置Activiti的相关信息,比如数据库连接、流程定义文件的位置等。 接下来,我们可以定义流程模型,包括流程节点、流程线等。可以使用Activiti提供的图形化工具Activiti Modeler进行可视化设计。然后,将流程模型部署到Activiti引擎。 在代码中,我们可以使用Activiti提供的API来启动流程实例、查询任务、完成任务等。通过编写监听器,我们可以在流程的不同节点上执行自定义的业务逻辑。 为了方便用户对流程审批操作,我们可以使用Activiti提供的表单功能。通过表单,用户可以填写审批意见、上传附件等。在代码中,我们可以通过获取表单数据来实现流程的控制逻辑。 最后,我们可以使用Activiti提供的监控功能来查看流程的状态和执行情况。Activiti提供了一个可视化的流程监控控制台,可以实时查看流程实例、任务、历史记录等信息。 综上所述,通过Spring Boot整合Activiti,我们可以实现流程审批功能。这使得流程管理更加简单高效,提高了审批流程的可追溯性和可控性。同时,使用Spring Boot的优势,我们可以更加便捷地进行开发和部署。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值