|
@@ -1,6 +1,15 @@
|
|
|
package com.qqflow.engine.domain.flow.assembler;
|
|
package com.qqflow.engine.domain.flow.assembler;
|
|
|
|
|
|
|
|
|
|
+import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.qqflow.engine.domain.flow.dto.ApprovalTaskDTO;
|
|
import com.qqflow.engine.domain.flow.dto.ApprovalTaskDTO;
|
|
|
|
|
+import com.qqflow.engine.domain.flow.mapper.ProcessDefinitionMapper;
|
|
|
|
|
+import com.qqflow.engine.domain.flow.mapper.ProcessInstanceMapper;
|
|
|
|
|
+import com.qqflow.engine.domain.flow.model.FlowModel;
|
|
|
|
|
+import com.qqflow.engine.domain.flow.model.FlowNode;
|
|
|
|
|
+import com.qqflow.engine.domain.flow.model.SubNodeConfig;
|
|
|
|
|
+import com.qqflow.engine.domain.flow.po.ProcessDefinition;
|
|
|
|
|
+import com.qqflow.engine.domain.flow.po.ProcessInstance;
|
|
|
import com.qqflow.engine.domain.system.entity.SysRole;
|
|
import com.qqflow.engine.domain.system.entity.SysRole;
|
|
|
import com.qqflow.engine.domain.system.entity.SysUser;
|
|
import com.qqflow.engine.domain.system.entity.SysUser;
|
|
|
import com.qqflow.engine.domain.system.mapper.SysRoleMapper;
|
|
import com.qqflow.engine.domain.system.mapper.SysRoleMapper;
|
|
@@ -10,8 +19,10 @@ import org.springframework.stereotype.Component;
|
|
|
import org.springframework.util.CollectionUtils;
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
|
|
|
+import java.util.HashSet;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
|
|
+import java.util.Objects;
|
|
|
import java.util.Set;
|
|
import java.util.Set;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
@@ -26,6 +37,9 @@ public class ApprovalTaskDTOAssembler {
|
|
|
|
|
|
|
|
private final SysUserMapper sysUserMapper;
|
|
private final SysUserMapper sysUserMapper;
|
|
|
private final SysRoleMapper sysRoleMapper;
|
|
private final SysRoleMapper sysRoleMapper;
|
|
|
|
|
+ private final ProcessInstanceMapper processInstanceMapper;
|
|
|
|
|
+ private final ProcessDefinitionMapper processDefinitionMapper;
|
|
|
|
|
+ private final ObjectMapper objectMapper;
|
|
|
|
|
|
|
|
public void fillAssigneeName(List<ApprovalTaskDTO> records) {
|
|
public void fillAssigneeName(List<ApprovalTaskDTO> records) {
|
|
|
if (CollectionUtils.isEmpty(records)) {
|
|
if (CollectionUtils.isEmpty(records)) {
|
|
@@ -66,4 +80,95 @@ public class ApprovalTaskDTOAssembler {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按流程定义的子节点配置填充任务 DTO 的 subNodeName(子节点名称)。
|
|
|
|
|
+ * 任务表仅保存 subNodeId,子节点名称需从对应流程定义模型的 properties.subNodes 解析。
|
|
|
|
|
+ */
|
|
|
|
|
+ public void fillSubNodeName(List<ApprovalTaskDTO> records) {
|
|
|
|
|
+ if (CollectionUtils.isEmpty(records)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ List<ApprovalTaskDTO> withSub = records.stream()
|
|
|
|
|
+ .filter(r -> r.getSubNodeId() != null && !r.getSubNodeId().isBlank())
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ if (withSub.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Set<Long> instanceIds = withSub.stream()
|
|
|
|
|
+ .map(ApprovalTaskDTO::getInstanceId)
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ if (instanceIds.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ List<ProcessInstance> instances = this.processInstanceMapper.selectBatchIds(instanceIds);
|
|
|
|
|
+ Map<Long, Long> instanceDefMap = new HashMap<>();
|
|
|
|
|
+ Set<Long> defIds = new HashSet<>();
|
|
|
|
|
+ for (ProcessInstance pi : instances) {
|
|
|
|
|
+ if (pi == null || pi.getProcessDefinitionId() == null) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ instanceDefMap.put(pi.getId(), pi.getProcessDefinitionId());
|
|
|
|
|
+ defIds.add(pi.getProcessDefinitionId());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (defIds.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ // definitionId -> (nodeId -> (subNodeId -> subNodeName))
|
|
|
|
|
+ Map<Long, Map<String, Map<String, String>>> cache = new HashMap<>();
|
|
|
|
|
+ for (Long defId : defIds) {
|
|
|
|
|
+ ProcessDefinition def = this.processDefinitionMapper.selectById(defId);
|
|
|
|
|
+ if (def == null || def.getModelJson() == null) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ FlowModel model = this.objectMapper.readValue(def.getModelJson(), FlowModel.class);
|
|
|
|
|
+ Map<String, Map<String, String>> nodeSubMap = new HashMap<>();
|
|
|
|
|
+ if (model != null && model.getNodes() != null) {
|
|
|
|
|
+ for (FlowNode node : model.getNodes()) {
|
|
|
|
|
+ Object subNodesObj = node.getProperties() != null ? node.getProperties().get("subNodes") : null;
|
|
|
|
|
+ if (subNodesObj == null) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ List<SubNodeConfig> subNodes = this.objectMapper.convertValue(
|
|
|
|
|
+ subNodesObj, new TypeReference<List<SubNodeConfig>>() {});
|
|
|
|
|
+ if (CollectionUtils.isEmpty(subNodes)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<String, String> subNameMap = new HashMap<>();
|
|
|
|
|
+ for (SubNodeConfig sn : subNodes) {
|
|
|
|
|
+ if (sn.getId() != null) {
|
|
|
|
|
+ subNameMap.put(sn.getId(), sn.getName());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!subNameMap.isEmpty()) {
|
|
|
|
|
+ nodeSubMap.put(node.getId(), subNameMap);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ cache.put(defId, nodeSubMap);
|
|
|
|
|
+ } catch (Exception ignored) {
|
|
|
|
|
+ // 模型解析失败时该定义下的子节点名称保持为空
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ for (ApprovalTaskDTO record : withSub) {
|
|
|
|
|
+ Long defId = instanceDefMap.get(record.getInstanceId());
|
|
|
|
|
+ if (defId == null) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<String, Map<String, String>> nodeSubMap = cache.get(defId);
|
|
|
|
|
+ if (nodeSubMap == null) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<String, String> subNameMap = nodeSubMap.get(record.getNodeId());
|
|
|
|
|
+ if (subNameMap == null) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ String subName = subNameMap.get(record.getSubNodeId());
|
|
|
|
|
+ if (subName != null && !subName.isBlank()) {
|
|
|
|
|
+ record.setSubNodeName(subName);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|