【activiti 入门】springboot 集成activiti6.0的demo

2023-11-11

环境:

jdk 1.8

maven 3.0

IDEA插件之actiBPM

springboot2.0

activiti6.0

mysql数据库

 

具体demo地址:https://download.csdn.net/download/qq_33333654/11790823

 

第一步、创建springbootweb项目

创建流程就不说了,自行百度吧。简单

第二步、集成activiti6.0

添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <packaging>war</packaging>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter-basic</artifactId>
            <version>6.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>6.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.41</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8081</port>
                    <path>/activity</path>
                    <systemProperties>
                        <com.sun.management.jmxremote.port>4000</com.sun.management.jmxremote.port>
                    </systemProperties>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project> 

 上面是我所有的依赖。

yml文件配置

spring:
  activiti:
    check-process-definitions: true #自动检查、部署流程定义文件
    database-schema-update: true  #自动更新数据库结构
    history-level: full  #保存历史数据级别设置为full最高级别,便于历史数据的追溯 还有两个级别activity与none
    # process-definition-location-prefix: classpath:/processes/
    #process-definition-location-suffixes:
    #  - **.bpmn20.xml
    #  - **.bpmn
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

注意下,check-process-definitions这个后面是要修改值的。

 

在resources文件夹下创建processes文件夹。

创建日志文件log4j.properties

log4j.rootLogger=DEBUG, ACT
log4j.appender.ACT=org.apache.log4j.ConsoleAppender
log4j.appender.A1.Encoding=UTF-8
log4j.appender.ACT.layout=org.apache.log4j.PatternLayout
log4j.appender.ACT.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n

 启动类添加注解

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class DemoApplication {

    public static void main(String[] args) {

        SpringApplication.run(DemoApplication.class, args);
    }
}

 启动项目,启动后刷新下数据库,可以看到28张act开头的数据库表,全部是activiti的表

第二步算是完成了。

第三步、绘制流程图

在processes文件夹下创建一个xml文件,文件内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/testm1539766523202" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1539766523202" name=""
             targetNamespace="http://www.activiti.org/testm1539766523202" typeLanguage="http://www.w3.org/2001/XMLSchema">
    <process id="leave1" name="leave1" isClosed="false" isExecutable="true" processType="None">
        <startEvent id="_2" name="start"/>
        <userTask activiti:assignee="${leave.userId}" activiti:exclusive="true" id="_3" name="submit"/>
        <exclusiveGateway gatewayDirection="Unspecified" id="_4" name="result"/>
        <userTask activiti:assignee="${leave.approver1}" activiti:exclusive="true" id="_5" name="approve1"/>
        <exclusiveGateway gatewayDirection="Unspecified" id="_6" name="result"/>
        <userTask activiti:assignee="${leave.approver2}" activiti:exclusive="true" id="_7" name="approve2"/>
        <exclusiveGateway gatewayDirection="Unspecified" id="_8" name="result"/>
        <endEvent id="_9" name="end"/>
        <sequenceFlow id="_10" sourceRef="_2" targetRef="_3"/>
        <sequenceFlow id="_11" sourceRef="_3" targetRef="_4"/>
        <sequenceFlow id="_12" name="y" sourceRef="_4" targetRef="_5">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.submit==true}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="_13" name="n" sourceRef="_4" targetRef="_9">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.submit==false}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="_14" sourceRef="_5" targetRef="_6"/>
        <sequenceFlow id="_15" name="n" sourceRef="_6" targetRef="_7">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree1==true}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="_16" sourceRef="_7" targetRef="_8"/>
        <sequenceFlow id="_17" name="y" sourceRef="_6" targetRef="_3">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree1==false}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="_18" name="n" sourceRef="_8" targetRef="_3">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree2==false}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="_19" name="y" sourceRef="_8" targetRef="_9">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree2==true}]]></conditionExpression>
        </sequenceFlow>
    </process>
</definitions>

 

 复制该文件,并粘贴到当前文件夹,后缀名修改为bpmn。双击打开,如下图:

流程图绘制完成。

第四步:部署流程、启动流程、审批、结束流程。

首先,找到yml文件,修改

check-process-definitions的值为false

如下图,分别创建对应的文件夹和文件,等下会挨个粘贴代码

 

参考文献:https://yq.aliyun.com/articles/697485

 

model的leave

package com.example.demo.model;

import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * @ProjectName: demo
 * @Package: com.example.demo.service.model
 * @ClassName: Leave
 * @Author: MC
 * @Description: ${description}
 * @Date: 2019/9/19 0019 13:14
 * @Version: 1.0
 */
@Data
public class Leave implements Serializable {
    private static final long serialVersionUID = 2248469053125414262L;

    private String userId;

    private Boolean submit;

    private Date startDate;

    private Date endDate;

    private float totalDay;

    private String desc;

    private String taskId;

    private String taskName;

    private String approver1;

    private Boolean agree1;

    private String approveDesc1;

    private String approver2;

    private Boolean agree2;

    private String approveDesc2;
}

 

ActivitiUtil
package com.example.demo.utils;

import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @ProjectName: demo
 * @Package: com.example.demo.utils
 * @ClassName: ActivitiUtil
 * @Author: MC
 * @Description: ${description}
 * @Date: 2019/9/19 0019 18:17
 * @Version: 1.0
 */
@Service
public class ActivitiUtil {
    @Autowired
    private ProcessEngine processEngine;

    @Autowired
    private RuntimeService runtimeService ;

    @Autowired
    private TaskService taskService ;

    @Autowired
    private RepositoryService repositoryService;

    /**
     * @Method 部署流程
     * @Author MC

     * @Return
     * @Date 2019/9/19 0019 18:34
     */
    public void deploy(String filePath){
        if(!StringUtils.isEmpty(filePath)){
            repositoryService.createDeployment()
                    .addClasspathResource(filePath)
                    .deploy();
        }
    }

    /**
     * @Method 启动流程
     * @Author MC

     * @Return
     * @Date 2019/9/19 0019 18:35
     */
    public Map<String,Object> start(Map<String,Object> map ,String processId){
        ProcessInstance leave1 = runtimeService.startProcessInstanceByKey(processId, map);
        String processDefinitionId = leave1.getProcessDefinitionId();
        System.out.print("============processDefinitionId:" + processDefinitionId);//流程定义的ID
        System.out.print("============processInstanceId:" + leave1.getId());//流程实例的ID
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("result",leave1);
        resultMap.put("processDefinitionId",processDefinitionId);
        resultMap.put("processInstanceId",leave1.getId());
        return resultMap;
    }

    /**
     * @Method 根据流程实例ID和用户ID查询任务ID
     * @Author MC
     用户ID必须设置为Assignee
     * @Return
     * @Date 2019/9/19 0019 19:01
     */
    public String getTaskId( String processInstanceId, String userId){
        TaskService taskService = processEngine.getTaskService();//获取任务的Service,设置和获取流程变量
        //查询当前办理人的任务ID
        Task task = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)//使用流程实例ID
                .taskAssignee(userId)//任务办理人
                .singleResult();

        return  task.getId();
    }

    /**
     * @Method 获取流程实例列表
     * @Author MC

     * @Return
     * @Date 2019/9/19 0019 18:32
     */
    public List<ProcessInstance> queryProcessInstanceAllList(String processDefinitionKey){
        return runtimeService
                .createProcessInstanceQuery().processDefinitionKey(processDefinitionKey)
                .list();
    }


    /**
     * @Method 根据assignee来查询用户
     * @Author MC

     * @Return
     * @Date 2019/9/19 0019 18:29
     */
    public Task queryTask(String assignee) {
        //startProcessInstance();
        // taskService.createTaskQuery().taskCandidateGroup("sales").singleResult();

        Task task= taskService.createTaskQuery().taskAssignee(assignee).singleResult();
        if(task == null){
            return null;
        }

        System.out.println("审批人为【"+assignee+"】的任务有:任务编号为【" + task.getId() + "】"+ task.getTaskDefinitionKey());
        return task;
    }

    /**
     *
     * @param queryType  查询类型1 根据 assignee 查询  2 根据candidateuser查询
     * @param str
     */
    public String getNextNodeId(int queryType,String str) {


        Task task = null;
        if(queryType==1) {
            task = taskService.createTaskQuery().taskAssignee(str).singleResult();
        }else if(queryType==2){
            task = taskService.createTaskQuery().taskCandidateUser(str).singleResult();

        }else if(queryType==3){
            task = taskService.createTaskQuery().taskCandidateGroup(str).singleResult();

        }

//        List<FlowElement> list = getNextNode(task.getId());


        if(task==null) {
            return null;
        }

//        for(FlowElement e :list) {
//            //((org.activiti.bpmn.model.UserTask) e)
//        }
        return task.getId();

    }


    /**
     * 获取流程的下一个节点 且要经过规则引擎判断后的节点
     * @param taskId
     * @return
     */
    private List<FlowElement> getNextNode(String taskId) {

        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if(task==null) {
            return null;
        }
        List<FlowElement> list = new ArrayList<FlowElement>();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();

        //当前活动节点
        String activitiId = processInstance.getActivityId();

        System.out.println("当前节点是【"+activitiId+"】");

        //pmmnModel 遍历节点需要它
        BpmnModel bpmnModel =  repositoryService.getBpmnModel(task.getProcessDefinitionId());

        List<Process> processList = bpmnModel.getProcesses();

        //循环多个物理流程
        for(Process process:processList) {

            //返回该流程的所有任务,事件
            Collection<FlowElement> cColl = process.getFlowElements();
            //遍历节点
            for(FlowElement f :cColl) {


                //如果改节点是当前节点 者 输出该节点的下一个节点
                if(f.getId().equals(activitiId)) {

                    List<SequenceFlow>  sequenceFlowList = new ArrayList<SequenceFlow>();
                    //通过反射来判断是哪种类型
                    if(f instanceof org.activiti.bpmn.model.StartEvent) {
                        //开始事件的输出路由
                        sequenceFlowList   = ((org.activiti.bpmn.model.StartEvent) f).getOutgoingFlows();
                    }else if(f instanceof org.activiti.bpmn.model.UserTask) {

                        sequenceFlowList   = ((org.activiti.bpmn.model.UserTask) f).getOutgoingFlows();


                        for(SequenceFlow sf :sequenceFlowList)  {

                            String targetRef = sf.getTargetRef();
                            FlowElement ref = process.getFlowElement(targetRef);

                            // nextActivitiIdList.add(ref.getId());

                            list.add(ref);
                        }

                    }else if(f instanceof org.activiti.bpmn.model.SequenceFlow) {


                    }else if(f instanceof org.activiti.bpmn.model.EndEvent) {
                        sequenceFlowList   = ((org.activiti.bpmn.model.EndEvent) f).getOutgoingFlows();
                    }
                    break;
                }

            }

        }
        return list;
    }


    /**
     * @Method 流程流转到下一步
     * @Author MC
根据 assignee 查询出任务,如果存在则设置当前任务的 assignee 为 nextUser
     * @Return 不存在下一个节点返回false;
     * @Date 2019/9/19 0019 18:23
     */
    public boolean completeByAssignee(String assignee,String nextUser) throws Exception {

        HashMap<String,Object> map = new HashMap<String,Object>();

        map.put("nextUser", nextUser);
        Task task = taskService.createTaskQuery().taskAssignee(assignee).singleResult();
        if(task == null){
            System.out.println("下一节点不存在");
            return false;
        }
        taskService.complete(task.getId(),map);
        System.out.println("完成任务 编号为【" + task.getId() + "】,名称为【"+task.getName()+"】的任务");
        return true;
    }

    /**
     * 设置某个节点的审批人员
     * @param taskId
     * @param user
     */
    public void setApproveUser(String taskId,String user) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        task.setAssignee(user);
        taskService.saveTask(task);
    }


    /**
     * 取下一个节点的审批人
     * @param taskId
     * @return
     */
    public List<String> getNextTaskUserByTaskId(String taskId) {
        List<String> list = new ArrayList<String>();
        List<FlowElement> fList = getNextNode(taskId);
        for(FlowElement u:fList){
            String str =  ((org.activiti.bpmn.model.UserTask) u).getAssignee();
            list.add(str);
        }
        return list ;
    }


    /**
     * 找当前节点的候选审批人  供流程实例start后调用
     * @param taskId
     * @return
     */
    public List<String> getThisTaskUser(String taskId) {
        List<String> list = new ArrayList<String>();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        String taskUser = task.getAssignee();

        //*****************************根据taskUser的配置到自己的表里面去找数据

        list.add(taskUser);
        return list ;
    }

    /**
     * @Method 任务是否完结
     * @Author MC

     * @Return
     * @Date 2019/9/20 0020 11:20
     */
    public boolean isOverTask(String processInstanceId){
        ProcessInstance pi= runtimeService.createProcessInstanceQuery() // 创建流程实例查询
                .processInstanceId(processInstanceId) // 用流程实例id查询
                .singleResult();
        if(pi!=null){
            System.out.println("流程正在执行!");
            return false;
        }else{
            System.out.println("流程已经执行结束!");
        }
        return true;
    }


    /**
     * @Method 历史流程实例查询
     * @Author MC

     * @Return
     * @Date 2019/9/20 0020 11:22
     */
    public  List<HistoricProcessInstance>  queryHisProInstance(String processDefinitionKey){
        List<HistoricProcessInstance> historicProcessInstanceList = processEngine.getHistoryService().createHistoricProcessInstanceQuery()
                .processDefinitionKey(processDefinitionKey)
                .orderByProcessInstanceEndTime()
                .desc()
                .list();
        /*for(HistoricProcessInstance historicProcessInstance:historicProcessInstanceList){
            System.out.println("历史流程实例id: "+historicProcessInstance.getId());
            System.out.println("历史流程实例的完成时间: "+historicProcessInstance.getEndTime());
        }*/
        return historicProcessInstanceList;
    }


    /**
     * 查询历史流程变量
     */
    public List<HistoricVariableInstance> queryHisProVariable(String processInstanceId){
        List<HistoricVariableInstance> historicVariableInstanceList = processEngine.getHistoryService()
                .createHistoricVariableInstanceQuery()
                .processInstanceId(processInstanceId).list();
        /*for(HistoricVariableInstance historicVariableInstance: historicVariableInstanceList){
            System.out.println("历史流程变量id: "+historicVariableInstance.getId());
            System.out.println("历史流程变量名称: "+historicVariableInstance.getVariableName());
            System.out.println("历史流程变量值: "+historicVariableInstance.getValue());
            System.out.println("==================================================");
        }*/
        return historicVariableInstanceList;
    }


    /**
     * 根据办理人查询历史任务实例
     */
    public List<HistoricTaskInstance> queryHisTaskInstanceByAssignee(String processDefinitionKey,String taskAssignee){
        List<HistoricTaskInstance> historicTaskInstanceList = processEngine.getHistoryService().createHistoricTaskInstanceQuery()
                .processDefinitionKey(processDefinitionKey)
                .taskAssignee(taskAssignee).list();
        /*for(HistoricTaskInstance historicTaskInstance:historicTaskInstanceList){
            System.out.println("历史任务id: "+historicTaskInstance.getId());
            System.out.println("历史任务名称: "+historicTaskInstance.getName());
            System.out.println("历史任务结束时间: "+historicTaskInstance.getEndTime());
            System.out.println("办理人: "+historicTaskInstance.getAssignee());
            System.out.println("==================================================");
        }*/
        return historicTaskInstanceList;
    }



    /**
     * 历史任务查询
     * type: 0:未完成 1:已完成  "":all
     */
    public List<HistoricTaskInstance> historyTaskList(String processInstanceId,String type){
        List<HistoricTaskInstance> list=null;

        if(StringUtils.isEmpty(type)){
            list =  processEngine.getHistoryService() // 历史相关Service
                    .createHistoricTaskInstanceQuery() // 创建历史任务实例查询
                    .processInstanceId(processInstanceId) // 用流程实例id查询
                    .list();
        }else if("0".equals(type)){
            list =  processEngine.getHistoryService() // 历史相关Service
                    .createHistoricTaskInstanceQuery() // 创建历史任务实例查询
                    .processInstanceId(processInstanceId) // 用流程实例id查询
                    .unfinished()
                    .list();
        }else if("1".equals(type)){
            processEngine.getHistoryService() // 历史相关Service
                    .createHistoricTaskInstanceQuery() // 创建历史任务实例查询
                    .processInstanceId(processInstanceId) // 用流程实例id查询
                    .finished() // 查询已经完成的任务
                    .list();
        }
       /* for(HistoricTaskInstance hti:list){
            System.out.println("任务ID:"+hti.getId());
            System.out.println("流程实例ID:"+hti.getProcessInstanceId());
            System.out.println("任务名称:"+hti.getName());
            System.out.println("办理人:"+hti.getAssignee());
            System.out.println("开始时间:"+hti.getStartTime());
            System.out.println("结束时间:"+hti.getEndTime());
            System.out.println("=================================");
        }*/

       return list;
    }

    /**
     * 已完成的历史活动查询
     */
    public List<HistoricActivityInstance> historyActInstanceList(String processInstanceId){
        List<HistoricActivityInstance>  list=processEngine.getHistoryService() // 历史相关Service
                .createHistoricActivityInstanceQuery() // 创建历史活动实例查询
                .processInstanceId(processInstanceId) // 执行流程实例id
                .finished()
                .list();
       /* for(HistoricActivityInstance hai:list){
            System.out.println("活动ID:"+hai.getId());
            System.out.println("流程实例ID:"+hai.getProcessInstanceId());
            System.out.println("活动名称:"+hai.getActivityName());
            System.out.println("办理人:"+hai.getAssignee());
            System.out.println("开始时间:"+hai.getStartTime());
            System.out.println("结束时间:"+hai.getEndTime());
            System.out.println("=================================");
        }*/
       return list;
    }

}

 

LeaveController
package com.example.demo.web;

import com.example.demo.model.Leave;
import com.example.demo.utils.ActivitiUtil;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ProjectName: demo
 * @Package: com.example.demo.web
 * @ClassName: LeaveController
 * @Author: MC
 * @Description: ${description}
 * @Date: 2019/9/19 0019 13:08
 * @Version: 1.0
 */
@RestController
@RequestMapping("/level/v1")
public class LeaveController {
    public static final Logger log = LoggerFactory.getLogger(LeaveController.class);
    @Autowired
    private ProcessEngine processEngine;

    @Autowired
    private RuntimeService runtimeService ;

    @Autowired
    private TaskService taskService ;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private  ActivitiUtil activitiUtil;

    /**
     * @Method 部署流程
     * @Author MC

     * @Return
     * @Date 2019/9/19 0019 17:07
     */
    @RequestMapping(value = "/deploy",method = RequestMethod.GET)
    public Map<String,Object> deploy(){
        repositoryService.createDeployment()
                .addClasspathResource("processes/leave1.bpmn")
                .deploy();
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
        for (int i = 0; i < list.size(); i++) {
            ProcessDefinition p = list.get(i);
            System.out.print("============key:"+p.getKey());
        }
        Map<String,Object> map = new HashMap<>();
        map.put("list",list);
        return map;
    }

    /**
     * @Method 根据userId启动流程
     * @Author MC

     * @Return
     * @Date 2019/9/19 0019 13:23
     */
    @RequestMapping(value = "/start",method = RequestMethod.GET)
    public Map<String,Object> start(@RequestParam String userId){
        Map<String,Object> map = new HashMap<>();
        Leave leave = new Leave();
        leave.setUserId(userId);
        map.put("leave",leave);
        ProcessInstance leave1 = runtimeService.startProcessInstanceByKey("leave1", map);
        String processDefinitionId = leave1.getProcessDefinitionId();
        System.out.print("============processDefinitionId:" + processDefinitionId);//流程定义的ID
        System.out.print("============processInstanceId:" + leave1.getId());//流程实例的ID
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("result",leave1);
        resultMap.put("processDefinitionId",processDefinitionId);
        resultMap.put("processInstanceId",leave1.getId());
        return resultMap;
    }

    @RequestMapping(value = "/selectUser",method = RequestMethod.GET)
    public String selectUser() throws Exception {
        String taskId = activitiUtil.getTaskId("5005", "feng");
        List<String> userList= activitiUtil.getNextTaskUserByTaskId(taskId);
        //设置审批人
        activitiUtil.setApproveUser(taskId, "12321");
        taskId = activitiUtil.getNextNodeId(1,"feng");
        //第一个审批人提交流程  feng 为当前节点审批人,xiaozhang 为设置的下一节点审批人
        boolean b = activitiUtil.completeByAssignee("feng","xiaozhang");
        //************第一个人审批成功
        if(b){
            //TODO
        }
//        taskId = activitiUtil.getNextNodeId(1,"xiaozhang");
//        //选人
//        userList= activitiUtil.getNextTaskUserByTaskId(taskId);
//        //第一个审批人提交流程
//        activitiUtil.completeByAssignee("xiaozhang","xiaoming");
//
//        activitiUtil.getNextNodeId(1,"xiaoming");
//
//        //第二个审批人提交流程
//        activitiUtil.completeByAssignee("xiaoming","xiangwang");
        //************第二个人审批成功

        return "";

    }



    /**
     * @Method 根据流程实例ID和任务办理人其实就是Assignee获取任务task实例
     * @Author MC

     * @Return
     * @Date 2019/9/19 0019 13:45
     */
    @RequestMapping(value = "/task",method = RequestMethod.GET)
    public String task(@RequestParam String processInstanceId,@RequestParam String userId){
        //查询当前办理人的任务ID
        Task task = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)//使用流程实例ID
                .taskAssignee(userId)//任务办理人
                .singleResult();

        return  task.getId();
    }


    /**
     * @Method 填写请假表单
     * @Author MC

     * @Return
     * @Date 2019/9/19 0019 13:45
     */
    @RequestMapping(value = "/apply",method = RequestMethod.POST)
    public Map<String,Object> apply(@RequestBody Leave leave){
        String taskId = leave.getTaskId();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Map<String,Object> map = new HashMap<>();
        // 获取流程参数  对应启动流程时,入参的参数leave
        Leave variable = (Leave)taskService.getVariable(taskId, "leave");
        // 从入参的表单对象中取值,设置流程参数对象的值
        variable.setDesc(leave.getDesc());
        variable.setStartDate(leave.getStartDate());
        variable.setTotalDay(leave.getTotalDay());
        variable.setApprover1(leave.getApprover1());
        variable.setSubmit(leave.getSubmit());
        map.put("leave",variable);
         taskService.complete(taskId,map);
//        Map<String, Object> resultMap = ResultMapHelper.getSuccessMap();
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("leave",leave);
        return resultMap;
    }


    /**
     * @Method 根据用户ID查询流程集合
     * @Author MC

     * @Return
     * @Date 2019/9/19 0019 13:52
     */
    @RequestMapping(value = "/find",method = RequestMethod.GET)
    public Map<String,Object> find(@RequestParam("userId") String userId){
        List<Task> list = taskService.createTaskQuery().taskAssignee(userId).list();
        List<Leave> resultList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(list)){
            for (Task t : list) {
                Leave leave = (Leave)taskService.getVariable(t.getId(),"leave");
                leave.setTaskId(t.getId());
                leave.setTaskName(t.getName());
                resultList.add(leave);
            }
        }

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("resultList",resultList);
        return resultMap;
    }


    /**
     * 直接主管审批
     * @param leave
     * @return
     */
    @RequestMapping(value = "/approve1", method = RequestMethod.POST)
    public Map<String, Object> approve1(@RequestBody Leave leave){
        Task task = taskService.createTaskQuery().taskId(leave.getTaskId()).singleResult();
        Map<String, Object> vars = new HashMap<>();
        Leave origin = (Leave) taskService.getVariable(leave.getTaskId(), "leave");
        origin.setApproveDesc1(leave.getApproveDesc1());
        origin.setAgree1(leave.getAgree1());
        origin.setApprover2(leave.getApprover2());
        vars.put("leave", origin);
        taskService.complete(leave.getTaskId(),vars);//设置完以后会发现run_task表中的Assignee字段为空。。。。
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("leave", origin);
        return resultMap;
    }

    /**
     * 部门主管审批
     * @param leave
     * @return
     */
    @RequestMapping(value = "/approve2", method = RequestMethod.POST)
    public Map<String, Object> approve2(@RequestBody Leave leave){
        Task task = taskService.createTaskQuery().taskId(leave.getTaskId()).singleResult();
        Map<String, Object> vars = new HashMap<>();
        Leave origin = (Leave) taskService.getVariable(leave.getTaskId(), "leave");
        origin.setApproveDesc2(leave.getApproveDesc2());
        origin.setAgree2(leave.getAgree2());
        vars.put("leave", origin);
        taskService.complete(leave.getTaskId(),vars);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("leave", origin);
        return resultMap;
    }


    /**
     * 查看历史记录
     * @param userId
     * @return
     */
    @RequestMapping(value="/findClosed", method = RequestMethod.GET)
    public Map<String, Object> findClosed(@RequestParam String userId){
//        HistoryService historyService = processEngine.getHistoryService();
        List<Leave> leaves = new ArrayList<>();
        List<HistoricProcessInstance> historicProcessInstanceList = activitiUtil.queryHisProInstance("leave1");
        for(HistoricProcessInstance historicProcessInstance:historicProcessInstanceList){
            System.out.println("历史流程实例id: "+historicProcessInstance.getId());
            System.out.println("历史流程实例的完成时间: "+historicProcessInstance.getEndTime());
            leaves.add((Leave) historicProcessInstance.getProcessVariables().get("leave"));
        }
       // 注意:这一段为什么获取不到数据?哪位能帮忙解决下?
       List<HistoricProcessInstance> list = processEngine.getHistoryService().createHistoricProcessInstanceQuery().
                processDefinitionKey("leave1")
                .variableValueEquals("leave.userId",userId).list();


        List<HistoricVariableInstance> historicVariableInstanceList = activitiUtil.queryHisProVariable("5005");
        for(HistoricVariableInstance historicVariableInstance: historicVariableInstanceList){
            System.out.println("历史流程变量id: "+historicVariableInstance.getId());
            System.out.println("历史流程变量名称: "+historicVariableInstance.getVariableName());
            System.out.println("历史流程变量值: "+historicVariableInstance.getValue());
            System.out.println("==================================================");
        }

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("datas", leaves);
        return resultMap;
    }


}

 第四步操作完成。

接下来启动项目,观察数据库内容的变化,并按照绘制的流程图调用相关的接口,观察数据库的变化。

 

以上内容属于入门篇,仅供参考。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【activiti 入门】springboot 集成activiti6.0的demo 的相关文章

  • Activiti6.0学习实践(4)-流程引擎配置一

    在上一节 我们进行了一个hello world 的简单应用搭建 本节继续对activiti的一些重要组件进行更进一步的分析 目录 1 activiti工程骨架 1 2 添加demo类到骨架工程 1 3 创建基于骨架的maven工程 2 流程
  • activiti报错:org.activiti.engine.ActivitiTaskAlreadyClaimedException: Task ‘12502‘ is already claimed

    在运行activiti时 报错信息如下 Exception in thread main org activiti engine ActivitiTaskAlreadyClaimedException Task 12502 is alrea
  • Activiti和tk.mybatis的坑

    近期开发关于工作流的项目 遇到一个很坑的问题 activiti和tk mybatis居然会有冲突 先看异常 报错的原因大概就算这句话 Parameter 1 of method springProcessEngineConfiguratio
  • activiti7-4-流程激活和挂起

    我是一个目录 1 分析 2 全部流程实例的挂起和激活 3 单个流程实例挂起 1 分析 如果公司制度发生变化 1 原本没有批完的流程怎么办 例如 30人没有处理完 怎么办 看公司制度了 有可能 按原来的走 也有可能全部打回 重新发起 全部按照
  • 计算机专业毕业设计一

    概述 从一个医学生转行成为一名程序员 对于我来说 是一个超前的跨越 好奇的朋友会问了 医学这么吃香的行业 怎么转行做码农呢 这个道理很简单 就是想象和显示差距太大了 距离梦想的专业差了点距离 请允许我去小黑屋哭上半个小时 想当年 我意气风发
  • Activiti 工作流引擎 详解

    Activiti 工作流引擎 详解 1 Activiti工作流概述 1 1 工作流概述 1 2 工作流系统 1 3 Activiti概述 1 4 BPM 2 Activiti工作流环境搭建 3 Activiti 类 配置文件之间的关系 3
  • 【activiti】网关

    activiti网关 网关是用来控制流程的走向的 1 排他网关 ExclusiveGateway 1 1 什么是排他网关 排他网关 用来在流程中实现决策 当执行到这个网关时 会根据判断条件去选择执行某一条分支 注意 排他网关只会选择一个为t
  • 工作流Activiti7整合SpringBoot使用

    前言 一个软件系统中具有工作流的功能 我们把它称为工作流系统 一个系统中工作流的功能是什么 就是对系统的业务流程进行自动化管理 所以工作流是建立在业务流程的基础上 所以一个软件的系统核心根本上还是系统的业务流程 工作流只是协助进行业务流程管
  • springboot整合activiti7

    一 添加依赖
  • activiti学习(五)——执行监听器与任务监听器的基本使用

    本文介绍执行监听器与任务监听器的基本原理和使用方法 当流程途径连线或者节点的时候 会触发对应的事件类型 执行监听器与任务监听器在生产中经常会用在几个方面 动态分配节点处理人 通过前一个节点设置的变量 在运行到下一个节点时设置对应的处理人 当
  • activiti自定义代理人、候选人、候选组选择

    介绍 AdminEAP框架中集成了Activiti工作流组件 使用了activiti explorer中的在线流程设计器 其中在选择代理人 审批人 中 原生的操作是输入数据 没有和系统自动关联 同时 原生的在线流程设计器使用AngularJ
  • 【activiti 入门】springboot 集成activiti6.0的demo

    环境 jdk 1 8 maven 3 0 IDEA插件之actiBPM springboot2 0 activiti6 0 mysql数据库 具体demo地址 https download csdn net download qq 3333
  • 2023最新版本Activiti7系列-源码篇-初始化过程

    源码分析 1 设计模式 1 1 命令模式 https dpb bobokaoya sm blog csdn net article details 89115420 1 2 责任链模式 https dpb bobokaoya sm blog
  • 《5分钟说完一个概念》:什么是Bootstrap采用

    想知道中国人的平均身高 群体均值 群体方差为 每次抽样 1000 人 抽样了 次 每次抽样的 1000人 的平均身高是一次随机抽样 这
  • Activiti-设置全局变量的四种方法

    1 在流程启动的时候设置全局变量 在流程启动时设置全局变量 Test public void startProcessInstance 得到runtimeService RuntimeService runtimeService proce
  • Spring新事务与Retryable相结合

    如果我有一个方法 对于某个异常有 Spring 可重试 并且还有一个 Transactional Requires new 那么每次重试完成时 它会创建一个新事务还是使用现有事务 ie Retryable maxAttempts 5 bac
  • 如何将候选用户列表传递给 alfresco 中的 activiti 工作流任务?

    我希望能够传递作为任务候选者的用户列表 用户是从数据列表中检索的 不能作为一个组使用 Activiti candidateUsers 似乎是正确的方法 假设已获取用户并将其设置在变量 ipw reviwers 中
  • 将 Activiti 任务从旧流程迁移到新流程

    我有一个用于某些业务流程的 Activiti 项目 问题在于移民 现有流程有一些未完成的任务 我想通过添加新步骤来修改现有流程 现在 当我创建一个新任务时 这个新任务将根据更新的流程进行处理 而未完成的任务将按照旧流程进行处理 让我们看下面
  • 开源 BPM 工具(如 Activiti、bonita)和 Windows Workflow Foundation 之间有什么区别

    我试图找到一个基于asp net的免费开源BPM工具 但不幸的是我没有找到这样的工具 但最近我读到一篇关于Windows Workflow Foundation的文章 那么它是否提供了类似于开源BPM工具如Activiti bonita J
  • 如何获取控制器中流程实例的ID?

    我的环境 Alfresco Share v5 2 d r134641 b15 Aikau 1 0 101 3 Spring Surf 5 2 d Spring WebScripts 6 13 Freemarker 2 3 20 alfres

随机推荐

  • 2018网易前端实习笔试题

    前端时间做了网易前端实习的笔试题 偶像想起 总结一下 前面的选择题 我就不一一细说了 主要考察的是对于前端的基础 以及计算机基础 这次主要讲下算法题 所有算法我均用js所写 不同语言思路均相同 以下都是我对题目的简述 1 小易学了集合 已知
  • CTF show WEB7-8

    题目网站https ctf show web7 点开其中一篇文章 输入id 1 1存在全部文章内容 说明为整形注入 1 爆库名 web7 当输入为id 1 or ascii substr database 1 1 119时出现文章内容 证明
  • 如何制作 linux 系统 U盘启动盘

    原贴 如何制作 linux 系统 U盘启动盘 Will kkc的博客 CSDN博客 linux系统启动盘 1 制作linux 系统的U盘启动盘 需要选择ISO 模式 给大家推荐几个制作相关软件以及相关制作过程 UltraISO rufus
  • Nginx将日志输送到Rsyslog服务

    直接使用Nginx记录日志 在多台服务器的情况下日志会过于分散不容易管理 不过nginx在1 7 1版本以后 可以使用Rsyslog来记录日志 配置过程如下 一 Nginx配置文件 该配置也可以实现将nginx日志通过rsyslog服务输送
  • PHP中的正规表达式

    PHP继承 NIX的一贯传统 完全支持正规表达式的处理 正规表达式提供了一种高级的 但不直观的字符串匹配和处理的方法 用过PERL的正规表达式的朋友都知道 正规表达式的功能非常强大 但学起来不是那么容易 比如 这段有效却难以理解的代码足够使
  • 大数据毕业设计 校园学生一卡通数据分析与可视化 - python

    文章目录 0 项目简介 任务 1数据导入与预处理 任务 1 1 探查数据质量并进行缺失值和异常值处理 1 1 2检查重复值 1 1 3数据内容总览 1 1 4数据分布总览 1 1 5消费金额和消费次数观察消费金额和消费次数的散点图 1 1
  • 企业微信 vue ios 出现 63002,INVALID SIGNATURE问题

    下面是官网的说法 可以先按下面的方法进行排查排查 概述 微信开放文档 1 确认签名算法正确 可用http mp weixin qq com debug cgi bin sandbox t jsapisign 页面工具进行校验 2 确认con
  • [创业之路-71] :创业思维与打工思维的区别

    其实打工思维和创业思维最核心的本质区别是你是否愿意去尝试 很多时候我打工的时候老板没发现我的潜质 所以我去创业了 这个没有 你打工的时候一定有一项极其长的长项 只不过当时你可能也没意识到 老板没意识到 所谓创业者和职场人没有本质的差异 但创
  • 如何使用Python的Pyecharts制作漂亮的Tree 树图?

    Pyecharts是一个基于Echarts的Python数据可视化库 可以很容易地生成各种漂亮的图表 本文介绍如何使用Pyecharts绘制Tree树图 安装Pyecharts 使用pip安装Pyecharts pip install py
  • 在IDE中使用Bito - 一个不需要VPN就可以使用的chatgpt

    文章目录 在IDE中使用Bito 什么是Bito 为什么要使用Bito Bito可以做什么 如何在IDE中安装Bito 使用Bito 在IDE中使用Bito 什么是Bito 用他自己的介绍就是 Bito s AI helps develop
  • fetch整个仓库 github_【每日github】B站开源的播放器、markdown插件等

    第15篇 1 Modernizr Modernizr Modernizr帮助我们检测浏览器是否实现了某个feature 如果实现了那么开发人员就可以充分利用这个feature做一些工作 反之没有实现开发人员也好提供一个fallback 所以
  • neo4j清空数据库

    版本为 neo4j community 4 4 6 使用py2neo删除 fimport py2neo from py2neo import Graph Node Relationship NodeMatcher g Graph http
  • Git(六):基本命令(2):复位、修改、分支合并与日志

    目录 9 reset 复位 9 1 描述 9 2 基本用法 9 2 1 回滚添加操作 9 2 2 回滚最近一次提交 9 2 3 回滚最近几次提交 9 2 4 回滚 pull 9 2 5 回滚 merge 9 2 6 区别 9 2 7 中断的
  • Velocity不用愁!Velocity系统的前端工程化之路

    Velocity是一个基于Java的Web页面模版引擎 十多年前 Velocity将Java代码从Web页面中分离出来 使得开发者能够并行网页开发和Java开发 随着十年前后端分离的浪潮涌动 回首再面对这些基于Velocity的旧系统 无论
  • 狂神说Linux学习笔记整理

    1 Linux简介 Linux 全称GNU Linux 是一种免费使用和自由传播的类UNIX操作系统 其内核由林纳斯 本纳第克特 托瓦兹于1991年10月5日首次发布 它主要受到Minix和Unix思想的启发 是一个基于POSIX的多用户
  • 最强Http缓存策略之强缓存和协商缓存的详解与应用实例

    HTTP缓存是指浏览器或者代理服务器将已经请求过的资源保存到本地 以便下次请求时能够直接从缓存中获取资源 从而减少网络请求次数 提高网页的加载速度和用户体验 缓存分为强缓存和协商缓存两种模式 一 强缓存 强缓存是指浏览器直接从本地缓存中获取
  • Mybatis Plus 入门 简单的CRUD 使用详解 条件查询 分页查询 DML操作 MP代码生成器

    Mybatis Plus入门 MP是 MybatisPlus 简称MP 是一个 Mybatis 的增强工具 在 Mybatis 的基础上只做增强不做改变 MP为简化开发 提高效率而生 它已经封装好了单表curd方法 我们直接调用这些方法就能
  • java引入bean代码_Spring学习笔记之通过Java代码装配Bean

    自建博客地址 https bytelife net 欢迎访问 本文为博客自动同步文章 为了更好的阅读体验 建议您移步至我的博客 虽然很多场景下可以使用组件扫描和自动装配来实现Spring的自动化配置 但有些时候自动化配置的方案是行不通的 因
  • java 图片验证码

    image jsp 主要是采用下面导入的几个包来绘制 验证码图片
  • 【activiti 入门】springboot 集成activiti6.0的demo

    环境 jdk 1 8 maven 3 0 IDEA插件之actiBPM springboot2 0 activiti6 0 mysql数据库 具体demo地址 https download csdn net download qq 3333