|
@@ -1,19 +1,112 @@
|
|
|
package org.springblade.archive.external.impl;
|
|
|
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
import org.springblade.archive.external.bean.ExternalDataInfo;
|
|
|
+import org.springblade.archive.external.utils.TransUtil;
|
|
|
+import org.springblade.archive.mapper.ArchivesAutoMapper;
|
|
|
+import org.springblade.archive.trans.ArchiveReq;
|
|
|
+import org.springblade.archive.trans.ArchiveTreeVo;
|
|
|
import org.springblade.business.entity.ArchiveFile;
|
|
|
+import org.springblade.common.utils.SnowFlakeUtil;
|
|
|
import org.springblade.manager.entity.ArchiveTreeContract;
|
|
|
+import org.springblade.manager.feign.ArchiveTreeContractClient;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
+
|
|
|
@Service
|
|
|
+@AllArgsConstructor
|
|
|
public class ExternalDataArchiveTreeService {
|
|
|
+ private final ArchiveTreeContractClient archiveTreeContractClient;
|
|
|
+ private ArchivesAutoMapper autoMapper;
|
|
|
+
|
|
|
+ public ExternalDataInfo getDataByIds(String nodeId, String remoteId){
|
|
|
+ ExternalDataInfo externalDataInfo = TransUtil.getDataByIds(nodeId, remoteId);
|
|
|
+
|
|
|
+ if (externalDataInfo.getParent() == null) {
|
|
|
+ ArchiveTreeContract archiveTreeContract = archiveTreeContractClient.getArchiveTreeContractById(externalDataInfo.getPid());
|
|
|
+ externalDataInfo.setParent(archiveTreeContract);
|
|
|
+ }
|
|
|
+ return externalDataInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void handleArchiveTreesBegin(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo){
|
|
|
+ //初始化
|
|
|
+ externalDataInfo.Init();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void handleArchiveTrees(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo){
|
|
|
+ List<ArchiveTreeVo> archiveTreeVos = req.getTrees();
|
|
|
+ List<ArchiveTreeVo> ArchiveTreeContract = req.getTrees();
|
|
|
+ externalDataInfo.addArchives(req.getTrees());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void handleArchiveTreesFinish(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo){
|
|
|
+ syncData(projectId,req,externalDataInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<ArchiveTreeContract> listConvert(String nodeId,List<ArchiveTreeVo> archiveTreeVos, ExternalDataInfo externalDataInfo) {
|
|
|
+
|
|
|
+ List<ArchiveTreeContract> archiveTreeContracts = new ArrayList<>();
|
|
|
+ Map<String, Long> archiveTreeNodeIdMapping = new LinkedHashMap<>();
|
|
|
+ Long rootId = externalDataInfo.getPid();
|
|
|
+ ArchiveTreeContract rootNode = externalDataInfo.getParent();
|
|
|
+
|
|
|
+ // 1. 生成所有节点的唯一新ID并建立映射
|
|
|
+ for (ArchiveTreeVo advertTreeVo : archiveTreeVos) {
|
|
|
+ //根节点也映射
|
|
|
+ if (advertTreeVo.getId().equals(nodeId)) {
|
|
|
+ archiveTreeNodeIdMapping.put(nodeId, rootId);
|
|
|
+ }
|
|
|
+ archiveTreeNodeIdMapping.put(advertTreeVo.getId(), SnowFlakeUtil.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 遍历所有节点,构建ArchiveTreeContract对象
|
|
|
+ for (ArchiveTreeVo advertTreeVo : archiveTreeVos) {
|
|
|
+
|
|
|
+ //根节点不需要新政
|
|
|
+ if (advertTreeVo.getId().equals(nodeId)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ ArchiveTreeContract treeContract = new ArchiveTreeContract();
|
|
|
+
|
|
|
+ // 拷贝rootNode的属性到当前节点(如名称、类型等元数据)
|
|
|
+ if (rootNode != null) {
|
|
|
+ BeanUtils.copyProperties(rootNode, treeContract); // 使用Spring BeanUtils
|
|
|
+ }
|
|
|
|
|
|
- public void syncData(ExternalDataInfo externalDataInfo) {
|
|
|
+ // 设置新ID(从映射表中获取)
|
|
|
+ Long newNodeId = archiveTreeNodeIdMapping.get(advertTreeVo.getId());
|
|
|
+ treeContract.setId(newNodeId);
|
|
|
+ treeContract.setOutId(advertTreeVo.getId());
|
|
|
+
|
|
|
+ //核心转化
|
|
|
+ treeContract.fromExternal(advertTreeVo);
|
|
|
+
|
|
|
+ // 设置父ID逻辑:
|
|
|
+ String originalParentId = advertTreeVo.getPid();
|
|
|
+ Long parentId = archiveTreeNodeIdMapping.get(originalParentId); // 查找映射表
|
|
|
+ if (parentId == null) {
|
|
|
+ parentId = rootId; // 映射不存在则指向根ID
|
|
|
+ }
|
|
|
+ treeContract.setParentId(parentId);
|
|
|
+
|
|
|
+ // 将构建好的对象加入结果列表
|
|
|
+ archiveTreeContracts.add(treeContract);
|
|
|
+ }
|
|
|
+
|
|
|
+ //保存
|
|
|
+ externalDataInfo.setArchiveTreeNodeIdMapping(archiveTreeNodeIdMapping);
|
|
|
+
|
|
|
+ return archiveTreeContracts;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void syncData(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo) {
|
|
|
// 新增的合同列表
|
|
|
List<ArchiveTreeContract> addContracts = new ArrayList<>();
|
|
|
|
|
@@ -21,15 +114,17 @@ public class ExternalDataArchiveTreeService {
|
|
|
List<ArchiveTreeContract> upContracts = new ArrayList<>();
|
|
|
|
|
|
// 获取外部系统合同数据
|
|
|
- List<ArchiveTreeContract> externalContracts = getExternalContracts(
|
|
|
- externalDataInfo.getProjectName(),
|
|
|
- externalDataInfo
|
|
|
- );
|
|
|
+ List<ArchiveTreeContract> externalContracts = listConvert(req.getNodeId(), externalDataInfo.getArchives(),externalDataInfo);
|
|
|
+
|
|
|
+ List<String> outIds = Optional.ofNullable(externalContracts)
|
|
|
+ .orElseGet(Collections::emptyList)
|
|
|
+ .stream()
|
|
|
+ .map(ArchiveTreeContract::getOutId) // 假设 getOutId() 返回 String
|
|
|
+ .filter(Objects::nonNull) // 可选:过滤 null 值
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
|
// 获取本地存储的合同数据
|
|
|
- List<ArchiveTreeContract> localContracts = getLocalContracts(
|
|
|
- externalDataInfo.getProjectName()
|
|
|
- );
|
|
|
+ List<ArchiveTreeContract> localContracts = getLocalContracts(projectId,outIds);
|
|
|
|
|
|
// 比对差异获取需新增/更新的合同
|
|
|
getAddAndUpdateContracts(
|
|
@@ -45,28 +140,28 @@ public class ExternalDataArchiveTreeService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取本地合同数据
|
|
|
- * @param projectName 项目名称
|
|
|
- * @return 本地合同列表
|
|
|
+ *
|
|
|
+ * @param projectId
|
|
|
+ * @return
|
|
|
*/
|
|
|
- private List<ArchiveTreeContract> getLocalContracts(String projectName) {
|
|
|
- List<ArchiveTreeContract> localContracts = new ArrayList<>();
|
|
|
- // 模拟实现:根据项目名称查询数据库获取本地合同
|
|
|
- // 示例伪代码:localContracts = contractMapper.selectByProject(projectName);
|
|
|
+ private List<ArchiveTreeContract> getLocalContracts(Long projectId) {
|
|
|
+ List<ArchiveTreeContract> localContracts = archiveTreeContractClient.getOutNodes(projectId);
|
|
|
return localContracts;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取外部系统合同数据(需实现)
|
|
|
- * @param projectName 项目名称
|
|
|
- * @param externalData 外部数据参数
|
|
|
- * @return 外部系统合同列表
|
|
|
+ *
|
|
|
+ * @param projectId
|
|
|
+ * @return
|
|
|
*/
|
|
|
- private List<ArchiveTreeContract> getExternalContracts(String projectName, ExternalDataInfo externalData) {
|
|
|
- // 待实现:调用外部系统接口获取合同数据
|
|
|
- return new ArrayList<>();
|
|
|
+ private List<ArchiveTreeContract> getLocalContracts(Long projectId, List<String> outIds) {
|
|
|
+
|
|
|
+ List<ArchiveTreeContract> localContracts = autoMapper.getOutNodesByOutIds(projectId,outIds);
|
|
|
+ //List<ArchiveTreeContract> localContracts = archiveTreeContractClient.getOutNodesByOutIds(projectId,outIds);
|
|
|
+ return localContracts;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 执行新增/更新持久化操作(需实现)
|
|
|
* @param addContracts 新增合同集合
|
|
@@ -83,26 +178,40 @@ public class ExternalDataArchiveTreeService {
|
|
|
List<ArchiveTreeContract> addContracts,
|
|
|
List<ArchiveTreeContract> upContracts) {
|
|
|
|
|
|
- // 将外部合同转换为 Map,键为 ID,值为 ArchiveTreeContract
|
|
|
- Map<Long, ArchiveTreeContract> externalContractsMap = externalContracts.stream()
|
|
|
- .collect(Collectors.toMap(ArchiveTreeContract::getId, contract -> contract));
|
|
|
+ // 1. 提取本地合同的 outId 集合(用于快速判断外部合同是否已存在)
|
|
|
+ Set<String> localOutIdSet = localContracts.stream()
|
|
|
+ .map(ArchiveTreeContract::getOutId) // 直接使用本地合同的 outId 字段
|
|
|
+ .filter(outId -> outId != null && !outId.isEmpty()) // 过滤空值
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 2. 遍历外部合同,判断新增或更新
|
|
|
+ for (ArchiveTreeContract externalContract : externalContracts) {
|
|
|
+ String externalOutId = externalContract.getOutId();
|
|
|
|
|
|
- // 遍历本地合同,找出新增和更新的合同
|
|
|
- for (ArchiveTreeContract localContract : localContracts) {
|
|
|
- ArchiveTreeContract externalContract = externalContractsMap.get(localContract.getId());
|
|
|
- if (externalContract == null) {
|
|
|
- // 外部系统没有此合同,认为是新增合同
|
|
|
- addContracts.add(localContract);
|
|
|
+ // 处理空 outId(根据业务需求决定是否跳过或新增)
|
|
|
+ if (externalOutId == null || externalOutId.isEmpty()) {
|
|
|
+ // addContracts.add(externalContract); // 如果需要处理空 outId 则取消注释
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断外部 outId 是否存在于本地
|
|
|
+ if (!localOutIdSet.contains(externalOutId)) {
|
|
|
+ addContracts.add(externalContract); // 不存在则新增
|
|
|
} else {
|
|
|
- // 外部系统有此合同,比较更新时间
|
|
|
-// if (!externalContract.getOutUrl().equals(localContract.getOutUrl())) {
|
|
|
-// // 更新时间不同,认为是更新合同
|
|
|
-// localContract.setOutUrl(externalContract.getOutUrl());
|
|
|
-// upContracts.add(localContract);
|
|
|
-// }
|
|
|
+ // 存在则查找对应本地合同,判断是否需要更新
|
|
|
+// localContracts.stream()
|
|
|
+// .filter(localContract -> externalOutId.equals(localContract.getOutId()))
|
|
|
+// .findFirst()
|
|
|
+// .ifPresent(localContract -> {
|
|
|
+// // 示例:根据时间戳判断是否需要更新
|
|
|
+// if (externalContract.getUpdateTime().after(localContract.getUpdateTime())) {
|
|
|
+// upContracts.add(externalContract);
|
|
|
+// }
|
|
|
+// });
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
|
|
|
- }
|
|
|
}
|