ワークフローアクティビティの一般的な方法

最近カプセル化されたワークフローで一般的に使用される方法を要約します。最初に一般的な概要を説明し、次にそれらについて詳しく説明します。

ビジネステーブルをワークフローにリンクする方法は次のとおりです。ビジネステーブルの一意の識別子がワークフローのテーブルに保存されるため、関連付けることができます。

一般的な方法:

package com.xxx.activiti.util;

import com.xxx.common.base.AjaxResult;
import org.activiti.engine.*;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.history.*;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.zip.ZipInputStream;


/**
 * 类描述:工作流相关公用类
 *
 * @author :carry
 * @version: 1.0  CreatedDate in  2019年06月24日
 * <p>
 * 修订历史: 日期			修订者		修订描述
 */
public class ActivitiUtil {

    private static ProcessEngine processEngine;

    static {
        //得到流程引擎
        processEngine = ProcessEngines.getDefaultProcessEngine();
    }

    private static ActivitiUtil activitiUtil = null;

    private ActivitiUtil() {
    }

    public static ActivitiUtil getInstance() {
        //多加一次判断,解决多线程问题
        if (activitiUtil == null) {
            synchronized (ActivitiUtil.class) {
                if (activitiUtil == null)
                    activitiUtil = new ActivitiUtil();
                return activitiUtil;
            }
        }
        return activitiUtil;
    }

    /**
     * @方法描述: 历史任务查询, 返回历史任务关联的业务key,用于查询业务表数据(组任务和个人任务)
     * user 用户(组)   assigneeOrGroup  个人任务、组任务区分标记   0 个人任务  1组任务
     * @return: String businessKeys
     * @Author: carry
     */
    public String historyTaskList(String user, String assigneeOrGroup) {
        String businessKeys = "";
        StringBuffer sbProcessId = new StringBuffer("");
        Set<String> processInstanceIds = new HashSet<String>();
        List<HistoricTaskInstance> list = null;
        HistoricTaskInstanceQuery historicTaskInstanceQuery = ProcessEngines.getDefaultProcessEngine().getHistoryService() // 历史任务Service
                .createHistoricTaskInstanceQuery(); // 创建历史任务实例查询
        if ("0".equals(assigneeOrGroup)) {
            list = historicTaskInstanceQuery
                    .taskAssignee(user) // 指定办理人
                    .finished() // 查询已经完成的任务
                    .list();
        } else {
            list = historicTaskInstanceQuery
                    .taskCandidateUser(user) // 指定办理人
                    .finished() // 查询已经完成的任务
                    .list();
        }

        for (HistoricTaskInstance t : list) {
            String processId = t.getProcessInstanceId();
            sbProcessId.append(processId).append(":");

            if (!processInstanceIds.contains(processId)) {
                processInstanceIds.add(processId);
            }
        }

        StringBuffer sbProcess = new StringBuffer("");

        //根据历史流程实例,获得业务key
        List<HistoricProcessInstance> historicProcessInstancelist = ProcessEngines.getDefaultProcessEngine().getHistoryService()
                .createHistoricProcessInstanceQuery()
                .processInstanceIds(processInstanceIds)
                .orderByProcessInstanceId().desc().list();
        for (HistoricProcessInstance p : historicProcessInstancelist) {
//            String instanceId = p.getSuperProcessInstanceId();
            String bizKey = p.getBusinessKey().split(":")[1];

            sbProcess.append(bizKey).append(",");
        }
        businessKeys = sbProcess.toString().substring(0, sbProcess.length() - 1).toString();

        return businessKeys;
    }

    /**
     * @方法描述: 部署流程
     * deploymentName 部署的流程名字  bpmnName 画图的bpmn名字  pngName 画图的png名字
     * @return: void
     * @Author: carry
     */
    public void deployeProcess(String deploymentName, String bpmnName, String pngName) throws Exception {
        //加载的那两个内容就是我们之前已经弄好的基础内容哦。
        //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取仓库服务的实例 addClasspathResource表示从类路径下加载资源文件,一次只能加载一个文件
        processEngine.getRepositoryService()
                .createDeployment()
                .name(deploymentName)//添加流程定义的名字,别名
                .addClasspathResource("templates/"+bpmnName)//添加流程定义的规则
                .addClasspathResource("templates/"+pngName)//添加流程定义的图片
                .deploy();//完成发布
    }


    /**
     * @方法描述: 部署流程
     * @return: void
     * @Author: carry
     */
    public void deployeProcess(File file, String processName) throws IOException {
        InputStream inputStream = new FileInputStream(file);
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        this.processEngine.getRepositoryService()
                .createDeployment()
                .name(processName)
                .addZipInputStream(zipInputStream)
                .deploy();
    }

    /**
     * @方法描述: 通过字节流来进行部署流程
     * @return: void
     * @Author: carry
     */
    public void deplyoProcessByInputSterm(InputStream io, String processName) {
        ZipInputStream zipInputStream = new ZipInputStream(io);
        this.processEngine.getRepositoryService()
                .createDeployment()
                .name(processName)
                .addZipInputStream(zipInputStream)
                .deploy();
    }

    /**
     * @方法描述: 通过key来启动流程
     * key 部署的key businessId  业务id  executeStr 执行人(组)的变量  userId执行人(组)
     * @return: String 返回流程实例id
     * @Author: carry
     */
    public String startProcessInstanceByKey(String key, String businessId, String executeStr, String userId) throws Exception {
        //流程key,可以bean指定和流程图一样,也可以写死,这里是waterPlanProcess
        String objId = key + ":" + businessId;//用于关联业务表
        Map<String, Object> vars = new HashMap<String, Object>();
        //此步骤的执行人,应为userid
        vars.put(executeStr, userId);//用于关联人员表
        vars.put("objId", objId);//用于关联业务表
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //启动流程是第二个参数就是表act_ru_execution中的BUSINESS_KEY字段,用于关联业务表  第三个是变量 variables(在act表里存放变量信息)
        ProcessInstance processInstance = processEngine.getRuntimeService()
                .startProcessInstanceByKey(key, objId, vars);  //画流程的时候自己定义的,最外面的地方

        return processInstance.getId();
    }

    /**
     * @方法描述: 获取待办事件 个人任务
     * @return: List<String> 返回业务表的主键集合
     * @Author: carry
     */
    public List<String> findPersonalTask(String assignee) throws Exception {
        List<String> list = this.findTask(assignee, "0");
        return list;
    }

    /**
     * @方法描述: 获取待办事件  组任务
     * @return: List<String> 返回业务表的主键集合
     * @Author: carry
     */
    public List<String> findMyGroupTask(String assignee) throws Exception {
        List<String> list = this.findTask(assignee, "1");

        return list;
    }

    /**
     * @方法描述: 获取待办事件  个人或者组任务
     * assignee 用户  flag 个人、组任务标记  0 个人 1组任务
     * @return: List<String> 返回业务表的主键集合
     * @Author: carry
     */
    public List<String> findTask(String assignee, String flag) throws Exception {
        List<String> list = new ArrayList<String>();
        List<Task> tasks = null;
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = ProcessEngines.getDefaultProcessEngine().getTaskService();
        TaskQuery taskQuery = processEngine.getTaskService()
                .createTaskQuery();

        if ("0".equals(flag)) {
            tasks = taskQuery.taskAssignee(assignee)//个人任务
                    .list();
        } else {
            tasks = taskQuery.taskCandidateUser(assignee)//组任务
                    .list();
        }

        for (Task task : tasks) {
            //获取业务表的变量,关联业务表取出业务表数据
            String objId = (String) taskService.getVariable(task.getId(), "objId");
            if (StringUtils.isNotBlank(objId)) {
                String planApplyId = objId.split(":")[1];
                list.add(planApplyId);
            }

        }

        return list;
    }

    /**
     * @方法描述: 获取待办事件 个人任务
     * taskId 任务id  userId 下一个执行人  nextUserMark 下一个执行人变量
     * @return: void
     * @Author: carry
     */
    public void complete(String taskId, String userId, String nextUserMark) throws Exception {
        Map<String, Object> variables = new HashMap<String, Object>();
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //不是最后环节则指定下一执行人,如果是最后的环节,则完成即可
        if (StringUtils.isNotBlank(userId)) {
            variables.put(nextUserMark, userId);
            processEngine.getTaskService()
                    .complete(taskId, variables); //查看act_ru_task表
        } else {
            processEngine.getTaskService()
                    .complete(taskId); //查看act_ru_task表
        }
    }

    /**
     * 历史活动查询
     * 比如这个流程实例什么时候开始的,什么时候结束的,以及中间具体的执行步骤,这时候,我们需要查询历史流程活动执行表,act_hi_actinst
     * 也就是此流程的流程图
     */
    public List<HistoricActivityInstance> historyActInstanceList(String instanceId) throws Exception {
        List<HistoricActivityInstance> list = processEngine.getHistoryService() // 历史任务Service
                .createHistoricActivityInstanceQuery() // 创建历史活动实例查询
                .processInstanceId(instanceId) // 指定流程实例id
                .finished() // 查询已经完成的任务
                .list();

        return list;
    }

    /**
     * @方法描述: 查询正在执行的任务办理人表
     * taskId 任务id
     * @return: void
     * @Author: carry
     */
    public List<IdentityLink> findRunPersonTask(String taskId) throws Exception {

        List<IdentityLink> list = ProcessEngines.getDefaultProcessEngine().getTaskService()
                .getIdentityLinksForTask(taskId);
        if (list != null && list.size() > 0) {
            for (IdentityLink identityLink : list) {
                System.out.println(identityLink.getTaskId() + "   " + identityLink.getType() + "   " + identityLink.getProcessInstanceId() + "   " + identityLink.getUserId());
            }
        }

        return list;

    }

    /**
     * @方法描述: 查询历史任务的办理人
     * processInstanceId   流程实例id
     * @return: List<HistoricIdentityLink> 历史任务办理人
     * @Author: carry
     */
    public List<HistoricIdentityLink> findHistoryPersonTask(String processInstanceId) throws Exception {
        List<HistoricIdentityLink> list = ProcessEngines.getDefaultProcessEngine().getHistoryService()
                .getHistoricIdentityLinksForProcessInstance(processInstanceId);
        if (list != null && list.size() > 0) {
            for (HistoricIdentityLink identityLink : list) {
                System.out.println(identityLink.getTaskId() + "   " + identityLink.getType() + "   " + identityLink.getProcessInstanceId() + "   " + identityLink.getUserId());
            }
        }

        return list;
    }

    /**
     * @方法描述: 拾取任务 组任务分配给个人任务 指定任务的办理人字段
     * userId 分配的人 taskId  任务id
     * @return: void
     * @Author: carry
     */
    public void claim(String userId, String taskId) throws  Exception{
        //可以是组任务的成员 也可以是其他人
        ProcessEngines.getDefaultProcessEngine().getTaskService()
                .claim(taskId, userId);
    }

    /**
     * @方法描述: 将个人任务回退到组任务 前提是之前一定是组任务
     * @return: void
     * @Author: carry
     */
    public void setAssignee(String taskId) {
        ProcessEngines.getDefaultProcessEngine().getTaskService()
                .setAssignee(taskId, null);
    }

    /**
     * @方法描述: 向组任务中添加成员
     * @return: void
     * @Author: carry
     */
    public void addGroupUser(String taskId, String userId) {
        ProcessEngines.getDefaultProcessEngine().getTaskService()
                .addCandidateUser(taskId, userId);
    }

    /**
     * @方法描述: 从组任务中删除成员
     * @return: void
     * @Author: carry
     */
    public void deleteGroupUser(String taskId, String userId) {
        ProcessEngines.getDefaultProcessEngine().getTaskService()
                .deleteCandidateUser(taskId, userId);
    }


    /**
     * @方法描述: 查询所有的部署流程,可以得到需要启动的流程id等流程信息
     * @return: java.util.List<org.activiti.engine.repository.Deployment>
     * @Author: carry
     */
    public List<Deployment> getAllDeplyoment() {

        List<Deployment> List = this.processEngine.getRepositoryService()
                .createDeploymentQuery()
                .orderByDeploymenTime()
                .desc()
                .list();

        return List;
    }

    /**
     * @方法描述: 查询所有的部署定义信息
     * @return: java.util.List<org.activiti.engine.repository.ProcessDefinition>
     * @Author: carry
     */
    public List<ProcessDefinition> getAllProcessInstance() {
        return this.processEngine.getRepositoryService()
                .createProcessDefinitionQuery()
                .orderByProcessDefinitionVersion()
                .desc()
                .list();
    }

    /**
     * @方法描述: 根据部署ID,来删除部署
     * @return: void
     * @Author: carry
     */
    public void deleteDeplyomentByPID(String deplyomenId) {
        this.processEngine.getRepositoryService()
                .deleteDeployment(deplyomenId, true);
    }

    /**
     * @方法描述: 查询某个部署流程的流程图
     * @return: java.io.InputStream
     * @Author: carry
     */
    public InputStream lookProcessPicture(String pid) {
        return this.processEngine.getRepositoryService()
                .getProcessDiagram(pid);
    }

    /**
     * @方法描述: 开启流程实例
     * @return: void
     * @Author: carry
     */
    public void startProceesInstance() {

    }

    /**
     * @方法描述: 根据TaskId,获取到当前的执行节点实例对象
     * @return: org.activiti.engine.impl.pvm.process.ActivityImpl
     * @Author: carry
     */
    public ActivityImpl getActivityImplByTaskId(String taskId) {
        //首先得到任务
        Task task = this.getTaskByTaskId(taskId);
        //其次,得到流程实例
        ProcessInstance processInstance = this.getProcessInstanceByTask(task);
        //再次,根据流程实例来获取到流程定义
        ProcessDefinitionEntity processDefinitionEntity = this.getProcessDefinitionEntityByTask(task);
        //再根据,流程定义,通过流程实例中来获取到activiti的ID,从而得到acitviImp
        ActivityImpl activity = processDefinitionEntity.findActivity(processInstance.getActivityId());
        return activity;
    }

    /**
     * @方法描述: 根据taskId,判断对应的流程实例是否结束
     * * 如果结束了,那么得到的流程实例就是返回一个null
     * * 否则就是返回对应的流程实例对象
     * * 当然也可以选择返回boolean类型的
     * @return: org.activiti.engine.runtime.ProcessInstance
     * @Author: carry
     */
    public ProcessInstance isFinishProcessInstancs(String taskId) {
        //1,先根据taskid,得到任务
        Task task = getTaskByTaskId(taskId);
        //2:完成当前任务
        finishCurrentTaskByTaskId(taskId);
        //3:得到当前任务对应得的流程实例对象
        ProcessInstance processInstance = getProcessInstanceByTask(task);
        return processInstance;
    }

    /**
     * @方法描述: 获取当前执行节点的所有出口
     * @return: java.util.List<org.activiti.engine.impl.pvm.PvmTransition>
     * @Author: carry
     */
    public List<PvmTransition> getCurrentActivitiImplPvm(ActivityImpl activity) {
        List<PvmTransition> outgoingTransitions = activity.getOutgoingTransitions();
        return outgoingTransitions;
    }

    /**
     * @方法描述: 根据taskId获取到task
     * @return: org.activiti.engine.task.Task
     * @Author: carry
     */
    public Task getTaskByTaskId(String taskId) {
        //得到当前的任务
        Task task = this.processEngine.getTaskService()
                .createTaskQuery()
                .taskId(taskId)
                .singleResult();
        return task;
    }

    /**
     * @方法描述: 根据Task中的流程实例的ID,来获取对应的流程实例
     * @return: org.activiti.engine.runtime.ProcessInstance
     * @Author: carry
     */
    public ProcessInstance getProcessInstanceByTask(Task task) {
        //得到当前任务的流程
        ProcessInstance processInstance = this.processEngine.getRuntimeService()
                .createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult();
        return processInstance;
    }

    /**
     * @方法描述: 根据Task来获取对应的流程定义信息
     * @return: org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity
     * @Author: carry
     */
    public ProcessDefinitionEntity getProcessDefinitionEntityByTask(Task task) {
        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) this.processEngine.getRepositoryService()
                .getProcessDefinition(task.getProcessDefinitionId());
        return processDefinitionEntity;
    }

    /**
     * @方法描述: 根据taskId获取到businesskey,这个值是管理activiti表和自己流程业务表的关键之处
     * @return: java.lang.String
     * @Author: carry
     */
    public String getBusinessKeyByTaskId(String taskId) {
        Task task = this.getTaskByTaskId(taskId);
        ProcessInstance processInstance = this.getProcessInstanceByTask(task);
        //返回值
        return processInstance.getBusinessKey();
    }

    /**
     * @方法描述: 根据taskId,完成任务
     * @return: void
     * @Author: carry
     */
    public void finishCurrentTaskByTaskId(String taskId) {
        this.processEngine.getTaskService().complete(taskId);
    }

    /**
     * @方法描述: 完成任务的同时,进行下一个节点的审批人员的信息的传递
     * @return: void
     * @Author: carry
     */
    public void finishCurrentTaskByTaskId(String taskId, Object object) {
        Map<String, Object> map = new HashMap<>();
        map.put("assigeUser", object);
        this.processEngine.getTaskService().complete(taskId, map);
    }

    /**
     * @方法描述: 驳回上一个节点
     * @return: void
     * @Author: carry
     */
    public void reject(String taskId) {

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        HistoryService historyService = processEngine.getHistoryService();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //String taskId = "120002";//这里根据你自己的taskid来写
        Map variables = new HashMap<>();

        //获取当前任务
        HistoricTaskInstance currTask = historyService.createHistoricTaskInstanceQuery()
                .taskId(taskId)
                .singleResult();
        //获取流程实例
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(currTask.getProcessInstanceId())
                .singleResult();
        //获取流程定义
        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition(currTask.getProcessDefinitionId());
        if (processDefinitionEntity == null) {
            System.out.println("不存在的流程定义。");

        }

        //获取当前activity
        ActivityImpl currActivity = ((ProcessDefinitionImpl) processDefinitionEntity)
                .findActivity(currTask.getTaskDefinitionKey());

        //获取当前任务流入
        List<PvmTransition> histTransitionList = currActivity
                .getIncomingTransitions();


        //清除当前活动出口
        List<PvmTransition> originPvmTransitionList = new ArrayList<PvmTransition>();
        List<PvmTransition> pvmTransitionList = currActivity.getOutgoingTransitions();
        for (PvmTransition pvmTransition : pvmTransitionList) {
            originPvmTransitionList.add(pvmTransition);
        }
        pvmTransitionList.clear();

        //查找上一个user task节点
        List<HistoricActivityInstance> historicActivityInstances = historyService
                .createHistoricActivityInstanceQuery().activityType("userTask")
                .processInstanceId(processInstance.getId())
                .finished()
                .orderByHistoricActivityInstanceEndTime().desc().list();

        TransitionImpl transitionImpl = null;
        if (historicActivityInstances.size() > 0) {
            ActivityImpl lastActivity = ((ProcessDefinitionImpl) processDefinitionEntity)
                    .findActivity(historicActivityInstances.get(0).getActivityId());
            //创建当前任务的新出口
            transitionImpl = currActivity.createOutgoingTransition(lastActivity.getId());
            transitionImpl.setDestination(lastActivity);
        } else {
            System.out.println("上级节点不存在。");
        }
        variables = processInstance.getProcessVariables();
        // 完成任务
        List<Task> tasks = taskService.createTaskQuery()
                .processInstanceId(processInstance.getId())
                .taskDefinitionKey(currTask.getTaskDefinitionKey()).list();
        for (Task task : tasks) {
            taskService.complete(task.getId(), variables);
            historyService.deleteHistoricTaskInstance(task.getId());
        }

        // 恢复方向
        currActivity.getOutgoingTransitions().remove(transitionImpl);

        for (PvmTransition pvmTransition : originPvmTransitionList) {
            pvmTransitionList.add(pvmTransition);
        }
    }

    /**
     * @方法描述: 判断流程是否结束
     * processInstanceId 流程实例id
     * @return: String  流程的名字
     * @Author: carry
     */
    public String getProcessState(String processInstanceId) {
        String processStr = "";
        RuntimeService runtimeService = ProcessEngines.getDefaultProcessEngine().getRuntimeService();
        // 查看流程是否结束
        ProcessInstance processInstance = runtimeService//正在执行的流程
                .createProcessInstanceQuery()//创建流程实例查询对象
                .processInstanceId(processInstanceId)
                .singleResult();
        //如果为空,流程已结束
        if (processInstance == null) {
            processStr = "审批完成";
        } else {
            processStr = processInstance.getActivityId();
        }

        return processStr;
    }


    /**
     * 根据taskId查找businessKey
     * 根据task -》 processInstance  -》 businessKey -》 业务表
     */
//    public String getBusinessKeyByTaskId(String taskId) {
//        RuntimeService runtimeService = processEngine.getRuntimeService();
//        //启动流程实例
//        runtimeService.startProcessInstanceByKey("流程key值");
//
//        Task task = this.processEngine
//                .getTaskService()
//                .createTaskQuery()
//                .taskId(taskId)
//                .singleResult();
//        ProcessInstance processInstance = runtimeService//正在执行的流程
//                .createProcessInstanceQuery()//创建流程实例查询对象
//                .processInstanceId(task.getProcessInstanceId())
//                .singleResult();
//        return pi.getBusinessKey();
//    }

    /**
     * @方法描述: 查询当前任务详情是,获得当前的task,通过task获得当前流程,通过当前流程获取当前流程的业务id,从而获得业务详情
     * @return: void
     * @Author: carry
     */
    public void getBusinessDetialByTaskId(String taskId) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //获取执行的service
        TaskService taskService = ProcessEngines.getDefaultProcessEngine().getTaskService();
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .singleResult();
        String processInstanceStr = task.getProcessInstanceId();
        ProcessInstance processInstance = runtimeService//正在执行的流程
                .createProcessInstanceQuery()//创建流程实例查询对象
                .processInstanceId(processInstanceStr)
                .singleResult();

        String businessKey = processInstance.getBusinessKey();
        if (StringUtils.isNotBlank(businessKey)) {
            String waterId = businessKey.split(":")[1];
        }
        //根绝id获取申请用水的详细信息


    }

    /**
     * @方法描述:
     * @return: java.util.List<org.activiti.engine.task.Task>
     * @Author: carry
     */
//    public List<Task> getTasksByAssignee(String userId){
//        List<Task> assigneeTasks =  this.getTaskService()
//                .createTaskQuery()
//                .taskAssignee(userId)//参与者,个人任务查询
//                .orderByTaskCreateTime()
//                .desc()
//                .list();
//
//        return assigneeTasks;
//    }

    /**
     * 查询当前登陆人的所有任务
     *
     * @param userId
     * @return
     */
    public List<Task> queryCurretUserTaskByAssignerr(String userId) {
        return this.processEngine.getTaskService()
                .createTaskQuery()
                .taskAssignee(userId)
                .orderByTaskCreateTime()
                .desc()
                .list();
    }


}

 

コントローラーインターフェイスレイヤー:

package com.xxx.activiti.controller;

import com.xx.activiti.domain.User;
import com.xx.activiti.util.ActivitiUtil;
import com.xx.common.base.AjaxResult;
import com.xx.common.base.BaseController;
import com.google.gson.JsonObject;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricIdentityLink;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
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.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 类描述:
 *
 * @author :carry
 * @version: 1.0  CreatedDate in  2019年06月24日
 * <p>
 * 修订历史: 日期			修订者		修订描述
 */
@RestController
@RequestMapping("activiti/flow")
public class ActivitiController extends BaseController {

    private static ActivitiUtil activitiUtil;

    static {
        activitiUtil = ActivitiUtil.getInstance();
    }


    /**
     * @方法描述: 1:部署一个Activiti流程, 流程的名字 deploymentName bpmnName文件名 pngName图片名字
     * @return: AjaxResult
     * @Author: carry
     */
    @PostMapping("/creatActivitiTask")
    public AjaxResult creatActivitiTask(@RequestBody String deploymentName, @RequestBody String bpmnName, @RequestBody String pngName) {
        try {
            activitiUtil.deployeProcess(deploymentName, bpmnName, pngName);

            return success();
        } catch (Exception e) {
            return error(e.getMessage());
        }

    }

    /**
     * @方法描述: 启动流程实例 根据key启动,返回流程实例id
     * @return: AjaxResult
     * @Author: carry
     */
    @GetMapping("startProcessInstanceByKey")
    public AjaxResult startProcessInstanceByKey(String key, String businessId, String executeStr, String userId) {
        String instanceId = "";
        try {
            instanceId = activitiUtil.startProcessInstanceByKey(key, businessId, executeStr, userId);
        } catch (Exception e) {
            return error(e.getMessage());
        }

        return success(instanceId);
    }

    /**
     * @方法描述:获取待办事件 个人任务
     * @return: AjaxResult
     * @Author: carry
     */
    @GetMapping("findPersonalTask")
    public AjaxResult findPersonalTask(String assignee) {
        try {
            List<String> planApplyIdList = activitiUtil.findPersonalTask(assignee);

            JSONArray jsonArray = JSONArray.fromObject(planApplyIdList);

            return successInfo(jsonArray);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }


    /**
     * @方法描述:获取待办事件 组任务
     * @return: AjaxResult
     * @Author: carry
     */
    @GetMapping("findMyGroupTask")
    public AjaxResult findMyGroupTask(String assignee) {
        try {
            List<String> planApplyIdList = activitiUtil.findMyGroupTask(assignee);
            JSONArray jsonArray = JSONArray.fromObject(planApplyIdList);

            return successInfo(jsonArray);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }


    /**
     * @方法描述: 完成操作,完成的同时指定一个环节的执行人,如果是最后的环节,则执行人不需要,同时指定执行人的变量,和画图的时候对应起来
     * @return: AjaxResult
     * @Author: carry
     */
    @PostMapping("/complete")
    public AjaxResult complete(@RequestBody JSONObject jsonObject) {
        String taskId = "";
        String userId = "";
        String nextUserMark = "";
        //因为是LinkedMultiValueMap类型 用下面的方法取出参数
        JSONArray jsonArray = JSONArray.fromObject(null==jsonObject.get("taskId")?"":jsonObject.get("taskId"));
        taskId = (String) (jsonArray.get(0) == null? "" : jsonArray.get(0));
        jsonArray = JSONArray.fromObject(jsonObject.get("userId"));
        userId = (String) (jsonArray.get(0) == null ? "" : jsonArray.get(0));
        jsonArray = JSONArray.fromObject(jsonObject.get("nextUserMark"));
        nextUserMark = (String) (jsonArray.get(0) == null ? "" : jsonArray.get(0));

        try {
            activitiUtil.complete(taskId, userId, nextUserMark);
            return success();
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * @方法描述: 历史任务查询, 返回历史任务关联的业务key,用于查询业务表数据
     * @return: AjaxResult
     * @Author: carry
     */
    @GetMapping("/historyTaskListByAssignee")
    public AjaxResult historyTaskListByAssignee(@RequestParam String assignee) {

        try {
            String businessKeys = activitiUtil.historyTaskList(assignee, "0");
            return success(businessKeys);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * @方法描述: 历史任务查询, 返回历史任务关联的业务key,用于查询业务表数据(组任务)
     * @return: AjaxResult
     * @Author: carry
     */
    @GetMapping("/historyTaskListByGroup")
    public AjaxResult historyTaskListByGroup(@RequestParam String assignee) {

        try {
            String businessKeys = activitiUtil.historyTaskList(assignee, "1");
            return success(businessKeys);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }


    /**
     * @方法描述: 根绝流程实例id获取当前任务进行到哪一步
     * @return: AjaxResult
     * @Author: carry
     */
    @GetMapping("/getProcessState")
    public AjaxResult getProcessState(@RequestParam String processInstanceId) {
        String processStr = "";
        try {
            processStr = activitiUtil.getProcessState(processInstanceId);

            return success(processStr);
        } catch (Exception e) {

            return error(e.getMessage());
        }
    }

    /**
     * @方法描述: * 历史活动查询
     * 比如这个流程实例什么时候开始的,什么时候结束的,以及中间具体的执行步骤,这时候,我们需要查询历史流程活动执行表,act_hi_actinst
     * 也就是此流程的流程图
     * @return: AjaxResult
     * @Author: carry
     */
    @GetMapping("/historyActInstanceList")
    public AjaxResult historyActInstanceList(@RequestParam String instanceId) {
        try {
            List<HistoricActivityInstance> list = activitiUtil.historyActInstanceList(instanceId);
            JSONArray jsonArray = JSONArray.fromObject(list);

            return successInfo(jsonArray);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }


    /**
     * @方法描述: 查询正在执行的任务办理人表
     * @return: void
     * @Author: carry
     */
    @GetMapping("/findRunPersonTask")
    public AjaxResult findRunPersonTask(@RequestParam String taskId) {
        try {
            List<IdentityLink> list = activitiUtil.findRunPersonTask(taskId);
            JSONArray jsonArray = JSONArray.fromObject(list);

            return successInfo(jsonArray);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * @方法描述: 查询历史任务的办理人
     * @return: void
     * @Author: carry
     */
    @GetMapping("/findHistoryPersonTask")
    public AjaxResult findHistoryPersonTask(@RequestParam String processInstanceId) {
        try {
            List<HistoricIdentityLink> list = activitiUtil.findHistoryPersonTask(processInstanceId);
            JSONArray jsonArray = JSONArray.fromObject(list);

            return successInfo(jsonArray);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * @方法描述: 拾取任务 组任务分配给个人任务 指定任务的办理人字段
     * @return: void
     * @Author: carry
     */
    @GetMapping("/claim")
    public AjaxResult claim(@RequestParam  String userId,@RequestParam  String taskId) {
        try {
            activitiUtil.claim(userId,taskId);

        }catch (Exception e){
            return error(e.getMessage());
        }

        return success();
    }


    /**
     * @方法描述: 驳回上一个节点
     * @return: void
     * @Author: carry
     */
    @PostMapping("/reject")
    public AjaxResult reject(@RequestBody JSONObject jsonObject) {
        try {
            String taskId = "";
            JSONArray jsonArray = JSONArray.fromObject(jsonObject.get("taskId"));
            taskId = (String) (jsonArray.get(0) == null ? "" : jsonArray.get(0));

            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            TaskService taskService = processEngine.getTaskService();
            HistoryService historyService = processEngine.getHistoryService();
            RuntimeService runtimeService = processEngine.getRuntimeService();
            RepositoryService repositoryService = processEngine.getRepositoryService();
            //String taskId = "120002";//这里根据你自己的taskid来写
            Map variables = new HashMap<>();

            //获取当前任务
            HistoricTaskInstance currTask = historyService.createHistoricTaskInstanceQuery()
                    .taskId(taskId)
                    .singleResult();
            //获取流程实例
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(currTask.getProcessInstanceId())
                    .singleResult();
            //获取流程定义
            ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                    .getDeployedProcessDefinition(currTask.getProcessDefinitionId());
            if (processDefinitionEntity == null) {
                System.out.println("不存在的流程定义。");
                return error("不存在的流程定义。");
            }

            //获取当前activity
            ActivityImpl currActivity = ((ProcessDefinitionImpl) processDefinitionEntity)
                    .findActivity(currTask.getTaskDefinitionKey());

            //获取当前任务流入
            List<PvmTransition> histTransitionList = currActivity
                    .getIncomingTransitions();


            //清除当前活动出口
            List<PvmTransition> originPvmTransitionList = new ArrayList<PvmTransition>();
            List<PvmTransition> pvmTransitionList = currActivity.getOutgoingTransitions();
            for (PvmTransition pvmTransition : pvmTransitionList) {
                originPvmTransitionList.add(pvmTransition);
            }
            pvmTransitionList.clear();

            //查找上一个user task节点
            List<HistoricActivityInstance> historicActivityInstances = historyService
                    .createHistoricActivityInstanceQuery().activityType("userTask")
                    .processInstanceId(processInstance.getId())
                    .finished()
                    .orderByHistoricActivityInstanceEndTime().desc().list();

            TransitionImpl transitionImpl = null;
            if (historicActivityInstances.size() > 0) {
                ActivityImpl lastActivity = ((ProcessDefinitionImpl) processDefinitionEntity)
                        .findActivity(historicActivityInstances.get(0).getActivityId());
                //创建当前任务的新出口
                transitionImpl = currActivity.createOutgoingTransition(lastActivity.getId());
                transitionImpl.setDestination(lastActivity);
            } else {
                System.out.println("上级节点不存在。");
                return error("上级节点不存在。");
            }
            variables = processInstance.getProcessVariables();
            // 完成任务
            List<Task> tasks = taskService.createTaskQuery()
                    .processInstanceId(processInstance.getId())
                    .taskDefinitionKey(currTask.getTaskDefinitionKey()).list();
            for (Task task : tasks) {
                taskService.complete(task.getId(), variables);
                historyService.deleteHistoricTaskInstance(task.getId());
            }

            // 恢复方向
            currActivity.getOutgoingTransitions().remove(transitionImpl);

            for (PvmTransition pvmTransition : originPvmTransitionList) {
                pvmTransitionList.add(pvmTransition);
            }
        } catch (Exception e) {
            return error(e.getMessage());
        }

        return success();
    }

    /**
     * @方法描述: 根据名称查询流程部署
     * @return: com.xx.common.base.AjaxResult
     * @Author: carry
     */
    @GetMapping("testQueryDeploymentByName")
    public AjaxResult testQueryDeploymentByName(String deploymentByName) {
        try {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            List<Deployment> deployments = processEngine.getRepositoryService()
                    .createDeploymentQuery()
                    .orderByDeploymenTime()//按照部署时间排序
                    .desc()//按照降序排序
                    .deploymentName(deploymentByName)
                    .list();
            for (Deployment deployment : deployments) {
                System.out.println(deployment.getId());
            }
            JSONArray jsonArray = JSONArray.fromObject(deployments);

            return successInfo(jsonArray);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }


    /**
     * @方法描述: 查询所有的部署流程
     * @return: com.xxx.common.base.AjaxResult
     * @Author: carry
     */
    @GetMapping("queryAllDeplyoment")
    public AjaxResult queryAllDeplyoment() {
        try {
            //得到流程引擎
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            List<Deployment> lists = processEngine.getRepositoryService()
                    .createDeploymentQuery()
                    .orderByDeploymenTime()//按照部署时间排序
                    .desc()//按照降序排序
                    .list();
            for (Deployment deployment : lists) {
                System.out.println(deployment.getId() + "    部署名称>>>>>>>>>>" + deployment.getName());
            }
            JSONArray jsonArray = JSONArray.fromObject(lists);

            return successInfo(jsonArray);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * @方法描述: 查询所有的流程定义
     * @return: void
     * @Author: carry
     */
    @GetMapping("testQueryAllPD")
    public AjaxResult testQueryAllPD() {
        try {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            List<ProcessDefinition> pdList = processEngine.getRepositoryService()
                    .createProcessDefinitionQuery()
                    .orderByProcessDefinitionVersion()
                    .desc()
                    .list();
            for (ProcessDefinition pd : pdList) {
                System.out.println(pd.getName());
            }
            JSONArray jsonArray = JSONArray.fromObject(pdList);

            return successInfo(jsonArray);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * @方法描述: 设置流程变量 如果变量是javaBean 则必须序列化
     * 当一个javabean(实现序列号)放置到流程变量中,要求javabean的属性不能再发生变化
     * 如果发生变化,再获取的时候,抛出异常
     * 解决方案:在对象中添加
     * 同时指定: private static final long serialVersionUID = 6757393795687480331
     * 流程变量的获取针对流程实例(即1个流程),每个流程实例获取的流程变量时不同的
     * 在taskService中使用任务ID,流程变量的名称,获取流程变量的值。
     * @return: void
     * @Author: carry
     */
    @PostMapping("setVariables")
    public void setVariables(@RequestBody JSONObject jsonObject) {
        //获取执行的service
        TaskService taskService = ProcessEngines.getDefaultProcessEngine().getTaskService();
        //指定办理人
        String assigneeUesr = "";
        //流程实例id
        String processInstanceId = "";

        JSONArray jsonArray = JSONArray.fromObject(jsonObject.get("assigneeUesr"));
        assigneeUesr = (String) (jsonArray.get(0) == null ? "" : jsonArray.get(0));
        jsonArray = JSONArray.fromObject(jsonObject.get("processInstanceId"));
        processInstanceId = (String) (jsonArray.get(0) == null ? "" : jsonArray.get(0));

        Task task = taskService.createTaskQuery()//创建任务查询
                .taskAssignee(assigneeUesr)//指定办理人
                .processInstanceId(processInstanceId)//流程Id
                .singleResult();
        //变量中存放javaBean  得首先序列化
        User person = new User();
        person.setId("112");
        person.setName("test");
        person.setAge("12");
        //设置变量
        taskService.setVariable(task.getId(), "xxx", person);

    }

    /**
     * @方法描述: 获取流程变量
     * @return: void
     * @Author: carry
     */
    @GetMapping("getVariables")
    public void getVariables(@RequestParam String assigneeUesr, @RequestParam String processInstanceId) {
        //获取执行的service
        TaskService taskService = ProcessEngines.getDefaultProcessEngine().getTaskService();

        Task task = taskService.createTaskQuery()//创建任务查询
                .taskAssignee(assigneeUesr)//指定办理人
                .processInstanceId(processInstanceId)//流程Id
                .singleResult();
        //获取变量
        User person = (User) taskService.getVariable(task.getId(), "xxx");
        System.out.println(person.getName());
    }


    /**
     * @方法描述: 根据taskId查找businessKey
     * 根据task -》 processInstance  -》 businessKey -》 业务表
     * @return: void
     * @Author: carry
     */
    @GetMapping("/getBusinessKeyByTaskId")
    public AjaxResult getBusinessKeyByTaskId(@RequestParam String TaskId) {
        String bId = "";
        try {
            ActivitiUtil activitiUtil = ActivitiUtil.getInstance();
            bId = activitiUtil.getBusinessKeyByTaskId(TaskId);
        } catch (Exception e) {
            return error(e.getMessage());
        }

        return success(bId);

    }


    /**
     * @方法描述: 删除部署的流程
     * @return: void
     * @Author: carry
     */
    @PostMapping("/deleteDeplyomentByPID")
    public AjaxResult deleteDeplyomentByPID(@RequestBody JSONObject jsonObject) {
        try {
            String deploymentId = "";
            JSONArray jsonArray = JSONArray.fromObject(jsonObject.get("deploymentId"));
            deploymentId = (String) (jsonArray.get(0) == null ? "" : jsonArray.get(0));
            //级联删除
            ProcessEngines.getDefaultProcessEngine().getRepositoryService()
                    .deleteDeployment(deploymentId, true);
        } catch (Exception e) {
            return error(e.getMessage());
        }

        return success();
    }
}

 

おすすめ

転載: blog.csdn.net/CarryBest/article/details/94630303