2024-10-14 17:32:39 +08:00
|
|
|
|
package com.zhgd.xmgl.util;
|
|
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
2024-10-16 18:25:15 +08:00
|
|
|
|
import cn.hutool.core.collection.CollectionUtil;
|
2024-10-14 17:32:39 +08:00
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
2024-10-16 18:25:15 +08:00
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
2024-10-14 17:32:39 +08:00
|
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
2024-10-16 18:25:15 +08:00
|
|
|
|
import com.gexin.fastjson.JSON;
|
|
|
|
|
|
import com.gexin.fastjson.JSONArray;
|
|
|
|
|
|
import com.gexin.fastjson.JSONObject;
|
|
|
|
|
|
import com.wflow.bean.do_.UserDeptDo;
|
|
|
|
|
|
import com.wflow.bean.entity.WflowModelHistorys;
|
|
|
|
|
|
import com.wflow.bean.entity.WflowSubProcess;
|
|
|
|
|
|
import com.wflow.mapper.WflowModelHistorysMapper;
|
|
|
|
|
|
import com.wflow.mapper.WflowSubProcessMapper;
|
|
|
|
|
|
import com.wflow.service.OrgRepositoryService;
|
|
|
|
|
|
import com.wflow.workflow.UELTools;
|
|
|
|
|
|
import com.wflow.workflow.bean.dto.ProcessInstanceOwnerDto;
|
|
|
|
|
|
import com.wflow.workflow.bean.process.OrgUser;
|
|
|
|
|
|
import com.wflow.workflow.bean.process.ProcessNode;
|
|
|
|
|
|
import com.wflow.workflow.bean.process.enums.ApprovalModeEnum;
|
|
|
|
|
|
import com.wflow.workflow.bean.process.enums.NodeTypeEnum;
|
|
|
|
|
|
import com.wflow.workflow.bean.process.props.ApprovalProps;
|
|
|
|
|
|
import com.wflow.workflow.bean.process.props.CcProps;
|
|
|
|
|
|
import com.wflow.workflow.bean.vo.ProcessConditionResolveParamsVo;
|
|
|
|
|
|
import com.wflow.workflow.bean.vo.ProcessProgressVo;
|
2024-10-14 17:32:39 +08:00
|
|
|
|
import com.wflow.workflow.bean.vo.ProcessTaskVo;
|
2024-10-16 18:25:15 +08:00
|
|
|
|
import com.wflow.workflow.config.WflowGlobalVarDef;
|
|
|
|
|
|
import com.wflow.workflow.service.*;
|
|
|
|
|
|
import com.wflow.workflow.service.impl.ProcessTaskServiceImpl;
|
|
|
|
|
|
import com.zhgd.jeecg.common.execption.OpenAlertException;
|
2024-10-14 17:32:39 +08:00
|
|
|
|
import com.zhgd.xmgl.security.util.SecurityUtils;
|
2024-10-16 18:25:15 +08:00
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
import org.flowable.engine.HistoryService;
|
|
|
|
|
|
import org.flowable.engine.RepositoryService;
|
2024-10-14 17:32:39 +08:00
|
|
|
|
import org.flowable.engine.RuntimeService;
|
|
|
|
|
|
import org.flowable.engine.TaskService;
|
2024-10-16 18:25:15 +08:00
|
|
|
|
import org.flowable.engine.history.HistoricProcessInstance;
|
2024-10-14 17:32:39 +08:00
|
|
|
|
import org.flowable.engine.runtime.ProcessInstanceQuery;
|
|
|
|
|
|
import org.flowable.task.api.Task;
|
2024-10-16 18:25:15 +08:00
|
|
|
|
import org.flowable.task.api.TaskInfo;
|
2024-10-14 17:32:39 +08:00
|
|
|
|
import org.flowable.task.api.TaskQuery;
|
2024-10-16 18:25:15 +08:00
|
|
|
|
import org.flowable.task.api.history.HistoricTaskInstance;
|
|
|
|
|
|
import org.flowable.variable.api.history.HistoricVariableInstance;
|
2024-10-14 17:32:39 +08:00
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
import org.springframework.context.annotation.Lazy;
|
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
2024-10-16 18:25:15 +08:00
|
|
|
|
import java.util.*;
|
2024-10-14 17:32:39 +08:00
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
|
|
@Component
|
2024-10-16 18:25:15 +08:00
|
|
|
|
@Slf4j
|
2024-10-14 17:32:39 +08:00
|
|
|
|
public class FlowSeviceUtil {
|
2024-10-16 18:25:15 +08:00
|
|
|
|
private final static OrgUser UNKNOW_USER = OrgUser.builder().id("5201314").name("人员待定").build();
|
|
|
|
|
|
|
2024-10-14 17:32:39 +08:00
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private TaskService taskService;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private RuntimeService runtimeService;
|
2024-10-16 18:25:15 +08:00
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private ProcessInstanceService processService;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private WflowModelHistorysMapper modelHistorysMapper;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private HistoryService historyService;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private RepositoryService repositoryService;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private UserDeptOrLeaderService userDeptOrLeaderService;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private ProcessStepRenderService stepRenderService;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private ProcessTaskServiceImpl processTaskService;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private OrgRepositoryService orgRepositoryService;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private BusinessDataStorageService businessDataService;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private UELTools uelTools;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private WflowSubProcessMapper subProcessMapper;
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private ProcessNodeCatchService nodeCatchService;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取下一个待处理的审批节点
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param instanceId
|
|
|
|
|
|
* @param dfNodeId
|
|
|
|
|
|
* @return
|
|
|
|
|
|
*/
|
|
|
|
|
|
public ProcessProgressVo.ProgressNode getNextTodoApproval(String instanceId, String dfNodeId) {
|
|
|
|
|
|
//先查实例,然后判断是子流程还是主流程
|
|
|
|
|
|
HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
|
|
|
|
|
|
.processInstanceId(instanceId).singleResult();
|
|
|
|
|
|
//数据分类 表单配置及数据、审批任务结果、
|
|
|
|
|
|
ProcessInstanceOwnerDto owner = null;
|
|
|
|
|
|
Map<String, Object> formDatas = new HashMap<>();
|
|
|
|
|
|
//是否是子流程
|
|
|
|
|
|
boolean isSub = StrUtil.isNotBlank(instance.getSuperProcessInstanceId());
|
|
|
|
|
|
HistoricProcessInstance mainInst = isSub ? null : instance;
|
|
|
|
|
|
if (isSub) {
|
|
|
|
|
|
//查出主流程表单数据
|
|
|
|
|
|
mainInst = historyService.createHistoricProcessInstanceQuery()
|
|
|
|
|
|
.processInstanceId(instance.getSuperProcessInstanceId()).singleResult();
|
|
|
|
|
|
formDatas = businessDataService.getProcessInstanceFormData(mainInst.getId());
|
|
|
|
|
|
}
|
|
|
|
|
|
//优化查询,把之前查好几次的一次性查出来然后再分类
|
|
|
|
|
|
List<HistoricVariableInstance> variables = historyService.createHistoricVariableInstanceQuery()
|
|
|
|
|
|
.processInstanceId(instanceId).executionId(instanceId).list();
|
|
|
|
|
|
Map<String, Object> vars = Objects.nonNull(instance.getEndTime()) ?
|
|
|
|
|
|
new HashMap<>() : uelTools.getContextVar(instanceId, instance.getProcessDefinitionId());
|
|
|
|
|
|
//遍历所有变量,将数据分类
|
|
|
|
|
|
for (HistoricVariableInstance var : variables) {
|
|
|
|
|
|
vars.put(var.getVariableName(), var.getValue());
|
|
|
|
|
|
if (!isSub && var.getVariableName().startsWith("field")) {
|
|
|
|
|
|
formDatas.put(var.getVariableName(), var.getValue());
|
|
|
|
|
|
} else if (WflowGlobalVarDef.OWNER.equals(var.getVariableName())) {
|
|
|
|
|
|
owner = (ProcessInstanceOwnerDto) var.getValue();
|
|
|
|
|
|
} else if (WflowGlobalVarDef.START_DEPT.equals(var.getVariableName())) {
|
|
|
|
|
|
String key = instance.getStartUserId() + "_" + var.getValue();
|
|
|
|
|
|
Map<String, UserDeptDo> infoMap = orgRepositoryService.getUserDeptInfos(CollectionUtil.newArrayList(key));
|
|
|
|
|
|
UserDeptDo userDeptDo = infoMap.getOrDefault(key, new UserDeptDo());
|
|
|
|
|
|
owner = ProcessInstanceOwnerDto.builder().ownerDeptId(String.valueOf(var.getValue()))
|
|
|
|
|
|
.owner(instance.getStartUserId()).ownerName(userDeptDo.getUserName())
|
|
|
|
|
|
.ownerDeptId(userDeptDo.getDeptId()).ownerDeptName(userDeptDo.getDeptName()).build();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
Map<String, ProcessNode<?>> nodeMap = Collections.emptyMap();
|
|
|
|
|
|
if (isSub) {
|
|
|
|
|
|
WflowSubProcess subProcess = subProcessMapper.selectOne(new LambdaQueryWrapper<>(WflowSubProcess.builder()
|
|
|
|
|
|
.procDefId(instance.getProcessDefinitionId()).build()));
|
|
|
|
|
|
nodeMap = nodeCatchService.reloadProcessByStr(subProcess.getProcess());
|
|
|
|
|
|
HistoricVariableInstance formsVar = historyService.createHistoricVariableInstanceQuery()
|
|
|
|
|
|
.processInstanceId(mainInst.getId()).variableName(WflowGlobalVarDef.WFLOW_FORMS).singleResult();
|
|
|
|
|
|
}
|
|
|
|
|
|
//搜索当前版本流程的配置
|
|
|
|
|
|
WflowModelHistorys modelHistory = modelHistorysMapper.selectOne(new LambdaQueryWrapper<>(WflowModelHistorys.builder()
|
|
|
|
|
|
.processDefId(mainInst.getProcessDefinitionId()).version(mainInst.getProcessDefinitionVersion()).build()));
|
|
|
|
|
|
if (StrUtil.isNotBlank(dfNodeId)) {
|
|
|
|
|
|
nodeMap = nodeCatchService.reloadProcessByStr(modelHistory.getProcess());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
List<ProcessProgressVo.ProgressNode> progressNodeList = this.getFutureTask(instance, owner.getOwnerDeptId(), vars, nodeMap, modelHistory.getTenantId());
|
|
|
|
|
|
if (CollUtil.isEmpty(progressNodeList)) {
|
|
|
|
|
|
throw new OpenAlertException("获取下一个待处理的审批节点超时失败,instanceId=" + instanceId + ",nodeId=" + dfNodeId);
|
|
|
|
|
|
}
|
|
|
|
|
|
return progressNodeList.get(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isProcessDone(String process, String curNodeId, String dfNodeId) {
|
|
|
|
|
|
JSONObject rootJo = JSON.parseObject(process);
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
return getDeepFromProcess(rootJo, curNodeId, i) > getDeepFromProcess(rootJo, dfNodeId, i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Integer getDeepFromProcess(JSONObject jo, String curNodeId, int i) {
|
|
|
|
|
|
String id = jo.getString("id");
|
|
|
|
|
|
if (id.equals(curNodeId)) {
|
|
|
|
|
|
return i;
|
|
|
|
|
|
}
|
|
|
|
|
|
String type = jo.getString("type");
|
|
|
|
|
|
if (type.equals("CONDITIONS")) {
|
|
|
|
|
|
JSONArray array = jo.getJSONArray("branchs");
|
|
|
|
|
|
for (int j = 0; j < array.size(); j++) {
|
|
|
|
|
|
i = getDeepFromProcess(array.getJSONObject(j), curNodeId, i);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
JSONObject children = jo.getJSONObject("children");
|
|
|
|
|
|
if (CollUtil.isEmpty(children)) {
|
|
|
|
|
|
return i;
|
|
|
|
|
|
}
|
|
|
|
|
|
i = getDeepFromProcess(children, curNodeId, ++i);
|
|
|
|
|
|
}
|
|
|
|
|
|
return i;
|
|
|
|
|
|
}
|
2024-10-14 17:32:39 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取我的待办的instanceIdList
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param code 表单id,安全检查:wf66f6451c48b718d0aaf27522
|
|
|
|
|
|
* @return
|
|
|
|
|
|
*/
|
2024-10-16 18:25:15 +08:00
|
|
|
|
public List<String> getMyTodoInstanceIds(String code, String projectSn) {
|
2024-10-14 17:32:39 +08:00
|
|
|
|
if (SecurityUtils.getUser() == null) {
|
|
|
|
|
|
ArrayList<String> list = new ArrayList<>();
|
|
|
|
|
|
list.add("-1");
|
|
|
|
|
|
return list;
|
|
|
|
|
|
}
|
|
|
|
|
|
String userId = String.valueOf(SecurityUtils.getUser().getUserId());
|
|
|
|
|
|
TaskQuery taskQuery = taskService.createTaskQuery();
|
|
|
|
|
|
if (StrUtil.isNotBlank(code)) {
|
|
|
|
|
|
taskQuery.processDefinitionKey(code);
|
|
|
|
|
|
}
|
|
|
|
|
|
ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
|
|
|
|
|
|
Set<String> stringSet = processInstanceQuery.list().stream().map(p -> p.getProcessInstanceId()).collect(Collectors.toSet());
|
|
|
|
|
|
taskQuery.active().taskTenantId(projectSn)
|
|
|
|
|
|
.processInstanceIdIn(stringSet)
|
|
|
|
|
|
.taskCandidateOrAssigned(userId)
|
|
|
|
|
|
.orderByTaskCreateTime().desc();
|
|
|
|
|
|
Page<ProcessTaskVo> page = new Page<>();
|
|
|
|
|
|
List<Task> taskList = new ArrayList<>();
|
|
|
|
|
|
taskList = taskQuery.list();
|
|
|
|
|
|
List<String> list = taskList.stream().map(o -> o.getProcessInstanceId()).collect(Collectors.toList());
|
|
|
|
|
|
if (CollUtil.isEmpty(list)) {
|
|
|
|
|
|
list.add("-1");
|
|
|
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
|
|
|
}
|
2024-10-16 18:25:15 +08:00
|
|
|
|
|
|
|
|
|
|
private Set<String> getCcTaskUsers(String instanceId, String nodeId) {
|
|
|
|
|
|
//获取设置项
|
|
|
|
|
|
HistoricVariableInstance variableInstance = historyService.createHistoricVariableInstanceQuery()
|
|
|
|
|
|
.processInstanceId(instanceId)
|
|
|
|
|
|
.variableName(WflowGlobalVarDef.WFLOW_NODE_PROPS).singleResult();
|
|
|
|
|
|
Map nodeProps;
|
|
|
|
|
|
if (Objects.nonNull(variableInstance)) {
|
|
|
|
|
|
nodeProps = (Map) variableInstance.getValue();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
//流程首个节点需要从执行实例中取数据
|
|
|
|
|
|
nodeProps = runtimeService.getVariable(instanceId, WflowGlobalVarDef.WFLOW_NODE_PROPS, Map.class);
|
|
|
|
|
|
}
|
|
|
|
|
|
CcProps ccProps = (CcProps) nodeProps.get(nodeId);
|
|
|
|
|
|
//获取变量里面自选的抄送人
|
|
|
|
|
|
Set<String> ccUsers = new HashSet<>();
|
|
|
|
|
|
List<OrgUser> orgs = new ArrayList<>(ccProps.getAssignedUser());
|
|
|
|
|
|
if (ccProps.getShouldAdd()) {
|
|
|
|
|
|
//获取发起流程时添加的抄送人
|
|
|
|
|
|
HistoricVariableInstance result = historyService.createHistoricVariableInstanceQuery()
|
|
|
|
|
|
.processInstanceId(instanceId)
|
|
|
|
|
|
.variableName(nodeId).singleResult();
|
|
|
|
|
|
if (Objects.nonNull(result)) {
|
|
|
|
|
|
Optional.ofNullable(result.getValue()).ifPresent(us -> orgs.addAll((List<OrgUser>) us));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Optional.ofNullable(runtimeService.getVariable(instanceId, nodeId, List.class)).ifPresent(orgs::addAll);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//解析部门与人员选项
|
|
|
|
|
|
ccUsers.addAll(orgs.stream().filter(org -> "user".equals(org.getType()))
|
|
|
|
|
|
.map(OrgUser::getId).collect(Collectors.toSet()));
|
|
|
|
|
|
ccUsers.addAll(userDeptOrLeaderService.getUsersByDept(orgs.stream()
|
|
|
|
|
|
.filter(org -> "dept".equals(org.getType()))
|
|
|
|
|
|
.map(OrgUser::getId).collect(Collectors.toSet())));
|
|
|
|
|
|
return ccUsers;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private List<ProcessProgressVo.ProgressNode> getFutureTask(HistoricProcessInstance instance, String
|
|
|
|
|
|
startDept, Map<String, Object> context, Map<String, ProcessNode<?>> nodes, String tenantId) {
|
|
|
|
|
|
//根据流程遍历后续节点,期间要穿越后续包含并行网关和条件网关的节点,先找到所有激活的任务节点开始递归
|
|
|
|
|
|
//节点如果处于并行/包容分支内,可能会有多个活动的节点
|
|
|
|
|
|
List<ProcessProgressVo.ProgressNode> progressNodes = new LinkedList<>();
|
|
|
|
|
|
try {
|
|
|
|
|
|
Set<String> idSet = new LinkedHashSet<>();
|
|
|
|
|
|
context.put("root", instance.getStartUserId());
|
|
|
|
|
|
taskService.createTaskQuery().processInstanceId(instance.getId()).active().list()
|
|
|
|
|
|
.stream().map(TaskInfo::getTaskDefinitionKey)
|
|
|
|
|
|
.collect(Collectors.toSet()).forEach(nodeId -> {
|
|
|
|
|
|
//根据每个活动的节点进行遍历,最终它们会在合流点汇聚
|
|
|
|
|
|
idSet.add(nodeId);
|
|
|
|
|
|
Optional.ofNullable(nodes.get(nodeId)).ifPresent(node -> {
|
|
|
|
|
|
//已激活的当前节点,需要进行去重
|
|
|
|
|
|
if (node.getProps() instanceof ApprovalProps) {
|
|
|
|
|
|
ApprovalProps props = (ApprovalProps) node.getProps();
|
|
|
|
|
|
List<String> users = processTaskService.getApprovalUsers(instance.getId(), node.getId(), props, tenantId);
|
|
|
|
|
|
//取已下发的任务
|
|
|
|
|
|
List<HistoricTaskInstance> ingTask = historyService.createHistoricTaskInstanceQuery()
|
|
|
|
|
|
.processInstanceId(instance.getId()).taskDefinitionKey(nodeId).list();
|
|
|
|
|
|
//转交的也要过滤掉,但是只能过滤一次转交的
|
|
|
|
|
|
Set<String> ingTaskUser = ingTask.stream().map(TaskInfo::getAssignee).collect(Collectors.toSet());
|
|
|
|
|
|
ingTaskUser.addAll(ingTask.stream().filter(v -> Objects.nonNull(v.getOwner()))
|
|
|
|
|
|
.map(HistoricTaskInstance::getOwner).collect(Collectors.toList()));
|
|
|
|
|
|
Map<String, OrgUser> userMaps = userDeptOrLeaderService.getUserMapByIds(users);
|
|
|
|
|
|
users.stream().filter(v -> !ingTaskUser.contains(v))
|
|
|
|
|
|
.forEach(us -> {
|
|
|
|
|
|
Date createTime = ingTask.get(ingTask.size() - 1).getCreateTime();
|
|
|
|
|
|
//把时间往后延长10ms,使其排列到后方
|
|
|
|
|
|
createTime.setTime(createTime.getTime() + 10);
|
|
|
|
|
|
progressNodes.add(ProcessProgressVo.ProgressNode.builder()
|
|
|
|
|
|
.nodeId(node.getId())
|
|
|
|
|
|
// .isFuture(true)
|
|
|
|
|
|
.name(node.getName())
|
|
|
|
|
|
.user(userMaps.getOrDefault(us, UNKNOW_USER))
|
|
|
|
|
|
.nodeType(node.getType())
|
|
|
|
|
|
.comment(Collections.emptyList())
|
|
|
|
|
|
.approvalMode(props.getMode())
|
|
|
|
|
|
.startTime(createTime)
|
|
|
|
|
|
.build());
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
//遍历后续节点
|
|
|
|
|
|
foreachNode(node.getChildren(), idSet, progressNodes, instance, context, tenantId);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("获取[{}]未开始任务异常: {}", instance.getId(), e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
return progressNodes;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void foreachNode(ProcessNode<?> node, Set<String> idSet, List<ProcessProgressVo.ProgressNode> progressNodes,
|
|
|
|
|
|
HistoricProcessInstance instance, Map<String, Object> vars, String tenantId) {
|
|
|
|
|
|
if (Objects.isNull(node) || StrUtil.isBlank(node.getId()) || idSet.contains(node.getId())) return;
|
|
|
|
|
|
idSet.add(node.getId());
|
|
|
|
|
|
if ((NodeTypeEnum.TASK.equals(node.getType()) || NodeTypeEnum.APPROVAL.equals(node.getType())
|
|
|
|
|
|
|| NodeTypeEnum.CC.equals(node.getType()))) {
|
|
|
|
|
|
//没有遍历过的节点,且是(审批、抄送、办理)把对应的人员解析出来
|
|
|
|
|
|
Collection<String> users;
|
|
|
|
|
|
ApprovalModeEnum modeEnum;
|
|
|
|
|
|
if (NodeTypeEnum.CC.equals(node.getType())) {
|
|
|
|
|
|
modeEnum = null;
|
|
|
|
|
|
users = getCcTaskUsers(instance.getId(), node.getId());
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ApprovalProps props = (ApprovalProps) node.getProps();
|
|
|
|
|
|
modeEnum = props.getMode();
|
|
|
|
|
|
users = processTaskService.getApprovalUsers(instance.getId(), node.getId(), props, tenantId);
|
|
|
|
|
|
}
|
|
|
|
|
|
Map<String, OrgUser> userMaps = userDeptOrLeaderService.getUserMapByIds(users);
|
|
|
|
|
|
users.forEach(us -> progressNodes.add(ProcessProgressVo.ProgressNode.builder()
|
|
|
|
|
|
.nodeId(node.getId())
|
|
|
|
|
|
// .isFuture(true)
|
|
|
|
|
|
.name(node.getName())
|
|
|
|
|
|
.user(userMaps.getOrDefault(us, UNKNOW_USER))
|
|
|
|
|
|
.nodeType(node.getType())
|
|
|
|
|
|
.comment(Collections.emptyList())
|
|
|
|
|
|
.approvalMode(modeEnum)
|
|
|
|
|
|
.startTime(GregorianCalendar.getInstance().getTime())
|
|
|
|
|
|
.build()));
|
|
|
|
|
|
} else if (NodeTypeEnum.CONCURRENTS.equals(node.getType())) {
|
|
|
|
|
|
//并行网关,全部需要递归遍历
|
|
|
|
|
|
node.getBranchs().forEach(branch -> {
|
|
|
|
|
|
foreachNode(branch, idSet, progressNodes, instance, vars, tenantId);
|
|
|
|
|
|
});
|
|
|
|
|
|
//从分支出来继续往下遍历
|
|
|
|
|
|
} else if (NodeTypeEnum.INCLUSIVES.equals(node.getType()) || NodeTypeEnum.CONDITIONS.equals(node.getType())) {
|
|
|
|
|
|
//包容网关/条件网关,满足条件的分支都要执行
|
|
|
|
|
|
List<String> trueConditions = stepRenderService.getIsTrueConditions(ProcessConditionResolveParamsVo.builder()
|
|
|
|
|
|
.processDfId(instance.getProcessDefinitionId())
|
|
|
|
|
|
.conditionNodeId(node.getId()).context(vars)
|
|
|
|
|
|
.multiple(NodeTypeEnum.INCLUSIVES.equals(node.getType()))
|
|
|
|
|
|
.build());
|
|
|
|
|
|
//遍历满足条件的分支
|
|
|
|
|
|
node.getBranchs().forEach(bNode -> {
|
|
|
|
|
|
if (trueConditions.contains(bNode.getId())) {
|
|
|
|
|
|
foreachNode(bNode, idSet, progressNodes, instance, vars, tenantId);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
} else if (NodeTypeEnum.EMPTY.equals(node.getType())) {
|
|
|
|
|
|
//空节点的话是合流点,说明前面有网关,那么要回头再向上去找节点,太复杂了,难搞
|
|
|
|
|
|
//nodes.get(node.getParentId())
|
|
|
|
|
|
}
|
|
|
|
|
|
foreachNode(node.getChildren(), idSet, progressNodes, instance, vars, tenantId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-10-14 17:32:39 +08:00
|
|
|
|
}
|