Browse Source

推送平天路

huangtf 5 months ago
parent
commit
e63b453ca8

+ 4 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/MetadataClassificationClient.java

@@ -1,5 +1,6 @@
 package org.springblade.business.feign;
 
+import org.springblade.business.entity.MetadataClassification;
 import org.springblade.business.vo.MetadataClassificationVO;
 import org.springblade.common.constant.BusinessConstant;
 import org.springframework.cloud.openfeign.FeignClient;
@@ -25,4 +26,7 @@ public interface MetadataClassificationClient {
 
     @PostMapping(API_PREFIX + "/updateMetadata")
     boolean updateMetadata(@RequestBody MetadataClassificationVO vo);
+
+    @PostMapping(API_PREFIX + "/getMetadataClassification")
+    List<MetadataClassification> getMetadataClassification();
 }

+ 11 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/external/bean/ExternalDataInfo.java

@@ -1,6 +1,7 @@
 package org.springblade.archive.external.bean;
 
 import org.springblade.archive.trans.ArchiveTreeVo;
+import org.springblade.business.entity.MetadataClassification;
 import org.springblade.manager.entity.ArchiveTreeContract;
 
 import java.util.ArrayList;
@@ -27,6 +28,8 @@ public class ExternalDataInfo {
 
     private List<ArchiveTreeVo> archives = new ArrayList<>();
 
+    List<MetadataClassification> metadataClassifications = new ArrayList<>();
+
 
     //父节点
     private Long pid;
@@ -121,4 +124,12 @@ public class ExternalDataInfo {
     public void setPid(Long pid) {
         this.pid = pid;
     }
+
+    public List<MetadataClassification> getMetadataClassifications() {
+        return metadataClassifications;
+    }
+
+    public void setMetadataClassifications(List<MetadataClassification> metadataClassifications) {
+        this.metadataClassifications = metadataClassifications;
+    }
 }

+ 170 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveMetaService.java

@@ -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()) {
+            // 这里补充更新逻辑(示例代码未实现)
+        }
     }
 }

+ 11 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveTreeService.java

@@ -7,6 +7,8 @@ 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.business.entity.MetadataClassification;
+import org.springblade.business.feign.MetadataClassificationClient;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.manager.entity.ArchiveTreeContract;
 import org.springblade.manager.feign.ArchiveTreeContractClient;
@@ -22,6 +24,7 @@ import java.util.stream.Collectors;
 public class ExternalDataArchiveTreeService {
     private final ArchiveTreeContractClient archiveTreeContractClient;
     private ArchivesAutoMapper autoMapper;
+    private final MetadataClassificationClient metadataClassificationClient;
 
     public  ExternalDataInfo getDataByIds(String nodeId, String remoteId){
         ExternalDataInfo externalDataInfo = TransUtil.getDataByIds(nodeId, remoteId);
@@ -30,6 +33,14 @@ public class ExternalDataArchiveTreeService {
             ArchiveTreeContract archiveTreeContract = archiveTreeContractClient.getArchiveTreeContractById(externalDataInfo.getPid());
             externalDataInfo.setParent(archiveTreeContract);
         }
+
+        if (externalDataInfo.getMetadataClassifications()== null){
+            List<MetadataClassification> metadataClassificationList =   metadataClassificationClient.getMetadataClassification();
+            if (metadataClassificationList!= null ) {
+                externalDataInfo.setMetadataClassifications(metadataClassificationList);
+            }
+        }
+
         return externalDataInfo;
     }
 

+ 78 - 2
blade-service/blade-archive/src/main/java/org/springblade/archive/external/utils/TransUtil.java

@@ -1,9 +1,11 @@
 package org.springblade.archive.external.utils;
 
 import org.springblade.archive.external.bean.ExternalDataInfo;
+import org.springblade.business.entity.MetadataClassification;
+import org.springblade.common.utils.SnowFlakeUtil;
 
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.text.SimpleDateFormat;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -150,4 +152,78 @@ public class TransUtil {
         return getDataByExternalId(nodeId);
     }
 
+    public static String generateMetadataSql(ExternalDataInfo externalDataInfo, List<Map<String, Object>> metaDatas, String contractId) {
+        // 参数校验
+        if (metaDatas.isEmpty()) {
+            throw new IllegalArgumentException("metaDatas cannot be empty");
+        }
+
+        // 获取字段分类配置
+        List<MetadataClassification> classifications = externalDataInfo.getMetadataClassifications();
+
+        // 构建字段部分(固定字段 + 动态字段)
+        StringBuilder fieldBuilder = new StringBuilder()
+                .append("id, tenant_id, create_user, create_time, update_user, update_time, status, is_deleted, contract_id, file_id");
+
+        for (MetadataClassification mc : classifications) {
+            fieldBuilder.append(", ").append(mc.getFieldKey());
+        }
+
+        // 构建所有记录的VALUES部分
+        List<String> valuesList = new ArrayList<>();
+        for (Map<String, Object> metaData : metaDatas) {
+            // 提取必要字段
+            Object metaId = metaData.get("meta_id");
+            Object fileId = metaData.get("file_id");
+            if (metaId == null || fileId == null) {
+                throw new IllegalArgumentException("meta_id and file_id are required in each metadata");
+            }
+
+            // 构建keyValue映射
+            Map<String, Object> keyValue = new LinkedHashMap<>();
+            keyValue.put("关系", "引用");
+            keyValue.put("扫描分辨率", "300dpi");
+            keyValue.put("扫描色彩模式", "彩色");
+
+            // 转换元数据键名
+            for (Map.Entry<String, Object> entry : metaData.entrySet()) {
+                String label = TransUtil.LABEL_MAPPING.get(entry.getKey());
+                if (label != null) {
+                    keyValue.put(label, entry.getValue());
+                }
+            }
+
+            // 构建单条记录的VALUES
+            StringBuilder valueBuilder = new StringBuilder()
+                    .append(String.format("'%s', -1, -1, '%s', -1, '%s', 0, 0, '%s', '%s'",
+                            metaId,
+                            getCurrentDateTime(),
+                            getCurrentDateTime(),
+                            contractId,
+                            fileId));
+
+            // 添加动态字段值
+            for (MetadataClassification mc : classifications) {
+                Object value = keyValue.get(mc.getContainerName());
+                if (value != null) {
+                    valueBuilder.append(", '").append(value).append("'");
+                } else {
+                    valueBuilder.append(", NULL");
+                }
+            }
+
+            valuesList.add("(" + valueBuilder + ")");
+        }
+
+        // 构建完整SQL
+        return "INSERT INTO u_metadata_file (" +
+                fieldBuilder +
+                ") VALUES " +
+                String.join(", ", valuesList) + ";";
+    }
+
+    private static String getCurrentDateTime() {
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
+    }
+
 }

+ 3 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.java

@@ -32,6 +32,7 @@ import org.springblade.manager.entity.ArchiveTreeContract;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.user.entity.User;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -212,4 +213,6 @@ public interface ArchivesAutoMapper extends BaseMapper<ArchivesAuto> {
 	List<ArchivesAuto> getOutArchiveAutosByOutIds(@Param("projectId")Long projectId,@Param("ids") List<String> outIds);
 
 	List<ArchiveFile> getOutArchiveFilesByOutIds(@Param("projectId")Long projectId,@Param("ids") List<String> outIds);
+
+	List<Map<String, Object>> getMetadaFileByFileIds(@Param("fileIds") List<Long> fileIds);
 }

+ 9 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml

@@ -1368,6 +1368,15 @@
             #{id}
         </foreach>
     </select>
+    <select id="getMetadaFileByFileIds" resultType="java.util.Map">
+        SELECT *
+        FROM u_metadata_file
+        WHERE file_id IN
+        <foreach collection="fileIds" item="fileId" open="(" close=")" separator=",">
+            #{fileId}
+        </foreach>
+        ORDER BY file_id, create_time DESC
+    </select>
 
 
 </mapper>

+ 6 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/MetadataClassificationClientImpl.java

@@ -1,6 +1,7 @@
 package org.springblade.business.feignClient;
 
 import lombok.AllArgsConstructor;
+import org.springblade.business.entity.MetadataClassification;
 import org.springblade.business.feign.MetadataClassificationClient;
 import org.springblade.business.service.IMetadataClassificationService;
 import org.springblade.business.vo.MetadataClassificationVO;
@@ -30,4 +31,9 @@ public class MetadataClassificationClientImpl implements MetadataClassificationC
     public boolean updateMetadata(MetadataClassificationVO vo) {
         return iMetadataClassificationService.updateMetadata(vo);
     }
+
+    @Override
+    public List<MetadataClassification> getMetadataClassification() {
+        return iMetadataClassificationService.getMetadataClassification();
+    }
 }

+ 2 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/IMetadataClassificationService.java

@@ -24,4 +24,6 @@ public interface IMetadataClassificationService extends BaseService<MetadataClas
     List<MetadataClassificationVO> getMetadataFile(Long fileId);
 
     boolean updateMetadata(MetadataClassificationVO vo);
+
+    List<MetadataClassification> getMetadataClassification();
 }

+ 7 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/MetadataClassificationServiceImpl.java

@@ -559,4 +559,11 @@ public class MetadataClassificationServiceImpl
             itemizedProjectIdString.append("/");
         }
     }
+
+    public List<MetadataClassification> getMetadataClassification(){
+        QueryWrapper<MetadataClassification> metadata = new QueryWrapper<>();
+        metadata.lambda().eq(MetadataClassification::getIsDeleted, 0);
+        List<MetadataClassification> metadataClassifications = baseMapper.selectList(metadata);
+        return metadataClassifications ;
+    }
 }