Skip to content

Commit fcdd1f3

Browse files
committed
fix: upload zip
1 parent 43a5e4a commit fcdd1f3

1 file changed

Lines changed: 85 additions & 10 deletions

File tree

backend/services/data-management-service/src/main/java/com/datamate/datamanagement/application/DatasetFileApplicationService.java

Lines changed: 85 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import lombok.extern.slf4j.Slf4j;
3737
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
3838
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
39+
import org.apache.commons.io.FileUtils;
3940
import org.apache.commons.io.IOUtils;
4041
import org.apache.commons.lang3.StringUtils;
4142
import org.springframework.beans.factory.annotation.Autowired;
@@ -53,6 +54,7 @@
5354
import java.nio.file.Files;
5455
import java.nio.file.Path;
5556
import java.nio.file.Paths;
57+
import java.nio.file.StandardCopyOption;
5658
import java.nio.file.attribute.BasicFileAttributes;
5759
import java.time.LocalDateTime;
5860
import java.time.ZoneId;
@@ -364,18 +366,18 @@ public void downloadDatasetFileAsZip(String datasetId, HttpServletResponse respo
364366
}
365367
String datasetPath = dataset.getPath();
366368
Path downloadPath = Paths.get(datasetPath).normalize();
367-
369+
368370
// 检查路径是否存在
369371
if (!Files.exists(downloadPath) || !Files.isDirectory(downloadPath)) {
370372
throw BusinessException.of(DataManagementErrorCode.DATASET_NOT_FOUND);
371373
}
372-
374+
373375
response.setContentType("application/zip");
374376
String zipName = String.format("dataset_%s_%s.zip",
375377
dataset.getName() != null ? dataset.getName().replaceAll("[^a-zA-Z0-9_-]", "_") : "dataset",
376378
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
377379
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + zipName + "\"");
378-
380+
379381
try (ZipArchiveOutputStream zos = new ZipArchiveOutputStream(response.getOutputStream())) {
380382
try (Stream<Path> pathStream = Files.walk(downloadPath)) {
381383
pathStream
@@ -442,19 +444,25 @@ public String preUpload(UploadFilesPreRequest chunkUploadRequest, String dataset
442444
if (Objects.isNull(datasetRepository.getById(datasetId))) {
443445
throw BusinessException.of(DataManagementErrorCode.DATASET_NOT_FOUND);
444446
}
445-
447+
446448
// 构建上传路径,如果有 prefix 则追加到路径中
447449
String prefix = Optional.ofNullable(chunkUploadRequest.getPrefix()).orElse("").trim();
448450
prefix = prefix.replace("\\", "/");
449451
while (prefix.startsWith("/")) {
450452
prefix = prefix.substring(1);
451453
}
452-
453-
String uploadPath = datasetBasePath + File.separator + datasetId;
454-
if (!prefix.isEmpty()) {
455-
uploadPath = uploadPath + File.separator + prefix.replace("/", File.separator);
454+
455+
String uploadPath;
456+
// 如果需要解压,上传到全局临时目录以避免覆盖数据集中的同名文件
457+
if (chunkUploadRequest.isHasArchive()) {
458+
uploadPath = datasetBasePath + File.separator + ".temp_upload_" + System.currentTimeMillis();
459+
} else {
460+
uploadPath = datasetBasePath + File.separator + datasetId;
461+
if (!prefix.isEmpty()) {
462+
uploadPath = uploadPath + File.separator + prefix.replace("/", File.separator);
463+
}
456464
}
457-
465+
458466
ChunkUploadPreRequest request = ChunkUploadPreRequest.builder().build();
459467
request.setUploadPath(uploadPath);
460468
request.setTotalFileNum(chunkUploadRequest.getTotalFileNum());
@@ -512,8 +520,61 @@ private void saveFileInfoToDb(FileUploadResult fileUploadResult, String datasetI
512520
private void addFileToDataset(String datasetId, List<FileUploadResult> unpacked) {
513521
Dataset dataset = datasetRepository.getById(datasetId);
514522
dataset.setFiles(datasetFileRepository.findAllByDatasetId(datasetId));
523+
524+
// 收集所有临时目录,在文件处理完后统一删除
525+
Set<String> tempDirsToDelete = new HashSet<>();
526+
515527
for (FileUploadResult file : unpacked) {
516528
File savedFile = file.getSavedFile();
529+
String filePath = savedFile.getPath();
530+
531+
// 如果文件在临时目录(从解压的上传来),移动到数据集目录
532+
if (filePath.contains(".temp_upload_")) {
533+
try {
534+
// 提取临时目录之后的部分(保持相对路径结构)
535+
int tempIndex = filePath.indexOf(".temp_upload_");
536+
537+
// 找到 .temp_upload_{timestamp}/ 之后的内容
538+
// 临时目录格式: /dataset/.temp_upload_{timestamp}/
539+
int afterTimestamp = filePath.indexOf(File.separator, tempIndex + ".temp_upload_".length());
540+
if (afterTimestamp == -1) {
541+
// 没有分隔符,说明文件就在临时目录根下
542+
afterTimestamp = filePath.length();
543+
}
544+
545+
String tempDir = filePath.substring(0, afterTimestamp);
546+
String relativePath = filePath.substring(afterTimestamp);
547+
548+
// 去掉相对路径开头的分隔符
549+
if (relativePath.startsWith(File.separator)) {
550+
relativePath = relativePath.substring(1);
551+
}
552+
553+
// 构建目标路径:数据集根目录 + 相对路径
554+
String targetPath = datasetBasePath + File.separator + datasetId;
555+
if (!relativePath.isEmpty()) {
556+
targetPath = targetPath + File.separator + relativePath;
557+
}
558+
559+
File targetFile = new File(targetPath);
560+
// 创建父目录
561+
FileUtils.createParentDirectories(targetFile);
562+
563+
// 移动文件(覆盖已存在的文件)
564+
Files.move(savedFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
565+
log.info("Moved file from temp dir: {} -> {}", savedFile.getPath(), targetPath);
566+
567+
// 收集临时目录,稍后删除
568+
tempDirsToDelete.add(tempDir);
569+
570+
// 更新文件引用
571+
savedFile = targetFile;
572+
} catch (IOException e) {
573+
log.error("Failed to move file from temp directory: {}", filePath, e);
574+
continue; // 跳过此文件
575+
}
576+
}
577+
517578
LocalDateTime currentTime = LocalDateTime.now();
518579
// 统一 fileName:无论是否通过文件夹/压缩包上传,都只保留纯文件名
519580
String originalFileName = file.getFileName();
@@ -539,6 +600,20 @@ private void addFileToDataset(String datasetId, List<FileUploadResult> unpacked)
539600
datasetFileRepository.saveOrUpdate(datasetFile);
540601
dataset.addFile(datasetFile);
541602
}
603+
604+
// 递归删除所有临时目录
605+
for (String tempDir : tempDirsToDelete) {
606+
try {
607+
File tempDirFile = new File(tempDir);
608+
if (tempDirFile.exists() && tempDirFile.isDirectory()) {
609+
org.apache.commons.io.FileUtils.deleteDirectory(tempDirFile);
610+
log.info("Deleted temp directory: {}", tempDir);
611+
}
612+
} catch (IOException e) {
613+
log.warn("Failed to delete temp directory: {}", tempDir, e);
614+
}
615+
}
616+
542617
dataset.active();
543618
datasetRepository.updateById(dataset);
544619
}
@@ -623,7 +698,7 @@ public void downloadDirectory(String datasetId, String prefix, HttpServletRespon
623698
try {
624699
response.setContentType("application/zip");
625700
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + zipFileName + "\"");
626-
701+
627702
try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(response.getOutputStream())) {
628703
zipDirectory(normalized, normalized, zipOut);
629704
zipOut.finish();

0 commit comments

Comments
 (0)