|
@@ -1,19 +1,189 @@
|
|
|
package org.springblade.archive.external.impl;
|
|
|
|
|
|
import lombok.AllArgsConstructor;
|
|
|
+import org.springblade.archive.entity.ArchivesAuto;
|
|
|
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.ArchiveAutoVo;
|
|
|
import org.springblade.archive.trans.ArchiveReq;
|
|
|
+import org.springblade.business.entity.ArchiveFile;
|
|
|
+import org.springblade.common.utils.SnowFlakeUtil;
|
|
|
+import org.springblade.manager.entity.ArchiveTreeContract;
|
|
|
+import org.springframework.dao.DataAccessException;
|
|
|
+import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
@Service
|
|
|
@AllArgsConstructor
|
|
|
public class ExternalDataArchiveMetaService {
|
|
|
|
|
|
+ private final JdbcTemplate jdbcTemplate;
|
|
|
+
|
|
|
+ private ExecutorService executorService;
|
|
|
+
|
|
|
+ private ArchivesAutoMapper autoMapper;
|
|
|
public void handleArchiveMetas(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo){
|
|
|
syncData(projectId, req, externalDataInfo);
|
|
|
}
|
|
|
|
|
|
public void syncData(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo) {
|
|
|
+ List<Map<String, Object>> addMetaDatas = new ArrayList<>();
|
|
|
+ List<Map<String, Object>> upMetaDatas = new ArrayList<>();
|
|
|
+
|
|
|
+ ArchiveTreeContract rootNode = externalDataInfo.getParent();
|
|
|
+ String contractId = rootNode.getContractId().toString();
|
|
|
+ Long rootId = externalDataInfo.getPid();
|
|
|
+
|
|
|
+ List<Long> fileIds = new ArrayList<>();
|
|
|
+
|
|
|
+ List<Map<String, Object>> externalMetas = listConvert(req.getNodeId(), req.getMetas(), externalDataInfo);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ fileIds = externalMetas.stream()
|
|
|
+ .filter(Objects::nonNull) // 过滤null的Map
|
|
|
+ .map(map -> map.get("file_id")) // 提取值
|
|
|
+ .filter(Objects::nonNull) // 过滤null值
|
|
|
+ .map(obj -> {
|
|
|
+ try {
|
|
|
+ return ((Number) obj).longValue(); // 支持所有Number类型
|
|
|
+ } catch (ClassCastException e) {
|
|
|
+ return null; // 转换失败返回null
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .filter(Objects::nonNull) // 过滤转换失败的null
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<Map<String, Object>> localMetas = getLocalMetas(projectId, fileIds);
|
|
|
+
|
|
|
+
|
|
|
+ getAddAndUpdatemMetas(
|
|
|
+ externalDataInfo,
|
|
|
+ externalMetas,
|
|
|
+ localMetas,
|
|
|
+ addMetaDatas,
|
|
|
+ upMetaDatas);
|
|
|
+ //异步执行
|
|
|
+ executorService.execute(()->{
|
|
|
+
|
|
|
+ addAndUpdateFiles(addMetaDatas,upMetaDatas,contractId,externalDataInfo);
|
|
|
+
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 获取本地文件
|
|
|
+ private List<Map<String, Object>> getLocalMetas(Long projectId, List<Long> fileIds) {
|
|
|
+ List<Map<String, Object>> localMetas = new ArrayList<>();
|
|
|
+ if (fileIds!= null && fileIds.size() > 0) {
|
|
|
+ localMetas = autoMapper.getMetadaFileByFileIds(fileIds);
|
|
|
+ }
|
|
|
+ return localMetas;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<Map<String, Object>> listConvert(String nodeId, List<Object> metaObjects, ExternalDataInfo externalDataInfo) {
|
|
|
+ List<Map<String, Object>> metas = new ArrayList<>();
|
|
|
+ Map<String, Long> fileIdMapping = externalDataInfo.getFileIdMapping();
|
|
|
+
|
|
|
+ for (Object obj :metaObjects) {
|
|
|
+ Map<String, Object> metaData = (Map<String, Object>)obj;
|
|
|
+
|
|
|
+ if (metaData.get("process_id")== null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ String outFileId = (String)metaData.get("process_id");
|
|
|
+
|
|
|
+ Long fileId = fileIdMapping.get(outFileId);
|
|
|
+ if (fileId == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ metaData.put("file_id",fileId);
|
|
|
+ metaData.put("meta_id", SnowFlakeUtil.getId());
|
|
|
+ metas.add(metaData);
|
|
|
+ }
|
|
|
+
|
|
|
+ return metas;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void getAddAndUpdatemMetas(
|
|
|
+ ExternalDataInfo externalDataInfo,
|
|
|
+ List<Map<String, Object>> externalMetas,
|
|
|
+ List<Map<String, Object>> localMetas,
|
|
|
+ List<Map<String, Object>> addMetas,
|
|
|
+ List<Map<String, Object>> upMetas) {
|
|
|
+
|
|
|
+ // 构建本地file_id快速查找集合(时间复杂度O(n))
|
|
|
+ Set<Long> localFileIds = localMetas.stream()
|
|
|
+ .filter(Objects::nonNull) // 过滤空记录
|
|
|
+ .map(meta -> safeGetLong(meta.get("file_id"))) // 安全转换
|
|
|
+ .filter(Objects::nonNull) // 过滤无效ID
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 流式处理外部数据(时间复杂度O(m))
|
|
|
+ externalMetas.stream()
|
|
|
+ .filter(Objects::nonNull) // 过滤空记录
|
|
|
+ .filter(meta -> {
|
|
|
+ Long fileId = safeGetLong(meta.get("file_id"));
|
|
|
+ return fileId != null && !localFileIds.contains(fileId);
|
|
|
+ })
|
|
|
+ .forEach(addMetas::add); // 添加新增数据
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 安全转换为Long类型(支持多种数据类型)
|
|
|
+ */
|
|
|
+ private Long safeGetLong(Object value) {
|
|
|
+ if (value == null) return null;
|
|
|
+ try {
|
|
|
+ if (value instanceof Long) return (Long) value;
|
|
|
+ if (value instanceof Number) return ((Number) value).longValue();
|
|
|
+ if (value instanceof String) return Long.parseLong((String) value);
|
|
|
+ } catch (NumberFormatException ignored) {
|
|
|
+ // 记录日志:非法数值格式
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public void addAndUpdateFiles(List<Map<String, Object>> addMetaDatas,
|
|
|
+ List<Map<String, Object>> upMetaDatas,
|
|
|
+ String contractId, ExternalDataInfo externalDataInfo) {
|
|
|
+
|
|
|
+ // 批量新增处理
|
|
|
+ if (addMetaDatas != null && !addMetaDatas.isEmpty()) {
|
|
|
+ int batchSize = 10;
|
|
|
+ for (int i = 0; i < addMetaDatas.size(); i += batchSize) {
|
|
|
+ // 分页获取子列表
|
|
|
+ int toIndex = Math.min(i + batchSize, addMetaDatas.size());
|
|
|
+ List<Map<String, Object>> batchList = addMetaDatas.subList(i, toIndex);
|
|
|
+
|
|
|
+ // 生成批量SQL(假设externalDataInfo是类成员变量)
|
|
|
+ String sql = TransUtil.generateMetadataSql(externalDataInfo, batchList, contractId);
|
|
|
+
|
|
|
+ // 处理特殊字符(根据需求移除转义符)
|
|
|
+ String cleanSql = sql.replaceAll("\\\\", "");
|
|
|
+
|
|
|
+ // 执行SQL
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute(cleanSql);
|
|
|
+ } catch (DataAccessException e) {
|
|
|
+ // 添加错误处理(例如记录日志+抛出业务异常)
|
|
|
+ throw new RuntimeException("批量插入元数据失败,位置[" + i + "-" + toIndex + "]", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ // 更新处理(根据需求补充逻辑)
|
|
|
+ if (upMetaDatas != null && !upMetaDatas.isEmpty()) {
|
|
|
+ // 这里补充更新逻辑(示例代码未实现)
|
|
|
+ }
|
|
|
}
|
|
|
}
|