Activiti常用方法封装

package com.bangand.safety.workflow.service;

import com.bangand.safety.workflow.entity.ProcessHistory;
import com.bangand.safety.workflow.entity.ProcessInstanceAtt;
import com.bangand.safety.workflow.exception.ProcessNotFoundException;
import com.bangand.safety.workflow.utils.ActivitiUtils;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.HistoryService;
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.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author jiangtao
 * @create 2022/9/19 9:55
 */
@Component
@Slf4j
public class ActivitiService {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private HistoryService historyService;

    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 根据定义的的流程key启动流程
     *
     * @param processDefinitionKey 定义的流程key
     */
    public void startProcess(String processDefinitionKey, String businessKey) {
        if (StringUtils.isBlank(processDefinitionKey)) {
            throw new RuntimeException("processDefinitionKey不能为空!");
        }
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey(processDefinitionKey, businessKey);
        log.info("==========================");
        if (processInstance != null) {
            log.info("流程启动成功!");
            log.info("getProcessDefinitionKey:" + processInstance.getProcessDefinitionKey());
            log.info("processInstanceId:" + processInstance.getId());
        } else {
            log.error("流程启动失败!");
        }
        log.info("==========================");
    }

    /**
     * 根据定义的的流程key启动流程
     *
     * @param processDefinitionKey
     * @param businessKey
     * @param map                  全局变量
     */
    public void startProcess(String processDefinitionKey, String businessKey, Map map) {
        if (StringUtils.isBlank(processDefinitionKey)) {
            throw new RuntimeException("processDefinitionKey不能为空!");
        }
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey(processDefinitionKey, businessKey, map);
        log.info("==========================");
        if (processInstance != null) {
            log.info("流程启动成功!");
            log.info("getProcessDefinitionKey:" + processInstance.getProcessDefinitionKey());
            log.info("processInstanceId:" + processInstance.getId());
        } else {
            log.error("流程启动失败!");
        }
        log.info("==========================");
    }

    /**
     * 获取该节点所在流程的businessKey
     *
     * @param taskId
     * @return
     */
    public String queryBusinessByTaskId(String taskId) {
        // 获取当前节点所在流程
        String processInstanceId = queryProcessInstanceIdByTaskId(taskId);
        return getBusinessKeyByTask(processInstanceId);
    }

    /**
     * 完成个人任务
     *
     * @param businessKey
     */
    public void complete(String businessKey, String comment) {
        if (StringUtils.isBlank(businessKey)) {
            throw new RuntimeException("businessKey不能为空!");
        }
        Task task = taskService.createTaskQuery()
//                .taskId(taskId)
                .processInstanceBusinessKey(businessKey)
                .singleResult();
        if (StringUtils.isBlank(comment)) {
            comment = "同意";
        }
        if (task != null) {
            // 添加意见
            taskService.addComment(task.getId(), task.getProcessInstanceId(), comment);
            taskService.complete(task.getId());
            log.info("完成任务成功!");
        }
    }

    /**
     * 根据用户查询任务
     *
     * @param name
     * @return
     */
    public List<ProcessInstanceAtt> queryTaskByUser(String name) {
        if (StringUtils.isBlank(name)) {
            throw new RuntimeException("name不能为空!");
        }
        List<Task> list = taskService.createTaskQuery()
                .taskAssignee(name)
                .list();
        List<ProcessInstanceAtt> vars = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Task task = list.get(i);
            String processInstanceId = task.getProcessInstanceId();
            // 业务key  可能作业申请编号  作业票ticketsId
            String businessKey = getBusinessKeyByTask(processInstanceId);
            ProcessInstanceAtt processInstanceAtt = ProcessInstanceAtt.builder()
                    .processInstanceId(processInstanceId)
                    .assignee(task.getAssignee())
                    .executionId(task.getExecutionId())
                    .taskId(task.getId())
                    .businessKey(businessKey)
                    .build();
            vars.add(processInstanceAtt);
        }
        return vars;
    }

    /**
     * 获取当前任务所在流程的businessKey
     *
     * @param processInstanceId 流程Id
     * @return
     */
    private String getBusinessKeyByTask(String processInstanceId) {
        if (StringUtils.isBlank(processInstanceId)) {
            throw new RuntimeException("processInstanceId不能为空!");
        }
        return historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult()
                .getBusinessKey();
        // 该方式只能获取正在执行的流程
//        return runtimeService.createProcessInstanceQuery()
//                .processInstanceId(processInstanceId)
//                .singleResult()
//                .getBusinessKey();
    }

    /**
     * 根据taskId获取processInstanceId
     *
     * @param taskId
     * @return
     */
    private String queryProcessInstanceIdByTaskId(String taskId) {
        if (StringUtils.isBlank(taskId)) {
            throw new RuntimeException("taskId不能为空!");
        }
        return historyService.createHistoricTaskInstanceQuery()
                .taskId(taskId)
                .singleResult()
                .getProcessInstanceId();
    }

    /**
     * 根据businessKey获取processInstanceId
     *
     * @param businessKey
     * @return
     */
    private String queryProcessInstanceIdByBusinessKey(String businessKey) {
        if (StringUtils.isBlank(businessKey)) {
            throw new RuntimeException("businessKey不能为空!");
        }
        return historyService.createHistoricProcessInstanceQuery()
                .processInstanceBusinessKey(businessKey)
                .singleResult()
                .getId();
    }

    /**
     * 根据候选人查询任务
     *
     * @param candidateUser
     */
    public List<ProcessInstanceAtt> queryTaskByCandidateUser(String candidateUser) {
        if (StringUtils.isBlank(candidateUser)) {
            throw new RuntimeException("candidateUser不能为空!");
        }
        List<Task> list = taskService.createTaskQuery()
                .taskCandidateUser(candidateUser)
                .list();
        List<ProcessInstanceAtt> tasks = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Task task = list.get(i);
            String processInstanceId = task.getProcessInstanceId();
            // 业务key  可能作业申请编号  作业票ticketsId
            String businessKey = getBusinessKeyByTask(processInstanceId);
            ProcessInstanceAtt processInstanceAtt = ProcessInstanceAtt.builder()
                    .processInstanceId(processInstanceId)
                    .assignee(task.getAssignee())
                    .executionId(task.getExecutionId())
                    .taskId(task.getId())
                    .businessKey(businessKey)
                    .taskName(task.getName())
                    .id(task.getTaskDefinitionKey())
                    .build();
            tasks.add(processInstanceAtt);
        }
        return tasks;
    }

    /**
     * 候选人申请任务
     *
     * @param businessKey
     */
    public boolean requestTask(String businessKey) {
        // 获取当前用户
        String candidateUser = ActivitiUtils.getActivitiUser();
        if (StringUtils.isBlank(candidateUser)) {
            throw new RuntimeException("candidateUser不能为空!");
        }
        if (StringUtils.isBlank(businessKey)) {
            throw new RuntimeException("businessKey不能为空!");
        }
        Task task = taskService.createTaskQuery()
                .taskCandidateUser(candidateUser)
//                .taskId(taskId)
                .processInstanceBusinessKey(businessKey)
                .singleResult();
        if (task != null) {
            taskService.claim(task.getId(), candidateUser);
            log.info(candidateUser + "申领到了任务!");
            return true;
        }
        return false;
    }

    /**
     * 放弃申领到的任务
     *
     * @param businessKey
     */
    public void rejectTask(String businessKey) {
        // 获取当前用户
        String assignee = ActivitiUtils.getActivitiUser();
        if (StringUtils.isBlank(businessKey)) {
            throw new RuntimeException("businessKey不能为空!");
        }
        if (StringUtils.isBlank(assignee)) {
            throw new RuntimeException("assignee不能为空!");

        }
        Task task = taskService.createTaskQuery()
                .taskAssignee(assignee)
//                .taskId(taskId)
                .processInstanceBusinessKey(businessKey)
                .singleResult();
        if (task != null) {
            taskService.setAssignee(task.getId(), null);
            log.info(assignee + "放弃了任务!");
        }
    }

    /**
     * 根据businessKey结束流程,该操作会将所有的变量删除并且结束流程,适用于所有流程
     *
     * @param businessKey
     * @param endReason   结束该流程的原因
     */
    public void endProcess(String businessKey, String endReason) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
//                .processInstanceId(processInstanceId)
                .processInstanceBusinessKey(businessKey)
                .singleResult();
        if (processInstance != null) {
            runtimeService.deleteProcessInstance(processInstance.getId(), endReason);
            log.info("流程删除成功!");
        } else {
            throw new ProcessNotFoundException("流程不存在!");
        }
    }


    /**
     * 判断流程是否结束
     *
     * @param businessKey
     */
    public boolean isEnd(String businessKey) {
        HistoricProcessInstance historicProcessInstance = historyService
                .createHistoricProcessInstanceQuery()
//                .processInstanceId(processInstanceId)
                .processInstanceBusinessKey(businessKey)
                .singleResult();
        if (historicProcessInstance != null) {
            if (historicProcessInstance.getEndTime() != null) {
                log.info("流程已结束!");
                return true;
            } else {
                log.info("流程未结束!");
                return false;
            }
        } else {
            throw new ProcessNotFoundException("流程不存在!");
        }
    }


    /**
     * 当前任务节点直接走向结束,结束该流程,只适用于单线或者使用了只是用了排他网关的流程,建议使用@endProcess()
     *
     * @param businessKey
     */
    public void endTask(String businessKey) {
        if (StringUtils.isBlank(businessKey)) {
            throw new RuntimeException("businessKey不能为空!");
        }
        //  当前任务
        // todo 如果并行网关或包含网关,由于查询出来的结果可能是多个,会报错
        Task task = taskService.createTaskQuery()
//                .taskId(taskId)
                .processInstanceBusinessKey(businessKey)
                .singleResult();

        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        List<EndEvent> endEventList = bpmnModel.getMainProcess().findFlowElementsOfType(EndEvent.class);

        FlowNode endFlowNode = endEventList.get(0);
        FlowNode currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(task.getTaskDefinitionKey());

        //  临时保存当前活动的原始方向
        List originalSequenceFlowList = new ArrayList<>();
        originalSequenceFlowList.addAll(currentFlowNode.getOutgoingFlows());
        //  清理活动方向
        currentFlowNode.getOutgoingFlows().clear();

        //  建立新方向
        SequenceFlow newSequenceFlow = new SequenceFlow();
        newSequenceFlow.setId("newSequenceFlowId");
        newSequenceFlow.setSourceFlowElement(currentFlowNode);
        newSequenceFlow.setTargetFlowElement(endFlowNode);
        List newSequenceFlowList = new ArrayList<>();
        newSequenceFlowList.add(newSequenceFlow);
        //  当前节点指向新的方向
        currentFlowNode.setOutgoingFlows(newSequenceFlowList);

        //  完成当前任务
        taskService.complete(task.getId());
        log.info("流程已结束!");

        //  可以不用恢复原始方向,不影响其它的流程
//        currentFlowNode.setOutgoingFlows(originalSequenceFlowList);
    }


    /**
     * 查询历史审批状态
     *
     * @param businessKey
     */
    public List<ProcessHistory> queryHistory(String businessKey) {
        if (StringUtils.isBlank(businessKey)) {
            throw new RuntimeException("businessKey不能为空!");
        }
        String processInstanceId = queryProcessInstanceIdByBusinessKey(businessKey);
        // 历史节点
        List<HistoricActivityInstance> list = historyService
                .createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .orderByHistoricActivityInstanceStartTime()
                .asc()
                .finished()
                .list()
                .stream()
                // 去掉网关信息
                .filter(item -> !StringUtils.containsAny(item.getActivityType(), "inclusiveGateway", "parallelGateway", "exclusiveGateway"))
                .collect(Collectors.toList());
        List<ProcessHistory> resultList = new ArrayList<>();
        // 历史变量
        for (int i = 0; i < list.size(); i++) {
            HistoricActivityInstance historicActivityInstance = list.get(i);
            String taskId = historicActivityInstance.getTaskId();
            List<Comment> taskComments = taskService.getTaskComments(taskId);
            // 获取审批意见
            List<String> comments = taskComments.stream().map(item -> item.getFullMessage()).collect(Collectors.toList());
            ProcessHistory processHistory = ProcessHistory.builder()
                    .assignee(historicActivityInstance.getAssignee()) // 审批人
                    .taskName(historicActivityInstance.getActivityName()) // 任务节点名称
                    .startTime(format.format(historicActivityInstance.getStartTime())) // 节点开始时间
                    .endTime(format.format(historicActivityInstance.getEndTime())) // 节点结束时间
                    .taskComments(comments) // 审批意见
                    .build();
            resultList.add(processHistory);
        }
        return resultList;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值