Jelajahi Sumber

修复影像上传问题

gengjunfang 1 Minggu lalu
induk
melakukan
43274eaa67

+ 93 - 30
src/main/java/com/zskk/qcns/modules/dicom/service/impl/DicomServiceImpl.java

@@ -283,32 +283,50 @@ public class DicomServiceImpl implements DicomService {
             log.info("找到已存在的检查记录,将更新: studyId={}, studyInstanceUid={}",
                 studyInfo.getStudyId(), studyInfo.getStudyInstanceUid());
 
-            // 更新上传时间和文件路径
-            studyInfo.setUploadTime(LocalDateTime.now());
-            studyInfo.setUpdateTime(LocalDateTime.now());
-
-            // 重新统计序列和图像数
-            java.util.Set<Integer> uniqueSeriesNumbers = new java.util.HashSet<>();
-            for (File file : studyFiles) {
-                try {
-                    DicomParser.DicomData dicomData = DicomParser.parse(file);
-                    if (dicomData.getSeriesNumber() != null) {
-                        uniqueSeriesNumbers.add(dicomData.getSeriesNumber());
+            // 保存新文件到目录(内部按SOPInstanceUID去重:不存在的新增,已存在的覆盖)
+            saveStudyFiles(studyInstanceUid, studyFiles, institutionId);
+
+            // 根据目录中实际文件重新统计序列和图像数
+            String studyDirPath = DICOM_ROOT_PATH + studyInfo.getDicomFilePath();
+            File studyDir = new File(studyDirPath);
+            File[] allDicomFiles = studyDir.listFiles((dir, name) ->
+                name.toLowerCase().endsWith(".dcm") || name.toLowerCase().endsWith(".dicom"));
+
+            java.util.Set<String> allSeriesUids = new java.util.HashSet<>();
+            int totalImageCount = 0;
+            if (allDicomFiles != null) {
+                totalImageCount = allDicomFiles.length;
+                for (File file : allDicomFiles) {
+                    try {
+                        DicomParser.DicomData dicomData = DicomParser.parse(file);
+                        String seriesUid = dicomData.getSeriesInstanceUID();
+                        if (seriesUid != null && !seriesUid.isEmpty()) {
+                            allSeriesUids.add(seriesUid);
+                        }
+                    } catch (Exception e) {
+                        log.warn("解析文件失败: {}", file.getName(), e);
                     }
-                } catch (Exception e) {
-                    log.warn("解析文件失败: {}", file.getName(), e);
                 }
             }
 
-            // 更新统计信息
-            int seriesCount = uniqueSeriesNumbers.size() > 0 ? uniqueSeriesNumbers.size() : 1;
-            studyInfo.setSeriesCount(studyInfo.getSeriesCount() + seriesCount);
-            studyInfo.setImageCount(studyInfo.getImageCount() + studyFiles.size());
+            // 更新统计信息(使用实际值,而非累加)
+            studyInfo.setSeriesCount(allSeriesUids.size() > 0 ? allSeriesUids.size() : 1);
+            studyInfo.setImageCount(totalImageCount);
+            studyInfo.setUploadTime(LocalDateTime.now());
+            studyInfo.setUpdateTime(LocalDateTime.now());
 
             studyInfoMapper.updateById(studyInfo);
-            log.info("更新检查记录: studyId={}, 新的seriesCount={}, 新的imageCount={}",
+            log.info("更新检查记录: studyId={}, seriesCount={}, imageCount={}",
                 studyInfo.getStudyId(), studyInfo.getSeriesCount(), studyInfo.getImageCount());
 
+            // 重新异步解析序列详细信息
+            try {
+                dicomAsyncService.parseStudySeriesAsync(studyInfo.getStudyId());
+                log.info("已启动异步重新解析序列任务: studyId={}", studyInfo.getStudyId());
+            } catch (Exception e) {
+                log.error("启动异步解析失败: studyId={}", studyInfo.getStudyId(), e);
+            }
+
         } else {
             // 不存在,创建新记录
             studyInfo = new StudyInfo();
@@ -580,15 +598,58 @@ public class DicomServiceImpl implements DicomService {
 
         log.info("创建study目录: {}", targetDirPath);
 
-        // 复制所有文件到目标目录
-        for (File sourceFile : sourceFiles) {
-            String fileId = IdUtil.simpleUUID();
-            String targetFileName = fileId + ".dcm";
-            Path targetPath = targetDir.resolve(targetFileName);
+        // 1. 扫描目录中已有文件,建立 SOPInstanceUID -> 文件路径 的映射
+        java.util.Map<String, File> existingSopMap = new java.util.HashMap<>();
+        File[] existingFiles = targetDir.toFile().listFiles((dir, name) ->
+            name.toLowerCase().endsWith(".dcm") || name.toLowerCase().endsWith(".dicom"));
+        if (existingFiles != null) {
+            for (File existingFile : existingFiles) {
+                try {
+                    DicomParser.DicomData data = DicomParser.parse(existingFile);
+                    String sopUid = data.getSopInstanceUID();
+                    if (sopUid != null && !sopUid.isEmpty()) {
+                        existingSopMap.put(sopUid, existingFile);
+                    }
+                } catch (Exception e) {
+                    log.warn("解析已有DICOM文件失败: {}", existingFile.getName(), e);
+                }
+            }
+        }
+        log.info("目录中已有 {} 个DICOM文件", existingSopMap.size());
 
-            Files.copy(sourceFile.toPath(), targetPath, StandardCopyOption.REPLACE_EXISTING);
-            log.debug("复制文件: {} -> {}", sourceFile.getName(), targetFileName);
+        // 2. 处理新上传的文件:已存在的覆盖更新,不存在的新增
+        int newCount = 0, updateCount = 0;
+        for (File sourceFile : sourceFiles) {
+            try {
+                DicomParser.DicomData dicomData = DicomParser.parse(sourceFile);
+                String sopUid = dicomData.getSopInstanceUID();
+
+                if (sopUid != null && existingSopMap.containsKey(sopUid)) {
+                    // 已存在,覆盖更新
+                    File existingFile = existingSopMap.get(sopUid);
+                    Files.copy(sourceFile.toPath(), existingFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+                    log.debug("更新已有文件: sopInstanceUid={}, file={}", sopUid, existingFile.getName());
+                    updateCount++;
+                } else {
+                    // 不存在,新增
+                    String fileId = IdUtil.simpleUUID();
+                    String targetFileName = fileId + ".dcm";
+                    Path targetPath = targetDir.resolve(targetFileName);
+                    Files.copy(sourceFile.toPath(), targetPath, StandardCopyOption.REPLACE_EXISTING);
+                    log.debug("新增文件: sopInstanceUid={}, file={}", sopUid, targetFileName);
+                    newCount++;
+                }
+            } catch (Exception e) {
+                // 解析失败的文件仍然保存
+                String fileId = IdUtil.simpleUUID();
+                String targetFileName = fileId + ".dcm";
+                Path targetPath = targetDir.resolve(targetFileName);
+                Files.copy(sourceFile.toPath(), targetPath, StandardCopyOption.REPLACE_EXISTING);
+                log.warn("解析失败,直接保存: {}", sourceFile.getName(), e);
+                newCount++;
+            }
         }
+        log.info("文件处理完成: 新增={}, 更新={}", newCount, updateCount);
 
         return relativePath;
     }
@@ -1507,11 +1568,13 @@ public class DicomServiceImpl implements DicomService {
             }
         }
 
-        // 按实例号排序
-        imageList.sort(Comparator.comparing(
-            com.zskk.qcns.modules.dicom.vo.StudyImageVO::getInstanceNumber,
-            Comparator.nullsLast(Integer::compareTo)
-        ));
+        // 按序列号和实例号排序(先按序列分组,再按实例号排序)
+        imageList.sort(Comparator
+            .comparing(com.zskk.qcns.modules.dicom.vo.StudyImageVO::getSeriesNumber,
+                Comparator.nullsLast(Integer::compareTo))
+            .thenComparing(com.zskk.qcns.modules.dicom.vo.StudyImageVO::getInstanceNumber,
+                Comparator.nullsLast(Integer::compareTo))
+        );
 
         log.info("获取检查图像成功: studyId={}, imageCount={}", studyId, imageList.size());
         return imageList;