refactor(项目管理): 优化文件管理批量下载
This commit is contained in:
parent
94c76c6d95
commit
0ff439f776
|
@ -227,7 +227,7 @@ public class EnvironmentService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FileDownloadUtils.listBytesToZip(files);
|
return FileDownloadUtils.listFileBytesToZip(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<EnvironmentRequest> exportEnv(EnvironmentExportRequest environmentExportRequest) {
|
public List<EnvironmentRequest> exportEnv(EnvironmentExportRequest environmentExportRequest) {
|
||||||
|
|
|
@ -44,7 +44,11 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.unit.DataSize;
|
import org.springframework.util.unit.DataSize;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.*;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -235,7 +239,7 @@ public class FileMetadataService {
|
||||||
return fileMetadata.getId();
|
return fileMetadata.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String genTransferFileName(String fullFileName, String projectId) {
|
public String genTransferFileName(String fullFileName, String projectId) {
|
||||||
if (StringUtils.containsAny(fullFileName, "/")) {
|
if (StringUtils.containsAny(fullFileName, "/")) {
|
||||||
throw new MSException(Translator.get("file.name.error"));
|
throw new MSException(Translator.get("file.name.error"));
|
||||||
}
|
}
|
||||||
|
@ -293,6 +297,20 @@ public class FileMetadataService {
|
||||||
return fileService.upload(file, uploadFileRequest);
|
return fileService.upload(file, uploadFileRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public File getTmpFile(FileMetadata fileMetadata) {
|
||||||
|
File file = null;
|
||||||
|
if (TempFileUtils.isImgTmpFileExists(fileMetadata.getId())) {
|
||||||
|
file = new File(TempFileUtils.getTmpFilePath(fileMetadata.getId()));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
String filePath = TempFileUtils.createFile(TempFileUtils.getTmpFilePath(fileMetadata.getId()), this.getFile(fileMetadata));
|
||||||
|
file = new File(filePath);
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] getFileByte(FileMetadata fileMetadata) {
|
public byte[] getFileByte(FileMetadata fileMetadata) {
|
||||||
String filePath = null;
|
String filePath = null;
|
||||||
if (TempFileUtils.isImgTmpFileExists(fileMetadata.getId())) {
|
if (TempFileUtils.isImgTmpFileExists(fileMetadata.getId())) {
|
||||||
|
@ -400,12 +418,9 @@ public class FileMetadataService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] batchDownload(List<FileMetadata> fileMetadataList) {
|
public byte[] batchDownload(List<FileMetadata> fileMetadataList) {
|
||||||
Map<String, byte[]> files = new LinkedHashMap<>();
|
Map<String, File> fileMap = new HashMap<>();
|
||||||
fileMetadataList.forEach(fileMetadata -> {
|
fileMetadataList.forEach(fileMetadata -> fileMap.put(this.getFileName(fileMetadata.getName(), fileMetadata.getType()), this.getTmpFile(fileMetadata)));
|
||||||
byte[] bytes = this.getFileByte(fileMetadata);
|
return FileDownloadUtils.listBytesToZip(fileMap);
|
||||||
files.put(this.getFileName(fileMetadata.getName(), fileMetadata.getType()), bytes);
|
|
||||||
});
|
|
||||||
return FileDownloadUtils.listBytesToZip(files);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//检查下载的文件的大小
|
//检查下载的文件的大小
|
||||||
|
|
|
@ -73,6 +73,7 @@ public class FileModuleService extends ModuleTreeService implements CleanupProje
|
||||||
fileModule.setCreateUser(operator);
|
fileModule.setCreateUser(operator);
|
||||||
fileModule.setUpdateUser(operator);
|
fileModule.setUpdateUser(operator);
|
||||||
fileModule.setModuleType(ModuleConstants.NODE_TYPE_DEFAULT);
|
fileModule.setModuleType(ModuleConstants.NODE_TYPE_DEFAULT);
|
||||||
|
|
||||||
fileModuleMapper.insert(fileModule);
|
fileModuleMapper.insert(fileModule);
|
||||||
|
|
||||||
//记录日志
|
//记录日志
|
||||||
|
|
|
@ -1,12 +1,46 @@
|
||||||
package io.metersphere.project.utils;
|
package io.metersphere.project.utils;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
public class FileDownloadUtils {
|
public class FileDownloadUtils {
|
||||||
public static byte[] listBytesToZip(Map<String, byte[]> mapReport) {
|
|
||||||
|
public static byte[] listBytesToZip(Map<String, File> fileMap) {
|
||||||
|
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) {
|
||||||
|
for (Map.Entry<String, File> fileEntry : fileMap.entrySet()) {
|
||||||
|
String fileName = fileEntry.getKey();
|
||||||
|
File file = fileEntry.getValue();
|
||||||
|
if (file.exists()) {
|
||||||
|
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
|
||||||
|
ZipEntry zipEntry = new ZipEntry(fileName);
|
||||||
|
zipOutputStream.putNextEntry(zipEntry);
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int num;
|
||||||
|
while ((num = bis.read(buffer)) > 0) {
|
||||||
|
zipOutputStream.write(buffer, 0, num);
|
||||||
|
}
|
||||||
|
zipOutputStream.closeEntry();
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zipOutputStream.close();
|
||||||
|
return byteArrayOutputStream.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error(e);
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] listFileBytesToZip(Map<String, byte[]> mapReport) {
|
||||||
try {
|
try {
|
||||||
if (!mapReport.isEmpty()) {
|
if (!mapReport.isEmpty()) {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
|
|
@ -11,6 +11,7 @@ import io.metersphere.project.mapper.FileAssociationMapper;
|
||||||
import io.metersphere.project.mapper.FileMetadataMapper;
|
import io.metersphere.project.mapper.FileMetadataMapper;
|
||||||
import io.metersphere.project.mapper.FileModuleMapper;
|
import io.metersphere.project.mapper.FileModuleMapper;
|
||||||
import io.metersphere.project.service.FileAssociationService;
|
import io.metersphere.project.service.FileAssociationService;
|
||||||
|
import io.metersphere.project.service.FileMetadataService;
|
||||||
import io.metersphere.project.service.FileModuleService;
|
import io.metersphere.project.service.FileModuleService;
|
||||||
import io.metersphere.project.service.FileService;
|
import io.metersphere.project.service.FileService;
|
||||||
import io.metersphere.project.utils.FileManagementBaseUtils;
|
import io.metersphere.project.utils.FileManagementBaseUtils;
|
||||||
|
@ -90,6 +91,8 @@ public class FileManagementControllerTests extends BaseTest {
|
||||||
@Resource
|
@Resource
|
||||||
private FileMetadataMapper fileMetadataMapper;
|
private FileMetadataMapper fileMetadataMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
private FileMetadataService fileMetadataService;
|
||||||
|
@Resource
|
||||||
private CommonProjectService commonProjectService;
|
private CommonProjectService commonProjectService;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
@ -860,6 +863,11 @@ public class FileManagementControllerTests extends BaseTest {
|
||||||
fileBytes = mvcResult.getResponse().getContentAsByteArray();
|
fileBytes = mvcResult.getResponse().getContentAsByteArray();
|
||||||
Assertions.assertTrue(fileBytes.length > 0);
|
Assertions.assertTrue(fileBytes.length > 0);
|
||||||
|
|
||||||
|
//重新下载全部文件
|
||||||
|
mvcResult = this.requestPostDownloadFile(FileManagementRequestUtils.URL_FILE_BATCH_DOWNLOAD, null, batchProcessDTO);
|
||||||
|
fileBytes = mvcResult.getResponse().getContentAsByteArray();
|
||||||
|
Assertions.assertTrue(fileBytes.length > 0);
|
||||||
|
|
||||||
//全部文件大小超过默认配置(600M)的限制 事先存储20个大小为50M的数据,过后删除
|
//全部文件大小超过默认配置(600M)的限制 事先存储20个大小为50M的数据,过后删除
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
String id = "test_" + i;
|
String id = "test_" + i;
|
||||||
|
@ -1632,6 +1640,23 @@ public class FileManagementControllerTests extends BaseTest {
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
Assertions.assertTrue(error);
|
Assertions.assertTrue(error);
|
||||||
|
|
||||||
|
//文件名称非法
|
||||||
|
error = false;
|
||||||
|
try {
|
||||||
|
fileMetadataService.transferFile("", null, null, null, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
Assertions.assertTrue(error);
|
||||||
|
|
||||||
|
error = false;
|
||||||
|
try {
|
||||||
|
fileMetadataService.genTransferFileName("testTransfer/File.jpg", null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
Assertions.assertTrue(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void associationDelete() {
|
public void associationDelete() {
|
||||||
|
|
Loading…
Reference in New Issue