Activiti7工具类,常用方法封装

package com.dyttx.util;

import com.sun.istack.internal.NotNull;
import org.activiti.engine.*;
import org.activiti.engine.history.*;
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.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.*;
import java.util.zip.ZipInputStream;

/**
 * Activiti工具类
 *
 * @author zh
 */
@Component
public class Activiti7Util {
    private static final ProcessEngine PROCESS_ENGINE = ProcessEngines.getDefaultProcessEngine();

    /**
     * 资源管理类
     */
    private static final RepositoryService repositoryService = PROCESS_ENGINE.getRepositoryService();

    /**
     * 运行时管理类
     */
    private static final RuntimeService runtimeService = PROCESS_ENGINE.getRuntimeService();

    /**
     * 任务管理类
     */
    private static final TaskService taskService = PROCESS_ENGINE.getTaskService();

    /**
     * 历史数据管理类
     */
    private static final HistoryService historyService = PROCESS_ENGINE.getHistoryService();

    /**
     * 流程部署--将bpmn文件放在resources/bpmn 文件夹中进行部署
     *
     * @param name        部署时候可以起一个名字
     * @param bpmnName    bpmn文件名[带文件后缀 .bpmn]
     * @param bpmnImgName bpmn图片名[带图片后缀]
     */
    public static Map<String, Object> importProcessByResources(
            @NotNull String name, @NotNull String bpmnName, String bpmnImgName) {
        DeploymentBuilder deployment = repositoryService.createDeployment();
        deployment.name(name);
        deployment.addClasspathResource("bpmn/" + bpmnName);
        if (bpmnImgName != null) {
            deployment.addClasspathResource("bpmn/" + bpmnImgName);
        }
        // 执行部署
        Deployment deploy = deployment.deploy();
        return getMap(deploy);
    }

    /**
     * 流程部署-- 通过zip包进行bpmn文件部署
     *
     * @param zipPath: zip文件的路径 带[.zip] 后缀
     * @param name:    给部署起一个名字
     */
    public static Map<String, Object> importProcessByZip(String zipPath, String name)
            throws FileNotFoundException {
        FileInputStream fileInputStream = new FileInputStream(zipPath);
        ZipInputStream stream = new ZipInputStream(fileInputStream);
        Deployment deploy =
                repositoryService
                        .createDeployment()
                        .addZipInputStream(stream)
                        .name(name)
                        .deploy();
        return getMap(deploy);
    }

    private static Map<String, Object> getMap(Deployment deploy) {
        Map<String, Object> map = new HashMap<>(4);
        // 部署id
        map.put("deploymentId", deploy.getId());
        // 部署名称
        map.put("deploymentName", deploy.getName());
        // 部署时间
        map.put("deploymentTime", deploy.getDeploymentTime());
        return map;
    }

    /**
     * 查询流程定义集合【流程定义模板列表】
     *
     * @param key bpmn文件中的 processId processId = null 则查全部模板
     */
    public static List<Map<String, Object>> queryProcessDefinition(String key) {
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
        if (key != null) {
            // 根据指定key查出模板
            query.processDefinitionKey(key);
        }
        List<Map<String, Object>> result = new ArrayList<>();
        List<ProcessDefinition> list = query.list();
        for (ProcessDefinition processDefinition : list) {
            Map<String, Object> map = new HashMap<>(8);
            // 流程部署id
            map.put("deploymentId", processDefinition.getDeploymentId());
            // 流程定义id
            map.put("processDefinitionId", processDefinition.getId());
            // 流程定义key
            map.put("processDefinitionKey", processDefinition.getKey());
            // 流程定义名称
            map.put("processDefinitionName", processDefinition.getName());
            // 流程定义版本
            map.put("processDefinitionVersion", processDefinition.getVersion());
            result.add(map);
        }
        return result;
    }

    /**
     * 删除流程部署信息
     *
     * @param deploymentId 流程部署id
     * @param cascade:     true-连同已经存在的运行任务一起删除 false-不删除运行的任务
     * @author zh
     */
    public static void deleteProcessDefinition(String deploymentId, boolean cascade) {
        repositoryService.deleteDeployment(deploymentId, cascade);
    }

    /**
     * 根据指定的bpmn的 processId 下载已经存在数据库中的文件 需要 common-io.jar
     *
     * @param key          bpmn文件中的 processId
     * @param imgSavePath  需要把对应的图片文件保存的绝对路径【例:D:/bpmn/test-image.png】
     * @param bpmnSavePath 需要把对应的bpmn文件保存的绝对路径【例:D:/bpmn/test-bpmn.bpmn】
     */
    public static 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();
                }
            }
        }
    }

    /**
     * 开启一个流程实例
     *
     * @param processDefinitionId 流程定义id
     * @param businessKey         可以绑定一个自定义的业务id
     * @param params:             key:在bpmn文件中定义的变量占位符【例: ${userName}】 value:对应的占位值 【例: 小明】
     * @author zh
     */
    public static Map<String, Object> startProcessInstanceByKey(
            String processDefinitionId, String businessKey, Map<String, Object> params) {
        // 根据流程定义ID启动流程
        ProcessInstance one;
        if(StringUtils.isBlank(businessKey)){
            one = runtimeService.startProcessInstanceByKey(processDefinitionId, params);
        }else {
            one = runtimeService.startProcessInstanceByKey(processDefinitionId, businessKey, params);
        }
        Map<String, Object> map = new HashMap<>(4);
        // 流程定义id
        map.put("processDefinitionId", one.getProcessDefinitionId());
        // 流程实例id
        map.put("id", one.getId());
        // 当前活动id
        map.put("activityId", one.getActivityId());
        return map;
    }

    /**
     * 开启一个流程实例
     *
     * @param processDefinitionId 流程定义id
     * @param businessKey         可以绑定一个自定义的业务id
     * @author zh
     */
    public static Map<String, Object> startProcessInstanceByKey(
            String processDefinitionId, String businessKey) {
        // 根据流程定义ID启动流程
        ProcessInstance one;
        if(StringUtils.isBlank(businessKey)){
            one = runtimeService.startProcessInstanceByKey(processDefinitionId);
        }else {
            one = runtimeService.startProcessInstanceByKey(processDefinitionId, businessKey);
        }
        Map<String, Object> map = new HashMap<>(4);
        // 流程定义id
        map.put("processDefinitionId", one.getProcessDefinitionId());
        // 流程实例id
        map.put("id", one.getId());
        // 当前活动id
        map.put("activityId", one.getActivityId());
        return map;
    }

    /**
     * 【如果某个任务设置了负责人】则可通过该方法查询负责人【根据人名查出 自己有哪些任务待完成】
     *
     * @param key       bpmn里面的id值
     * @param assignee:负责人名
     * @author zh
     */
    public static List<Map<String, Object>> taskListByAssignee(String key, String assignee) {
        // 获取已经运行的任务列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(key).taskAssignee(assignee).list();
        return getMaps(taskList);
    }

    /**
     * 【如果某个任务设置了候选人】则可通过该方法查询候选人【根据人名查出 自己有哪些任务待完成】
     *
     * @param key                bpmn里面的id值
     * @param candidateUserName: 候选人名
     * @author zh
     */
    public static List<Map<String, Object>> taskListByCandidateUser(String key, String candidateUserName) {
        // 获取 已经运行的任务列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(key).taskCandidateUser(candidateUserName).list();
        return getMaps(taskList);
    }

    private static List<Map<String, Object>> getMaps(List<Task> taskList) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (Task task : taskList) {
            Map<String, Object> map = new HashMap<>(8);
            // 流程实例id
            map.put("processInstanceId", task.getProcessInstanceId());
            // 任务id
            map.put("id", task.getId());
            // 任务负责人
            map.put("assignee", task.getAssignee());
            // 任务名称
            map.put("name", task.getName());
            // 任务创建时间
            map.put("createTime", task.getCreateTime());
            result.add(map);
        }
        return result;
    }

    /**
     *  添加候选人
     *
     *@param taskId 任务id
     *@param userId 候选人
     *@author zh
     */
    public static void addGroupUser(String taskId, String userId){
        taskService.addCandidateUser(taskId, userId);
    }

    /**
     *  删除候选人
     *
     *@param taskId 任务id
     *@param userId 候选人
     *@author zh
     */
    public static void deleteGroupUser(String taskId, String userId){
        taskService.deleteCandidateUser(taskId, userId);
    }

    /**
     * 【如果某个任务设置了候选人】 某个负责人进行拾取任务【通过任务id和人名 开始拾取任务】
     *
     * @param taskId:           任务id
     * @param candidateUserName 候选人名
     * @return true-拾取成功 false=拾取失败
     * @author zh
     */
    public static boolean claimTask(String taskId, String candidateUserName) {
        // 根据条件 查出任务
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        // 能查到任务并且 传入参数也符合候选人 才能进行拾取
        if (task != null && isCandidate(taskId, candidateUserName)) {
            // 进行拾取操作 其实就是把指定任务的assignee设置对应的负责人名
            taskService.claim(task.getId(), candidateUserName);
            return true;
        }
        return false;
    }

    /**
     * 判断指定任务的候选人名单中是否有: candidateUserName
     *
     * @return true:是候选人 false:不是候选人
     */
    private static boolean isCandidate(String taskId, String candidateUserName) {
        for (IdentityLink link : taskService.getIdentityLinksForTask(taskId)) {
            if (candidateUserName.equals(link.getUserId())) {
                return true;
            }
        }
        return false;
    }

    /**
     * [描述]【如果某个任务设置了候选人】 负责人已经拾取某个任务以后 打算再归还回去
     *
     * @param taskId:           任务id
     * @param candidateUserName 候选人名
     * @author zh
     */
    public static 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);
            return true;
        }
        return false;
    }

    /**
     * 【如果某个任务设置了候选人】某个任务虽然是自己的 但是可以交给其他人进行完成
     *
     * @param taskId:           任务id
     * @param candidateUserName 候选人名
     * @param assigneeName:     交接人
     * @author zh
     */
    public static 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);
            return true;
        }
        return false;
    }

    /**
     * 根据名字 查询个人待执行的任务【已经把任务拾取了】【带分页】
     *
     * @param taskAssignName 人名【例:班长、经理、总经理等...】
     * @param key            bpmn文件中的processId
     * @param firstResult    当前页【默认从0开始】
     * @param maxResults     页长
     */
    public static List<Map<String, Object>> taskListByMy(
            String taskAssignName, String key, Integer firstResult, Integer maxResults) {
        List<Task> list =
                taskService
                        .createTaskQuery()
                        .processDefinitionKey(key)
                        .taskAssignee(taskAssignName)
                        .listPage(firstResult, maxResults);
        List<Map<String, Object>> result = new ArrayList<>();
        for (Task task : list) {
            Map<String, Object> taskMap = new HashMap<>(8);
            // 任务id
            taskMap.put("taskId", task.getId());
            // 任务名称
            taskMap.put("taskName", task.getName());
            // 创建时间
            taskMap.put("createTime", task.getCreateTime());
            // 任务负责人
            taskMap.put("taskAssignee", task.getAssignee());
            // 流程实例id
            taskMap.put("processInstanceId", task.getProcessInstanceId());
            result.add(taskMap);
        }
        return result;
    }

    /**
     * 完成个人任务
     *
     * @param taskAssignName: 任务代理人
     * @param taskId:         任务id params: 流程连接线上的变量 【例】假如流程线上面有一个变量名 ${audit=='通过'}
     *                        则调用时候:params.put("audit","通过"); 这里执行时,会判断控制线的变量 从而控制流程走向
     */
    public static boolean completeTask(String taskAssignName, String taskId, Map<String, Object> params) {
        try {
            Task task = taskService.createTaskQuery().taskId(taskId).taskAssignee(taskAssignName).singleResult();
            if (task == null) {
                // 说明根据任务id和人名 无法查到待办的指定任务
                return false;
            }
            taskService.complete(taskId, params);
            return true;
        } catch (ActivitiException ee) {
            ee.printStackTrace();
            //流程线上已经绑定变量了
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("【error】 执行报错: " + e.getMessage());
            return false;
        }
    }

    /**
     * 完成个人任务
     *
     * @param taskAssignName: 任务代理人
     * @param taskId:         任务id params: 流程连接线上的变量 【例】假如流程线上面有一个变量名 ${audit=='通过'}
     *                        则调用时候:params.put("audit","通过"); 这里执行时,会判断控制线的变量 从而控制流程走向
     */
    public static boolean completeTask(String taskAssignName, String taskId) {
        try {
            Task task = taskService.createTaskQuery().taskId(taskId).taskAssignee(taskAssignName).singleResult();
            if (task == null) {
                // 说明根据任务id和人名 无法查到待办的指定任务
                return false;
            }
            taskService.complete(taskId);
            return true;
        } catch (ActivitiException ee) {
            ee.printStackTrace();
            //流程线上已经绑定变量了
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("【error】 执行报错: " + e.getMessage());
            return false;
        }
    }

    /**
     * 先执行拾取任务,再进行完成任务。
     *
     * @author zh
     */
    public static boolean claimTaskAndCompleteTask(
            String taskId, String candidateUserName, Map<String, Object> params) {
        if (claimTask(taskId, candidateUserName)) {
            completeTask(candidateUserName, taskId, params);
            return true;
        }
        return false;
    }

    /**
     * 先执行拾取任务,再进行完成任务。
     *
     * @author zh
     */
    public static boolean claimTaskAndCompleteTask(
            String taskId, String candidateUserName) {
        if (claimTask(taskId, candidateUserName)) {
            completeTask(candidateUserName, taskId);
            return true;
        }
        return false;
    }

    /**
     * 根据相应的条件 查出历史的任务信息
     *
     * @param processDefinitionId: 流程定义id
     * @param processInstanceId:   流程实例id
     * @param assigneeName:        代理人名
     * @author zh
     */
    public static List<HistoricActivityInstance> 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);
        }
        return instanceQuery.list();
    }

    /**
     * 通过流程定义id --》 [挂起【暂停】] 或 [激活【启动】] 全部流程实例的执行
     *
     * @author zh
     */
    public static 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() + "已经操作成功【包括关联的所有实例】");
    }

    /**
     * 针对某一个流程实例进行【挂起】或【激活】操作
     *
     * @author zh
     */
    public static 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() + ",已经操作成功");
    }

}

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Activiti6 是一个流程引擎框架,它提供了一系列的工具类来简化流程定义和流程实例管理的操作。 其中,最常用工具类ProcessEngineFactory,它提供了获取 ProcessEngine 的方法,用于与 Activiti6 引擎进行交互。通过 ProcessEngineFactory,我们可以创建和销毁流程引擎实例,以及获取引擎的配置信息。 另外一个重要的工具类是 RepositoryService,它用于管理流程定义和流程部署的操作。通过 RepositoryService,我们可以进行流程定义的部署、更新和删除,以及查询已部署的流程定义信息。 TaskService 是用于处理流程中的任务的工具类。通过 TaskService,我们可以创建、完成和删除任务,以及查询任务的详细信息。 还有一个重要的工具类是 ManagementService,它提供了一系列的管理方法,用于执行底层的 Activiti6 引擎管理任务。例如,我们可以通过 ManagementService 来管理定时任务、任务持久化、流程实例的暂停和激活等。 除了上述的核心工具类Activiti6 还提供了其他一些工具类,如 HistoryService 用于查询历史数据,IdentityService 用于管理用户和组信息,以及 FormService 用于处理表单数据等。 总之,Activiti6 的工具类提供了丰富的方法和接口,可以方便地进行流程定义和流程实例管理的操作。使用这些工具类,我们可以轻松地构建和管理复杂的工作流程,提高工作效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周淮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值