栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【springboot】与activiti7进行整合的工具类

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【springboot】与activiti7进行整合的工具类

引入依赖
【注意:由于会自动引入mybatis依赖,所以如果引入后启动项目报错,可把mybatis依赖排除。】

        
            org.activiti
            activiti-spring-boot-starter
            7.0.0.Beta2
        
        
            org.activiti
            activiti-image-generator
            7.1.0.M6
        
        
            org.springframework.boot
            spring-boot-starter-jdbc
        
        
            mysql
            mysql-connector-java
            5.1.38
        
        

application.yml配置
【注意:activiti7配置信息,不要放在boostrap.yml 里面,我这边自测启动会报错。】

# Spring相关配置
spring:
  ##数据库连接信息
  datasource:
    # 数据源配置
    url: jdbc:mysql://127.0.0.1:3306/activiti2?useUnicode=true&characterEncoding=utf-8&useSSL=false&nullCatalogMeansCurrent=true
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    # 注册应用名
    name: actdemo
#    如果运行报错是 Could not set database schema on connection 可以先把activiti节点相关注解掉试试。
  activiti:
    # 自动建表  ACTIVITI 启用 activiti 必须要配置再 application.yml中
    database-schema: ACTIVITI
    database-schema-update: true
    history-level: full
    db-history-used: true
  jpa:
    show-sql: true

使用前说明:
1、我这里要提前说明,你需要懂得如何画流程图(epmn)文件,再用以下工具类会合适一些。因为你要懂得代理人(assign)、候选人(candidate)、流程变量、流程控制等名词。
2:
[流程定义]:就是导入了一个bpmn文件,算是定义了一个流程的结构。
[流程实例]:根据流程定义创建出一个真实的流程数据,比如某员工创建了请假条。
[任务]: 就是流程中的节点,该节点只允许存在一个负责人,但是可以存在多个候选人或者候选组。
【流程部署】:就是把你的bpmn文件解析存到数据库中,相当于新增了一条请假单模板。
【开启流程】:相当于你根据请假条模板创建了一条请假单,在创建方法( startProcessInstanceByKey )中就要指定接下来流程节点候选人(单个或多个)都有哪些。

举例:

工具类:

package com.example.util;

import com.sun.istack.internal.NotNull;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.*;
import org.activiti.engine.history.*;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntityImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Identitylink;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.el.PropertyNotFoundException;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipInputStream;


@Component
public class Activiti7Util {
    
    @Autowired
    private RepositoryService repositoryService;
    
    @Autowired
    private RuntimeService runtimeService;
    
    @Autowired
    private TaskService taskService;
    
    @Autowired
    private HistoryService historyService;
    
    @Autowired
    private ManagementService managementService;

    
    public Map importProcess(MultipartFile file ,MultipartFile imgFile, String name ,
                                    String bpmnResourceName , String imgResourceName) throws Exception{
        Resource resource = file.getResource();
        DeploymentBuilder name1 = repositoryService
                .createDeployment()
                .name(name);
        name1.addInputStream(bpmnResourceName, file.getInputStream());
        if (imgResourceName != null){
            name1.addInputStream(imgResourceName, imgFile.getInputStream());
        }
        Deployment deployment = name1.deploy();
        return getMap(deployment);
    }


    
    public Map importProcessByResources(@NotNull String name , @NotNull String bpmnName , String bpmnImgName){
        DeploymentBuilder deployment = repositoryService.createDeployment();
        deployment.name(name);
        deployment.addClasspathResource("processes/"+bpmnName);
        if (bpmnImgName != null){
            deployment.addClasspathResource("processes/"+bpmnImgName);
        }
        //执行部署
        Deployment deploy = deployment.deploy();
       return getMap(deploy);
    }

    
    public Map importProcessByZip(String zipPath , String name  ) throws FileNotFoundException {
        FileInputStream fileInputStream = new FileInputStream(zipPath);
        ZipInputStream stream = new ZipInputStream(fileInputStream);
        Deployment deploy = repositoryService.createDeployment()
                .addZipInputStream(stream)
                //act_re_procdef 表中的name
                .name(name)
                .deploy();
       return getMap(deploy);
    }

    private Map getMap(Deployment deploy) {
        Map map = new HashMap<>(3);
        System.out.println("部署ID:" + deploy.getId());
        System.out.println("部署Name:" + deploy.getName());
        System.out.println("部署时间:" + deploy.getDeploymentTime());
        map.put("deploymentId", deploy.getId());
        map.put("deploymentName", deploy.getName());
        map.put("deploymentTime", deploy.getDeploymentTime());
        return map;
    }


    
    public List> queryProcessDefinition(String key){
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
        if (key != null){
            //根据指定key查出模板
            query.processDefinitionKey(key);
        }

        List> result = new ArrayList<>();
        //List result = new ArrayList<>();
        List list = query.list();
        for (ProcessDefinition processDefinition : list) {
            System.out.println("流程定义id="+processDefinition.getId());
            System.out.println("流程定义名称="+processDefinition.getName());
            System.out.println("流程定义key="+processDefinition.getKey());
            System.out.println("流程定义版本="+processDefinition.getVersion());
            System.out.println("流程部署id="+processDefinition.getDeploymentId());
            Map map = new HashMap<>(5);
            map.put("deploymentId", processDefinition.getDeploymentId());
            map.put("processDefinitionId", processDefinition.getId());
            map.put("processDefinitionKey", processDefinition.getKey());
            map.put("processDefinitionName", processDefinition.getName());
            map.put("processDefinitionVersion", processDefinition.getVersion());
            result.add(map);
        }
        return result;
    }


    
    public void deleteProcessDefinition(String deploymentId , boolean cascade)   {
        //传入 流程部署id【如果已经存在运行任务,则这样的删除会报错】
        //repositoryService.deleteDeployment(deploymentId);
        //即便已经存在运行的任务,会执行级联删除操作【将运行的任务一起删除】
        repositoryService.deleteDeployment(deploymentId, cascade);
        System.out.println("删除流程部署信息成功");
    }


    
    public void downDeployment(String key ,String imgSavePath,String bpmnSavePath) {
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
            //根据指定key查出模板
            query.processDefinitionKey(key);
        for (ProcessDefinition processDefinition : query.list()) {
            //    拿到deploymentId
            String deploymentId = processDefinition.getDeploymentId();
            //图片目录和名称
            String pngName = processDefinition.getDiagramResourceName();
            InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId, pngName);
            String bpmnName = processDefinition.getResourceName();
            InputStream bpmnNameResourceAsStream = repositoryService.getResourceAsStream(deploymentId, bpmnName);
            File pngFile = new File(imgSavePath);
            File bpmnFile = new File(bpmnSavePath);
            FileOutputStream pngFileOutputStream = null;
            FileOutputStream bpmnFileOutputStream = null;
            try{
             pngFileOutputStream = new FileOutputStream(pngFile);
             bpmnFileOutputStream = new FileOutputStream(bpmnFile);
            IOUtils.copy(resourceAsStream, pngFileOutputStream);
            IOUtils.copy(bpmnNameResourceAsStream, bpmnFileOutputStream);
                }catch(Exception e){
                e.printStackTrace();
            }finally {
                //关闭流输入流
                try {
                    resourceAsStream.close();
                bpmnNameResourceAsStream.close();
                assert pngFileOutputStream != null;
                assert bpmnFileOutputStream != null;
                //关闭流输出流
                pngFileOutputStream.close();
                bpmnFileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
       System.out.println("操作成功");
    }

    
    public void startProcessInstanceByKey(String processDefinitionId, String businessKey , Map params ){
        // 根据流程定义ID启动流程
        ProcessInstance one = runtimeService.startProcessInstanceByKey(processDefinitionId, params);
        System.out.println("流程定义id:"+one.getProcessDefinitionId());
        System.out.println("流程实例id:"+one.getId());
        System.out.println("当前活动id:"+one.getActivityId());
        System.out.println("当前业务id:"+one.getBusinessKey());
        System.out.println(one.getProcessVariables());
        System.out.println("===============启动成功==================");
    }


    
    public List> taskListByCandidateUser( String key ,String candidateUserName){
        //获取 已经运行的任务列表
        List taskList = taskService.createTaskQuery().processDefinitionKey(key).list();
        //List result = new ArrayList<>();
        List> result = new ArrayList<>();
        // 根据传入的候选人名字 去查出哪些任务待办
        for (Task task : taskList) {
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("任务创建时间:" + task.getCreateTime());
            System.out.println("任务委派人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getProcessInstanceId());
            //根据任务id 查出相应的候选人列表
            List linksForTask = taskService.getIdentitylinksForTask(task.getId());
            for (Identitylink link : linksForTask) {
                System.out.println("候选人:"+link.getUserId());
                System.out.println("组id:"+link.getGroupId());
                System.out.println("候选类型:"+link.getType());
                //说明该任务的候选人之一 跟传入的参数相同 则该任务属于待办
                if (candidateUserName.equals(link.getUserId())){
                    List collect = linksForTask.stream().map(Identitylink::getUserId).collect(Collectors.toList());
                    Map map = new HashMap<>(8);
                    map.put("taskId", task.getId());
                    map.put("taskName", task.getName());
                    map.put("createTime", task.getCreateTime());
                    map.put("taskAssignee", task.getAssignee());
                    map.put("processInstanceId", task.getProcessInstanceId());
                    map.put("candidateList", collect);
                    map.put("candidateType", link.getType());
                    result.add(map);
                    break;
                }
            }
        }
        return result;
    }


    
    public boolean claimTask( String taskId , String candidateUserName ){
        //根据条件 查出任务
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                //由于这里 会调用Spring Security 框架 所有不采用这个方式
                //.taskCandidateUser(candidateUserName)
                .singleResult();
        //能查到任务并且 传入参数也符合候选人 才能进行拾取
        if (task != null && isCandidate(taskId, candidateUserName)){
            //进行拾取操作 其实就是把指定任务的assignee设置对应的负责人名
            taskService.claim(task.getId(), candidateUserName);
            System.out.println("拾取任务成功,往下可以继续完成改任务");
            return true;
        }
        System.out.println("【error】拾取任务失败,没有查到对应任务");
        return false;
    }

    
    private boolean isCandidate(String taskId , String candidateUserName ){
        for (Identitylink link : taskService.getIdentitylinksForTask(taskId)) {
            if (candidateUserName.equals(link.getUserId())){
                return true;
            }
        }
        return false;
    }

    
    public boolean claimTaskReturn( String taskId , String candidateUserName ){
        //根据条件 查出任务
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .taskCandidateUser(candidateUserName)
                .singleResult();
        if (task != null){
            //归还操作 其实就是把该任务的 assignee 设置成null
            taskService.setAssignee(task.getId(), null);
           System.out.println("归还任务成功");
           return true;
        }
        System.out.println("【error】归还任务失败,没有查到任务");
        return false;
    }


    
    public boolean taskHandover(String taskId , String candidateUserName, String  assigneeName  ){
        //根据条件 查出任务
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .taskCandidateUser(candidateUserName)
                .singleResult();
        //交接操作 这个任务是自己虽然是候选人 但是 可以直接把这个任务交接给别人进行完成
        if (task != null){
            taskService.setAssignee(task.getId(), assigneeName);
            System.out.println("交接成功");
            return true;
        }
        System.out.println("【error】交接失败,没有查到任务");
        return false;
    }


    
    public  List > taskListByMy(String taskAssignName , String key , Integer firstResult , Integer maxResults){
        List list = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee(taskAssignName)
                .listPage(firstResult, maxResults);
        List > result = new ArrayList<>();
        for (Task task : list) {
            System.out.println("流程定义id="+task.getProcessDefinitionId());
            System.out.println("任务id="+task.getId());
            System.out.println("任务负责人="+task.getAssignee());
            System.out.println("任务名称="+task.getName());
            Map taskMap = new HashMap<>(5);
            taskMap.put("taskId", task.getId());
            taskMap.put("taskName", task.getName());
            taskMap.put("createTime", task.getCreateTime());
            taskMap.put("taskAssignee", task.getAssignee());
            taskMap.put("processInstanceId", task.getProcessInstanceId());
            result.add(taskMap);
        }
        return result;
    }


    
    public boolean completeTask( String taskAssignName , String taskId , Map params){
        try{
            Task task = taskService.createTaskQuery()
                    .taskId(taskId)
                    .taskAssignee(taskAssignName)
                    .singleResult();
            if (task == null){
                System.out.println("【error】 说明根据任务id和人名 无法查到待办的指定任务");
                return false;
            }
            taskService.complete(taskId ,params);
            System.out.println("任务完成成功");
            return true;
            }catch(ActivitiException ee){
            ee.printStackTrace();
            System.out.println( "【error】流程线上已经绑定变量了:"+ee.getMessage());
            return false;
            }catch(Exception e){
            e.printStackTrace();
            System.out.println("【error】 执行报错: "+e.getMessage());
             return false;
        }
    }

    
    public boolean claimTaskAndCompleteTask(String taskId, String candidateUserName , Map params){
        if (this.claimTask(taskId,candidateUserName)){
            this.completeTask(candidateUserName, taskId,params);
            return true;
        };
        System.out.println( "【error】没有可以拾取的任务");
        return false;
    }


    
    public  List historicActivityInstanceList(String processDefinitionId , String processInstanceId,String assigneeName ){
        //例子:查询 act_hi_actinst 表中数据
        HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
        if (processDefinitionId != null){
            //查询条件: 根据流程定义id 拿到数据
            instanceQuery.processDefinitionId(processDefinitionId);
        }
        if (processInstanceId != null){
            //查询条件: 根据流程实例id 拿到数据
            instanceQuery.processInstanceId(processInstanceId);
        }
        if (assigneeName != null){
            instanceQuery.taskAssignee(assigneeName);
        }
        List list = instanceQuery.list();
        //总数
        long count = instanceQuery.count();
        for (HistoricActivityInstance instance : list) {
            System.out.println(instance.toString());
        }
        return list;
    }


    
    public void suspendAllProcessInstance( String key ){
        //通过指定的key 获取单个流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).singleResult();
        //判断指定的流程定义 是否挂起 true=挂起  false=激活
        boolean suspended = processDefinition.isSuspended();
        //拿到流程定义id
        String processDefinitionId = processDefinition.getId();
        if (suspended){
            //说明原来是挂起的 则可以对流程定义和旗下的所有流程实例进行激活操作
            //    参数说明:processDefinitionId=流程定义id 、 activateProcessInstances=挂起或者激活、activationDate=执行事件
            repositoryService.activateProcessDefinitionById(processDefinitionId, true, null);
            System.out.println("对流程定义id为"+processDefinitionId+",进行[激活]操作");
        }else{
            // 说明原来是激活的 则可以对流程定义和旗下的所有流程实例进行挂起操作
            repositoryService.activateProcessDefinitionById(processDefinitionId, false, null);
            System.out.println("对流程定义id为"+processDefinitionId+",进行[挂起]操作");
        }
       System.out.println("流程定义"+processDefinition.getName()+"已经操作成功【包括关联的所有实例】");
    }


    
    public void suspendProcessInstanceByProcessInstanceId( String processInstanceId ){
        ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        //原来是挂起的
        if (instance.isSuspended()){
            runtimeService.activateProcessInstanceById(instance.getId());
            System.out.println("流程实例id="+instance.getId()+",已激活");
        }else{
            runtimeService.suspendProcessInstanceById(instance.getId());
            System.out.println("流程实例id="+instance.getId()+",已挂起");
        }
        System.out.println("单个流程实例:"+instance.getName()+",已经操作成功");
    }


    
    public void xx(@NotNull String processInstanceId, HttpServletResponse response)
            throws IOException {
        ExecutionEntity pi = (ExecutionEntity) runtimeService
                .createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        if (pi == null) {
        //pi 如果为null  说明指定实例已经完成。可以从历史汇总查出来。
            xx2(processInstanceId, response);
            return;
        }
        ProcessDefinitionEntity pde = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition(pi.getProcessDefinitionId());
        List highLightedActivities = getHighLightedActivities(processInstanceId);
        List highLightedFlows = runtimeService.getActiveActivityIds(processInstanceId);
        if (pde != null && pde.isGraphicalNotationDefined()) {
            BpmnModel bpmnModel = repositoryService.getBpmnModel(pde.getId());
            ProcessDiagramGenerator ge = new DefaultProcessDiagramGenerator();
            InputStream resource = getResource(highLightedActivities, highLightedFlows, bpmnModel, ge);
            int len = 0;
            byte[] b = new byte[1024];
            while ((len = resource.read(b, 0, 1024)) != -1) {
                response.getOutputStream().write(b, 0, len);
            }
        } else {
            throw new ActivitiException("Process instance with id "
                    + processInstanceId + " has no graphic description");
        }
    }

    
    private void xx2(String processInstanceId, HttpServletResponse response)throws IOException {
        HistoricProcessInstanceEntityImpl pi = (HistoricProcessInstanceEntityImpl)historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        if (pi == null){
            throw new ActivitiObjectNotFoundException(
                    "Process instance with id" + processInstanceId
                            + " could not be found", ProcessInstance.class);
        }
        ProcessDefinitionEntity pde = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition(pi.getProcessDefinitionId());
        List highLightedActivities = getHighLightedActivities(processInstanceId);
        if (pde != null && pde.isGraphicalNotationDefined()) {
            BpmnModel bpmnModel = repositoryService.getBpmnModel(pde.getId());
            ProcessDiagramGenerator ge = new DefaultProcessDiagramGenerator();
            List highLightedFlows = historyService.getHistoricIdentitylinksForProcessInstance(processInstanceId).stream()
                                    .map(HistoricIdentitylink::getTaskId).collect(Collectors.toList());
            InputStream resource = getResource(highLightedActivities, highLightedFlows, bpmnModel, ge);
            int len = 0;
            byte[] b = new byte[1024];
            while ((len = resource.read(b, 0, 1024)) != -1) {
                response.getOutputStream().write(b, 0, len);
            }
        } else {
            throw new ActivitiException("Process instance with id "
                    + processInstanceId + " has no graphic description");
        }
    }


    private List getHighLightedActivities(@NotNull String processInstanceId) {
        List highLightedActivitList = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).list();
        return highLightedActivitList.stream().map(HistoricActivityInstance::getActivityId).collect(Collectors.toList());
    }
    private InputStream getResource(List highLightedActivities, List highLightedFlows, BpmnModel bpmnModel, ProcessDiagramGenerator ge) {
        return ge.generateDiagram(bpmnModel, highLightedActivities,
                highLightedFlows,
                "宋体", "宋体", null, false);
    }

}

整个工具类有很多方法,但用得到的基本就是一部分:

@Controller
@RequestMapping("/act")
public class ActivityController {
    @Resource
    private Activiti7Util util;

    
    public static String bpmnProcessId = "Process_test";
    public static Map map = new HashMap<>();
    public static String assigneeName = "小明";

    List banzhangList = Arrays.asList("小黑班长","小白班长");
    List teacherList = Arrays.asList("老师A","老师B");
    List fuList = Arrays.asList("小粉副校长","小红副校长");
    List zhengList = Arrays.asList("小绿正校长","小蓝正校长");


    
   @RequestMapping("/bushu")
   @ResponseBody
   public Object bushu( @RequestParam Map params ){
       String name = "请假条";
       String bpmnName = "qingjia.bpmn";
       String bpmnImgName = "qingjia.svg";
       Map deployment = util.importProcessByResources(name, bpmnName, bpmnImgName);
       return deployment;
   }

    
    @RequestMapping("/kaishi")
    @ResponseBody
    public Object kaishi(String applyUserName){

        Map params = new HashMap<>();
        params.put("userName", applyUserName);
        params.put("banzhangList", banzhangList);
        params.put("teacherList", teacherList);
        params.put("fuList", fuList);
        params.put("zhengList", zhengList);

        //TODO 这里可加入业务表 并获得新增的业务id  传入 businessKey
        String businessKey = "这里是业务id";
        util.startProcessInstanceByKey(bpmnProcessId, businessKey, params);
        List> tasks = util.taskListByMy(assigneeName, bpmnProcessId, 0, 100);
        for (Map task : tasks) {
            String taskId = (String) task.get("taskId");
            //开始一个流程 就先完成自己的任务
            util.completeTask(assigneeName , taskId,null);
        }
        return "success";
    }

    
    @RequestMapping("/shiquList")
    @ResponseBody
    public Object shiquList( @RequestParam Map params ){
        String candidateUserName = "SYSTEM";
        return util.taskListByCandidateUser(bpmnProcessId, candidateUserName);
    }



    
    @RequestMapping("/tongguo")
    @ResponseBody
    public Object tongguo( @RequestParam Map params ){
        String taskId = "";
        params.put("roomCheck", 1);
        String candidateUserName = "SYSTEM";
        return  util.claimTaskAndCompleteTask(candidateUserName, taskId, params);
    }
    
    @RequestMapping("/lishi")
    @ResponseBody
    public Object historicActivityInstanceList( @RequestParam Map params ){
        String definitionId = "resourcesOccupy3:2:bb047ad5-9ecd-11ec-a39b-080058000005";
        String instanceId = null;
        String assigneeName = "";
        return  util.historicActivityInstanceList(definitionId, instanceId , assigneeName);
    }

}

demo地址

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/768958.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号