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;
}
}
Activiti常用方法封装
于 2022-09-20 16:22:32 首次发布