package com.dl.workflow.service.impl;
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.StrUtil;
|
import com.dl.common.core.service.UserService;
|
import com.dl.common.exception.ServiceException;
|
import com.dl.common.helper.LoginHelper;
|
import com.dl.common.utils.StringUtils;
|
import com.dl.flowable.common.constant.ProcessConstants;
|
import com.dl.flowable.common.constant.TaskConstants;
|
import com.dl.flowable.common.enums.FlowComment;
|
import com.dl.flowable.common.enums.ProcessStatus;
|
import com.dl.flowable.factory.FlowServiceFactory;
|
import com.dl.flowable.flow.CustomProcessDiagramGenerator;
|
import com.dl.flowable.flow.FlowableUtils;
|
import com.dl.flowable.utils.ModelUtils;
|
import com.dl.flowable.utils.TaskUtils;
|
import com.dl.workflow.domain.bo.WfTaskBo;
|
import com.dl.workflow.service.IWfCopyService;
|
import com.dl.workflow.service.IWfTaskService;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.collections4.CollectionUtils;
|
import org.flowable.bpmn.constants.BpmnXMLConstants;
|
import org.flowable.bpmn.model.Process;
|
import org.flowable.bpmn.model.*;
|
import org.flowable.common.engine.api.FlowableException;
|
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
|
import org.flowable.common.engine.impl.identity.Authentication;
|
import org.flowable.engine.ProcessEngineConfiguration;
|
import org.flowable.engine.history.HistoricActivityInstance;
|
import org.flowable.engine.history.HistoricProcessInstance;
|
import org.flowable.engine.repository.ProcessDefinition;
|
import org.flowable.engine.runtime.Execution;
|
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.image.ProcessDiagramGenerator;
|
import org.flowable.task.api.DelegationState;
|
import org.flowable.task.api.Task;
|
import org.flowable.task.api.history.HistoricTaskInstance;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.io.InputStream;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* @author KonBAI
|
* @createTime 2022/3/10 00:12
|
*/
|
@RequiredArgsConstructor
|
@Service
|
@Slf4j
|
public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskService {
|
|
private final UserService sysUserService;
|
|
private final IWfCopyService copyService;
|
|
/**
|
* 完成任务
|
*
|
* @param taskBo 请求实体参数
|
*/
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public void complete(WfTaskBo taskBo) {
|
Task task = taskService.createTaskQuery().taskId(taskBo.getTaskId()).singleResult();
|
if (Objects.isNull(task)) {
|
throw new ServiceException("任务不存在");
|
}
|
// 获取 bpmn 模型
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
|
identityService.setAuthenticatedUserId(TaskUtils.getUserId());
|
if (DelegationState.PENDING.equals(task.getDelegationState())) {
|
taskService.addComment(taskBo.getTaskId(), taskBo.getProcInsId(), FlowComment.DELEGATE.getType(), taskBo.getComment());
|
taskService.resolveTask(taskBo.getTaskId());
|
} else {
|
taskService.addComment(taskBo.getTaskId(), taskBo.getProcInsId(), FlowComment.NORMAL.getType(), taskBo.getComment());
|
taskService.setAssignee(taskBo.getTaskId(), TaskUtils.getUserId());
|
if (ObjectUtil.isNotEmpty(taskBo.getVariables())) {
|
// 获取模型信息
|
String localScopeValue = ModelUtils.getUserTaskAttributeValue(bpmnModel, task.getTaskDefinitionKey(), ProcessConstants.PROCESS_FORM_LOCAL_SCOPE);
|
boolean localScope = Convert.toBool(localScopeValue, false);
|
taskService.complete(taskBo.getTaskId(), taskBo.getVariables(), localScope);
|
} else {
|
taskService.complete(taskBo.getTaskId());
|
}
|
}
|
// 设置任务节点名称
|
taskBo.setTaskName(task.getName());
|
// 处理下一级审批人
|
if (StringUtils.isNotBlank(taskBo.getNextUserIds())) {
|
this.assignNextUsers(bpmnModel, taskBo.getProcInsId(), taskBo.getNextUserIds());
|
}
|
// 处理抄送用户
|
if (!copyService.makeCopy(taskBo)) {
|
throw new RuntimeException("抄送任务失败");
|
}
|
}
|
|
/**
|
* 拒绝任务
|
*
|
* @param taskBo
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void taskReject(WfTaskBo taskBo) {
|
// 当前任务 task
|
Task task = taskService.createTaskQuery().taskId(taskBo.getTaskId()).singleResult();
|
if (ObjectUtil.isNull(task)) {
|
throw new RuntimeException("获取任务信息异常!");
|
}
|
if (task.isSuspended()) {
|
throw new RuntimeException("任务处于挂起状态");
|
}
|
// 获取流程实例
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
|
.processInstanceId(taskBo.getProcInsId())
|
.singleResult();
|
if (processInstance == null) {
|
throw new RuntimeException("流程实例不存在,请确认!");
|
}
|
// 获取流程定义信息
|
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
|
.processDefinitionId(task.getProcessDefinitionId())
|
.singleResult();
|
|
identityService.setAuthenticatedUserId(TaskUtils.getUserId());
|
// 添加审批意见
|
taskService.addComment(taskBo.getTaskId(), taskBo.getProcInsId(), FlowComment.REJECT.getType(), taskBo.getComment());
|
// 设置流程状态为已终结
|
runtimeService.setVariable(processInstance.getId(), ProcessConstants.PROCESS_STATUS_KEY, ProcessStatus.TERMINATED.getStatus());
|
// 获取所有节点信息
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
|
EndEvent endEvent = ModelUtils.getEndEvent(bpmnModel);
|
// 终止流程
|
List<Execution> executions = runtimeService.createExecutionQuery().parentId(task.getProcessInstanceId()).list();
|
List<String> executionIds = executions.stream().map(Execution::getId).collect(Collectors.toList());
|
runtimeService.createChangeActivityStateBuilder()
|
.processInstanceId(task.getProcessInstanceId())
|
.moveExecutionsToSingleActivityId(executionIds, endEvent.getId())
|
.changeState();
|
// 处理抄送用户
|
if (!copyService.makeCopy(taskBo)) {
|
throw new RuntimeException("抄送任务失败");
|
}
|
}
|
|
/**
|
* 退回任务
|
*
|
* @param bo 请求实体参数
|
*/
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public void taskReturn(WfTaskBo bo) {
|
// 当前任务 task
|
Task task = taskService.createTaskQuery().taskId(bo.getTaskId()).singleResult();
|
if (ObjectUtil.isNull(task)) {
|
throw new RuntimeException("获取任务信息异常!");
|
}
|
if (task.isSuspended()) {
|
throw new RuntimeException("任务处于挂起状态");
|
}
|
// 获取流程定义信息
|
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
|
// 获取流程模型信息
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
|
// 获取当前任务节点元素
|
FlowElement source = ModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
|
// 获取跳转的节点元素
|
FlowElement target = ModelUtils.getFlowElementById(bpmnModel, bo.getTargetKey());
|
// 从当前节点向前扫描,判断当前节点与目标节点是否属于串行,若目标节点是在并行网关上或非同一路线上,不可跳转
|
boolean isSequential = ModelUtils.isSequentialReachable(source, target, new HashSet<>());
|
if (!isSequential) {
|
throw new RuntimeException("当前节点相对于目标节点,不属于串行关系,无法回退");
|
}
|
|
// 获取所有正常进行的任务节点 Key,这些任务不能直接使用,需要找出其中需要撤回的任务
|
List<Task> runTaskList = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).list();
|
List<String> runTaskKeyList = new ArrayList<>();
|
runTaskList.forEach(item -> runTaskKeyList.add(item.getTaskDefinitionKey()));
|
// 需退回任务列表
|
List<String> currentIds = new ArrayList<>();
|
// 通过父级网关的出口连线,结合 runTaskList 比对,获取需要撤回的任务
|
List<UserTask> currentUserTaskList = FlowableUtils.iteratorFindChildUserTasks(target, runTaskKeyList, null, null);
|
currentUserTaskList.forEach(item -> currentIds.add(item.getId()));
|
|
// 循环获取那些需要被撤回的节点的ID,用来设置驳回原因
|
List<String> currentTaskIds = new ArrayList<>();
|
currentIds.forEach(currentId -> runTaskList.forEach(runTask -> {
|
if (currentId.equals(runTask.getTaskDefinitionKey())) {
|
currentTaskIds.add(runTask.getId());
|
}
|
}));
|
identityService.setAuthenticatedUserId(TaskUtils.getUserId());
|
// 设置回退意见
|
for (String currentTaskId : currentTaskIds) {
|
taskService.addComment(currentTaskId, task.getProcessInstanceId(), FlowComment.REBACK.getType(), bo.getComment());
|
}
|
|
try {
|
// 1 对 1 或 多 对 1 情况,currentIds 当前要跳转的节点列表(1或多),targetKey 跳转到的节点(1)
|
runtimeService.createChangeActivityStateBuilder()
|
.processInstanceId(task.getProcessInstanceId())
|
.moveActivityIdsToSingleActivityId(currentIds, bo.getTargetKey()).changeState();
|
} catch (FlowableObjectNotFoundException e) {
|
throw new RuntimeException("未找到流程实例,流程可能已发生变化");
|
} catch (FlowableException e) {
|
throw new RuntimeException("无法取消或开始活动");
|
}
|
// 设置任务节点名称
|
bo.setTaskName(task.getName());
|
// 处理抄送用户
|
if (!copyService.makeCopy(bo)) {
|
throw new RuntimeException("抄送任务失败");
|
}
|
}
|
|
|
/**
|
* 获取所有可回退的节点
|
*
|
* @param bo
|
* @return
|
*/
|
@Override
|
public List<FlowElement> findReturnTaskList(WfTaskBo bo) {
|
// 当前任务 task
|
Task task = taskService.createTaskQuery().taskId(bo.getTaskId()).singleResult();
|
// 获取流程定义信息
|
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
|
// 获取流程模型信息
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
|
// 查询历史节点实例
|
List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery()
|
.processInstanceId(task.getProcessInstanceId())
|
.activityType(BpmnXMLConstants.ELEMENT_TASK_USER)
|
.finished()
|
.orderByHistoricActivityInstanceEndTime().asc()
|
.list();
|
List<String> activityIdList = activityInstanceList.stream()
|
.map(HistoricActivityInstance::getActivityId)
|
.filter(activityId -> !StringUtils.equals(activityId, task.getTaskDefinitionKey()))
|
.distinct()
|
.collect(Collectors.toList());
|
// 获取当前任务节点元素
|
FlowElement source = ModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
|
List<FlowElement> elementList = new ArrayList<>();
|
for (String activityId : activityIdList) {
|
FlowElement target = ModelUtils.getFlowElementById(bpmnModel, activityId);
|
boolean isSequential = ModelUtils.isSequentialReachable(source, target, new HashSet<>());
|
if (isSequential) {
|
elementList.add(target);
|
}
|
}
|
return elementList;
|
}
|
|
/**
|
* 删除任务
|
*
|
* @param bo 请求实体参数
|
*/
|
@Override
|
public void deleteTask(WfTaskBo bo) {
|
// todo 待确认删除任务是物理删除任务 还是逻辑删除,让这个任务直接通过?
|
identityService.setAuthenticatedUserId(TaskUtils.getUserId());
|
taskService.deleteTask(bo.getTaskId(), bo.getComment());
|
}
|
|
/**
|
* 认领/签收任务
|
*
|
* @param taskBo 请求实体参数
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void claim(WfTaskBo taskBo) {
|
Task task = taskService.createTaskQuery().taskId(taskBo.getTaskId()).singleResult();
|
if (Objects.isNull(task)) {
|
throw new ServiceException("任务不存在");
|
}
|
taskService.claim(taskBo.getTaskId(), TaskUtils.getUserId());
|
}
|
|
/**
|
* 取消认领/签收任务
|
*
|
* @param bo 请求实体参数
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void unClaim(WfTaskBo bo) {
|
taskService.unclaim(bo.getTaskId());
|
}
|
|
/**
|
* 委派任务
|
*
|
* @param bo 请求实体参数
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void delegateTask(WfTaskBo bo) {
|
// 当前任务 task
|
Task task = taskService.createTaskQuery().taskId(bo.getTaskId()).singleResult();
|
if (ObjectUtil.isEmpty(task)) {
|
throw new ServiceException("获取任务失败!");
|
}
|
StringBuilder commentBuilder = new StringBuilder(LoginHelper.getNickName())
|
.append("->");
|
String nickName = sysUserService.selectNickNameById(bo.getUserId());
|
if (StringUtils.isNotBlank(nickName)) {
|
commentBuilder.append(nickName);
|
} else {
|
commentBuilder.append(bo.getUserId());
|
}
|
if (StringUtils.isNotBlank(bo.getComment())) {
|
commentBuilder.append(": ").append(bo.getComment());
|
}
|
identityService.setAuthenticatedUserId(TaskUtils.getUserId());
|
// 添加审批意见
|
taskService.addComment(bo.getTaskId(), task.getProcessInstanceId(), FlowComment.DELEGATE.getType(), commentBuilder.toString());
|
// 设置办理人为当前登录人
|
taskService.setOwner(bo.getTaskId(), TaskUtils.getUserId());
|
// 执行委派
|
taskService.delegateTask(bo.getTaskId(), bo.getUserId());
|
// 设置任务节点名称
|
bo.setTaskName(task.getName());
|
// 处理抄送用户
|
if (!copyService.makeCopy(bo)) {
|
throw new RuntimeException("抄送任务失败");
|
}
|
}
|
|
|
/**
|
* 转办任务
|
*
|
* @param bo 请求实体参数
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void transferTask(WfTaskBo bo) {
|
// 当前任务 task
|
Task task = taskService.createTaskQuery().taskId(bo.getTaskId()).singleResult();
|
if (ObjectUtil.isEmpty(task)) {
|
throw new ServiceException("获取任务失败!");
|
}
|
StringBuilder commentBuilder = new StringBuilder(LoginHelper.getNickName())
|
.append("->");
|
String nickName = sysUserService.selectNickNameById(bo.getUserId());
|
if (StringUtils.isNotBlank(nickName)) {
|
commentBuilder.append(nickName);
|
} else {
|
commentBuilder.append(bo.getUserId());
|
}
|
if (StringUtils.isNotBlank(bo.getComment())) {
|
commentBuilder.append(": ").append(bo.getComment());
|
}
|
identityService.setAuthenticatedUserId(TaskUtils.getUserId());
|
// 添加审批意见
|
taskService.addComment(bo.getTaskId(), task.getProcessInstanceId(), FlowComment.TRANSFER.getType(), commentBuilder.toString());
|
// 设置拥有者为当前登录人
|
taskService.setOwner(bo.getTaskId(), TaskUtils.getUserId());
|
// 转办任务
|
taskService.setAssignee(bo.getTaskId(), bo.getUserId());
|
// 设置任务节点名称
|
bo.setTaskName(task.getName());
|
// 处理抄送用户
|
if (!copyService.makeCopy(bo)) {
|
throw new RuntimeException("抄送任务失败");
|
}
|
}
|
|
/**
|
* 取消申请
|
*
|
* @param bo
|
* @return
|
*/
|
@Override
|
public void stopProcess(WfTaskBo bo) {
|
List<Task> taskList = taskService.createTaskQuery().processInstanceId(bo.getProcInsId()).list();
|
if (CollectionUtils.isEmpty(taskList)) {
|
throw new RuntimeException("流程未启动或已执行完成,取消申请失败");
|
}
|
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
|
.processInstanceId(bo.getProcInsId()).singleResult();
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
|
if (Objects.nonNull(bpmnModel)) {
|
Process process = bpmnModel.getMainProcess();
|
List<EndEvent> endNodes = process.findFlowElementsOfType(EndEvent.class, false);
|
if (CollectionUtils.isNotEmpty(endNodes)) {
|
Authentication.setAuthenticatedUserId(TaskUtils.getUserId());
|
runtimeService.setVariable(processInstance.getId(), ProcessConstants.PROCESS_STATUS_KEY, ProcessStatus.CANCELED.getStatus());
|
for (Task task : taskList) {
|
taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.STOP.getType(), "取消流程");
|
}
|
// 获取当前流程最后一个节点
|
String endId = endNodes.get(0).getId();
|
List<Execution> executions = runtimeService.createExecutionQuery()
|
.parentId(processInstance.getProcessInstanceId()).list();
|
List<String> executionIds = new ArrayList<>();
|
executions.forEach(execution -> executionIds.add(execution.getId()));
|
// 变更流程为已结束状态
|
runtimeService.createChangeActivityStateBuilder()
|
.moveExecutionsToSingleActivityId(executionIds, endId).changeState();
|
}
|
}
|
}
|
|
/**
|
* 撤回流程
|
*
|
* @param taskBo 请求实体参数
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void revokeProcess(WfTaskBo taskBo) {
|
String procInsId = taskBo.getProcInsId();
|
String taskId = taskBo.getTaskId();
|
// 校验流程是否结束
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
|
.processInstanceId(procInsId)
|
.active()
|
.singleResult();
|
if(ObjectUtil.isNull(processInstance)) {
|
throw new RuntimeException("流程已结束或已挂起,无法执行撤回操作");
|
}
|
// 获取待撤回任务实例
|
HistoricTaskInstance currTaskIns = historyService.createHistoricTaskInstanceQuery()
|
.taskId(taskId)
|
.taskAssignee(TaskUtils.getUserId())
|
.singleResult();
|
if (ObjectUtil.isNull(currTaskIns)) {
|
throw new RuntimeException("当前任务不存在,无法执行撤回操作");
|
}
|
// 获取 bpmn 模型
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(currTaskIns.getProcessDefinitionId());
|
UserTask currUserTask = ModelUtils.getUserTaskByKey(bpmnModel, currTaskIns.getTaskDefinitionKey());
|
// 查找下一级用户任务列表
|
List<UserTask> nextUserTaskList = ModelUtils.findNextUserTasks(currUserTask);
|
List<String> nextUserTaskKeys = nextUserTaskList.stream().map(UserTask::getId).collect(Collectors.toList());
|
|
// 获取当前节点之后已完成的流程历史节点
|
List<HistoricTaskInstance> finishedTaskInsList = historyService.createHistoricTaskInstanceQuery()
|
.processInstanceId(procInsId)
|
.taskCreatedAfter(currTaskIns.getEndTime())
|
.finished()
|
.list();
|
for (HistoricTaskInstance finishedTaskInstance : finishedTaskInsList) {
|
// 检查已完成流程历史节点是否存在下一级中
|
if (CollUtil.contains(nextUserTaskKeys, finishedTaskInstance.getTaskDefinitionKey())) {
|
throw new RuntimeException("下一流程已处理,无法执行撤回操作");
|
}
|
}
|
// 获取所有激活的任务节点,找到需要撤回的任务
|
List<Task> activateTaskList = taskService.createTaskQuery().processInstanceId(procInsId).list();
|
List<String> revokeExecutionIds = new ArrayList<>();
|
identityService.setAuthenticatedUserId(TaskUtils.getUserId());
|
for (Task task : activateTaskList) {
|
// 检查激活的任务节点是否存在下一级中,如果存在,则加入到需要撤回的节点
|
if (CollUtil.contains(nextUserTaskKeys, task.getTaskDefinitionKey())) {
|
// 添加撤回审批信息
|
taskService.setAssignee(task.getId(), TaskUtils.getUserId());
|
taskService.addComment(task.getId(), task.getProcessInstanceId(), FlowComment.REVOKE.getType(), LoginHelper.getNickName() + "撤回流程审批");
|
revokeExecutionIds.add(task.getExecutionId());
|
}
|
}
|
try {
|
runtimeService.createChangeActivityStateBuilder()
|
.processInstanceId(procInsId)
|
.moveExecutionsToSingleActivityId(revokeExecutionIds, currTaskIns.getTaskDefinitionKey()).changeState();
|
} catch (FlowableObjectNotFoundException e) {
|
throw new RuntimeException("未找到流程实例,流程可能已发生变化");
|
} catch (FlowableException e) {
|
throw new RuntimeException("执行撤回操作失败");
|
}
|
}
|
|
/**
|
* 获取流程过程图
|
*
|
* @param processId
|
* @return
|
*/
|
@Override
|
public InputStream diagram(String processId) {
|
String processDefinitionId;
|
// 获取当前的流程实例
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
|
// 如果流程已经结束,则得到结束节点
|
if (Objects.isNull(processInstance)) {
|
HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();
|
|
processDefinitionId = pi.getProcessDefinitionId();
|
} else {// 如果流程没有结束,则取当前活动节点
|
// 根据流程实例ID获得当前处于活动状态的ActivityId合集
|
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
|
processDefinitionId = pi.getProcessDefinitionId();
|
}
|
|
// 获得活动的节点
|
List<HistoricActivityInstance> highLightedFlowList = historyService.createHistoricActivityInstanceQuery()
|
.processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list();
|
|
List<String> highLightedFlows = new ArrayList<>();
|
List<String> highLightedNodes = new ArrayList<>();
|
//高亮线
|
for (HistoricActivityInstance tempActivity : highLightedFlowList) {
|
if ("sequenceFlow".equals(tempActivity.getActivityType())) {
|
//高亮线
|
highLightedFlows.add(tempActivity.getActivityId());
|
} else {
|
//高亮节点
|
highLightedNodes.add(tempActivity.getActivityId());
|
}
|
}
|
|
//获取流程图
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
|
ProcessEngineConfiguration configuration = processEngine.getProcessEngineConfiguration();
|
//获取自定义图片生成器
|
ProcessDiagramGenerator diagramGenerator = new CustomProcessDiagramGenerator();
|
return diagramGenerator.generateDiagram(bpmnModel, "png", highLightedNodes, highLightedFlows, configuration.getActivityFontName(),
|
configuration.getLabelFontName(), configuration.getAnnotationFontName(), configuration.getClassLoader(), 1.0, true);
|
|
}
|
|
/**
|
* 获取流程变量
|
*
|
* @param taskId 任务ID
|
* @return 流程变量
|
*/
|
@Override
|
public Map<String, Object> getProcessVariables(String taskId) {
|
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery()
|
.includeProcessVariables()
|
.finished()
|
.taskId(taskId)
|
.singleResult();
|
if (Objects.nonNull(historicTaskInstance)) {
|
return historicTaskInstance.getProcessVariables();
|
}
|
return taskService.getVariables(taskId);
|
}
|
|
/**
|
* 启动第一个任务
|
* @param processInstance 流程实例
|
* @param variables 流程参数
|
*/
|
@Override
|
public void startFirstTask(ProcessInstance processInstance, Map<String, Object> variables) {
|
// 若第一个用户任务为发起人,则自动完成任务
|
List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).list();
|
if (CollUtil.isNotEmpty(tasks)) {
|
String userIdStr = (String) variables.get(TaskConstants.PROCESS_INITIATOR);
|
identityService.setAuthenticatedUserId(TaskUtils.getUserId());
|
for (Task task : tasks) {
|
if (StrUtil.equals(task.getAssignee(), userIdStr)) {
|
taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.NORMAL.getType(), LoginHelper.getNickName() + "发起流程申请");
|
taskService.complete(task.getId(), variables);
|
}
|
}
|
}
|
}
|
|
/**
|
* 指派下一任务审批人
|
* @param bpmnModel bpmn模型
|
* @param processInsId 流程实例id
|
* @param userIds 用户ids
|
*/
|
private void assignNextUsers(BpmnModel bpmnModel, String processInsId, String userIds) {
|
// 获取所有节点信息
|
List<Task> list = taskService.createTaskQuery()
|
.processInstanceId(processInsId)
|
.list();
|
if (list.size() == 0) {
|
return;
|
}
|
Queue<String> assignIds = CollUtil.newLinkedList(userIds.split(","));
|
if (list.size() == assignIds.size()) {
|
for (Task task : list) {
|
taskService.setAssignee(task.getId(), assignIds.poll());
|
}
|
return;
|
}
|
// 优先处理非多实例任务
|
Iterator<Task> iterator = list.iterator();
|
while (iterator.hasNext()) {
|
Task task = iterator.next();
|
if (!ModelUtils.isMultiInstance(bpmnModel, task.getTaskDefinitionKey())) {
|
if (!assignIds.isEmpty()) {
|
taskService.setAssignee(task.getId(), assignIds.poll());
|
}
|
iterator.remove();
|
}
|
}
|
// 若存在多实例任务,则进行动态加减签
|
if (CollUtil.isNotEmpty(list)) {
|
if (assignIds.isEmpty()) {
|
// 动态减签
|
for (Task task : list) {
|
runtimeService.deleteMultiInstanceExecution(task.getExecutionId(), true);
|
}
|
} else {
|
// 动态加签
|
for (String assignId : assignIds) {
|
Map<String, Object> assignVariables = Collections.singletonMap(BpmnXMLConstants.ATTRIBUTE_TASK_USER_ASSIGNEE, assignId);
|
runtimeService.addMultiInstanceExecution(list.get(0).getTaskDefinitionKey(), list.get(0).getProcessInstanceId(), assignVariables);
|
}
|
}
|
}
|
}
|
}
|