Skip to content

Commit 186f4d4

Browse files
committed
feature:增加批量下载数据集文件为zip包的功能
1 parent 97e5992 commit 186f4d4

4 files changed

Lines changed: 62 additions & 8 deletions

File tree

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

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.dataengine.common.domain.model.FileUploadResult;
55
import com.dataengine.common.domain.service.FileService;
66
import com.dataengine.common.domain.utils.AnalyzerUtils;
7+
import com.dataengine.common.infrastructure.exception.BusinessException;
8+
import com.dataengine.common.infrastructure.exception.SystemErrorCode;
79
import com.dataengine.datamanagement.domain.contants.DatasetConstant;
810
import com.dataengine.datamanagement.domain.model.dataset.Dataset;
911
import com.dataengine.datamanagement.domain.model.dataset.DatasetFile;
@@ -16,6 +18,7 @@
1618
import com.dataengine.datamanagement.interfaces.dto.UploadFilesPreRequest;
1719
import com.fasterxml.jackson.core.JsonProcessingException;
1820
import com.fasterxml.jackson.databind.ObjectMapper;
21+
import jakarta.servlet.http.HttpServletResponse;
1922
import lombok.extern.slf4j.Slf4j;
2023
import org.apache.ibatis.session.RowBounds;
2124
import org.springframework.beans.factory.annotation.Autowired;
@@ -25,21 +28,27 @@
2528
import org.springframework.data.domain.Page;
2629
import org.springframework.data.domain.PageImpl;
2730
import org.springframework.data.domain.Pageable;
31+
import org.springframework.http.HttpHeaders;
2832
import org.springframework.stereotype.Service;
2933
import org.springframework.transaction.annotation.Transactional;
3034
import org.springframework.web.multipart.MultipartFile;
3135

36+
import java.io.BufferedInputStream;
3237
import java.io.File;
3338
import java.io.IOException;
39+
import java.io.InputStream;
3440
import java.net.MalformedURLException;
3541
import java.nio.file.Files;
3642
import java.nio.file.Path;
3743
import java.nio.file.Paths;
3844
import java.nio.file.StandardCopyOption;
3945
import java.time.LocalDateTime;
46+
import java.time.format.DateTimeFormatter;
4047
import java.util.List;
4148
import java.util.Objects;
4249
import java.util.UUID;
50+
import java.util.zip.ZipEntry;
51+
import java.util.zip.ZipOutputStream;
4352

4453
/**
4554
* 数据集文件应用服务
@@ -75,7 +84,7 @@ public DatasetFileApplicationService(DatasetFileRepository datasetFileRepository
7584
/**
7685
* 上传文件到数据集
7786
*/
78-
public DatasetFile uploadFile(String datasetId, MultipartFile file, String description, String uploadedBy) {
87+
public DatasetFile uploadFile(String datasetId, MultipartFile file) {
7988
Dataset dataset = datasetRepository.getById(datasetId);
8089
if (dataset == null) {
8190
throw new IllegalArgumentException("Dataset not found: " + datasetId);
@@ -182,6 +191,44 @@ public Resource downloadFile(String datasetId, String fileId) {
182191
}
183192
}
184193

194+
/**
195+
* 下载文件
196+
*/
197+
@Transactional(readOnly = true)
198+
public void downloadDatasetFileAsZip(String datasetId, HttpServletResponse response) {
199+
List<DatasetFile> allByDatasetId = datasetFileRepository.findAllByDatasetId(datasetId);
200+
response.setContentType("application/zip");
201+
String zipName = String.format("dataset_%s.zip",
202+
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
203+
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + zipName);
204+
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
205+
for (DatasetFile file : allByDatasetId) {
206+
addToZipFile(file, zos);
207+
}
208+
} catch (IOException e) {
209+
log.error("Failed to download files in batches.", e);
210+
throw BusinessException.of(SystemErrorCode.FILE_SYSTEM_ERROR);
211+
}
212+
}
213+
214+
private void addToZipFile(DatasetFile file, ZipOutputStream zos) throws IOException {
215+
if (file.getFilePath() == null || !Files.exists(Paths.get(file.getFilePath()))) {
216+
log.warn("The file hasn't been found on filesystem, id: {}", file.getId());
217+
return;
218+
}
219+
try (InputStream fis = Files.newInputStream(Paths.get(file.getFilePath()));
220+
BufferedInputStream bis = new BufferedInputStream(fis)) {
221+
ZipEntry zipEntry = new ZipEntry(file.getFileName());
222+
zos.putNextEntry(zipEntry);
223+
byte[] buffer = new byte[8192];
224+
int length;
225+
while ((length = bis.read(buffer)) >= 0) {
226+
zos.write(buffer, 0, length);
227+
}
228+
zos.closeEntry();
229+
}
230+
}
231+
185232
private String getFileExtension(String fileName) {
186233
if (fileName == null || fileName.isEmpty()) {
187234
return null;

backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/rest/DatasetFileController.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.dataengine.datamanagement.interfaces.dto.PagedDatasetFileResponse;
1111
import com.dataengine.datamanagement.interfaces.dto.UploadFileRequest;
1212
import com.dataengine.datamanagement.interfaces.dto.UploadFilesPreRequest;
13+
import jakarta.servlet.http.HttpServletResponse;
1314
import jakarta.validation.Valid;
1415
import lombok.extern.slf4j.Slf4j;
1516
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,6 +25,8 @@
2425
import org.springframework.web.bind.annotation.*;
2526
import org.springframework.web.multipart.MultipartFile;
2627

28+
import java.time.LocalDateTime;
29+
import java.time.format.DateTimeFormatter;
2730
import java.util.stream.Collectors;
2831

2932
/**
@@ -70,11 +73,9 @@ public ResponseEntity<Response<PagedDatasetFileResponse>> getDatasetFiles(
7073
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
7174
public ResponseEntity<Response<DatasetFileResponse>> uploadDatasetFile(
7275
@PathVariable("datasetId") String datasetId,
73-
@RequestPart(value = "file", required = false) MultipartFile file,
74-
@RequestParam(value = "description", required = false) String description) {
76+
@RequestPart(value = "file", required = false) MultipartFile file) {
7577
try {
76-
DatasetFile datasetFile = datasetFileApplicationService.uploadFile(
77-
datasetId, file, description, "system");
78+
DatasetFile datasetFile = datasetFileApplicationService.uploadFile(datasetId, file);
7879

7980
return ResponseEntity.status(HttpStatus.CREATED).body(Response.ok(DatasetConverter.INSTANCE.convertToResponse(datasetFile)));
8081
} catch (IllegalArgumentException e) {
@@ -111,7 +112,7 @@ public ResponseEntity<Response<Void>> deleteDatasetFile(
111112

112113
@IgnoreResponseWrap
113114
@GetMapping(value = "/{fileId}/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
114-
public ResponseEntity<Resource> downloadDatasetFile(
115+
public ResponseEntity<Resource> downloadDatasetFileById(
115116
@PathVariable("datasetId") String datasetId,
116117
@PathVariable("fileId") String fileId) {
117118
try {
@@ -130,6 +131,12 @@ public ResponseEntity<Resource> downloadDatasetFile(
130131
}
131132
}
132133

134+
@IgnoreResponseWrap
135+
@GetMapping(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
136+
public void downloadDatasetFileAsZip(@PathVariable("datasetId") String datasetId, HttpServletResponse response) {
137+
datasetFileApplicationService.downloadDatasetFileAsZip(datasetId, response);
138+
}
139+
133140
/**
134141
* 文件上传请求
135142
*

frontend/src/pages/DataManagement/dataset.api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function downloadFile(
6767
filename?: string
6868
) {
6969
return download(
70-
`/api/data-management/datasets/${id}/files/${fileId}/download`,
70+
`/api/data-management/datasets/${id}/files/download`,
7171
null,
7272
filename
7373
);

frontend/src/pages/DataManagement/hooks/useFilesOperation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export function useFilesOperation(dataset: Dataset) {
5454
await downloadFile(dataset.id, file.id, file.fileName);
5555
// 假设导出成功
5656
message.success({
57-
content: `已导出 ${selectedFiles.length} 个文件`,
57+
content: `已导出 1 个文件`,
5858
});
5959
setSelectedFiles([]); // 清空选中状态
6060
};

0 commit comments

Comments
 (0)