This commit is contained in:
@@ -47,7 +47,7 @@ public class FileUploadController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
FileUploadSession session = fileUploadService.initUpload(authToken.getUser().getId(), request.getFileName(),
|
FileUploadSession session = fileUploadService.initUpload(authToken.getUser().getId(), request.getFileName(),
|
||||||
request.getFileType(), request.getFileSize());
|
request.getFileType(), request.getExtension(), request.getFileSize());
|
||||||
|
|
||||||
return ResponseEntity.ok(FileApiResponse.success(session));
|
return ResponseEntity.ok(FileApiResponse.success(session));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ public class InitUploadRequest {
|
|||||||
@NotBlank(message = "File type is required")
|
@NotBlank(message = "File type is required")
|
||||||
private String fileType;
|
private String fileType;
|
||||||
|
|
||||||
|
@NotBlank(message = "File extension is required")
|
||||||
|
private String extension;
|
||||||
|
|
||||||
@NotNull(message = "File size is required")
|
@NotNull(message = "File size is required")
|
||||||
@Positive(message = "File size must be positive")
|
@Positive(message = "File size must be positive")
|
||||||
private Long fileSize;
|
private Long fileSize;
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ public class FileUploadSession {
|
|||||||
@Column(name = "last_error")
|
@Column(name = "last_error")
|
||||||
private String lastError;
|
private String lastError;
|
||||||
|
|
||||||
|
@Column(name = "extension")
|
||||||
|
private String extension;
|
||||||
|
|
||||||
@Column(name = "retry_count")
|
@Column(name = "retry_count")
|
||||||
private Integer retryCount = 0;
|
private Integer retryCount = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
public interface FileUploadService {
|
public interface FileUploadService {
|
||||||
FileUploadSession initUpload(Long userId, String fileName,
|
FileUploadSession initUpload(Long userId, String fileName,
|
||||||
String fileType, long fileSize);
|
String fileType, String extension, long fileSize);
|
||||||
|
|
||||||
UploadProgressResponse uploadChunk(String uploadId, Integer chunkNumber,
|
UploadProgressResponse uploadChunk(String uploadId, Integer chunkNumber,
|
||||||
MultipartFile chunkFile) throws IOException;
|
MultipartFile chunkFile) throws IOException;
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public class FileUploadServiceImpl implements FileUploadService {
|
|||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public FileUploadSession initUpload(Long userId, String fileName,
|
public FileUploadSession initUpload(Long userId, String fileName,
|
||||||
String fileType, long fileSize) {
|
String fileType, String extension, long fileSize) {
|
||||||
log.info("Initializing upload for user {}: {} ({} bytes, type: {})",
|
log.info("Initializing upload for user {}: {} ({} bytes, type: {})",
|
||||||
userId, fileName, fileSize, fileType);
|
userId, fileName, fileSize, fileType);
|
||||||
|
|
||||||
@@ -101,6 +101,7 @@ public class FileUploadServiceImpl implements FileUploadService {
|
|||||||
|
|
||||||
FileUploadSession session = FileUploadSession.builder()
|
FileUploadSession session = FileUploadSession.builder()
|
||||||
.userId(userId)
|
.userId(userId)
|
||||||
|
.extension(extension)
|
||||||
.fileName(fileName)
|
.fileName(fileName)
|
||||||
.fileType(fileType)
|
.fileType(fileType)
|
||||||
.fileSize(fileSize)
|
.fileSize(fileSize)
|
||||||
@@ -364,7 +365,7 @@ public class FileUploadServiceImpl implements FileUploadService {
|
|||||||
|
|
||||||
Files.createDirectories(userUploadsDir);
|
Files.createDirectories(userUploadsDir);
|
||||||
|
|
||||||
String safeFileName = generateUniqueFileName(session.getFileName());
|
String safeFileName = generateUniqueFileName(session.getFileName(), session.getExtension());
|
||||||
Path finalPath = userUploadsDir.resolve(safeFileName);
|
Path finalPath = userUploadsDir.resolve(safeFileName);
|
||||||
|
|
||||||
if (Files.exists(finalPath)) {
|
if (Files.exists(finalPath)) {
|
||||||
@@ -374,20 +375,24 @@ public class FileUploadServiceImpl implements FileUploadService {
|
|||||||
return finalPath;
|
return finalPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateUniqueFileName(String originalName) {
|
private String generateUniqueFileName(String originalName, String extension) {
|
||||||
String safeName = originalName.replaceAll("[^a-zA-Z0-9\\.\\-_]", "_");
|
int dotIndex = originalName.lastIndexOf('.');
|
||||||
|
log.info("dotIndex: {}", dotIndex);
|
||||||
|
log.info("originalName: {}", originalName);
|
||||||
|
String nameWithoutExtension;
|
||||||
|
|
||||||
|
if (dotIndex > 0) {
|
||||||
|
nameWithoutExtension = originalName.substring(0, dotIndex)
|
||||||
|
.replaceAll("[^a-zA-Z0-9\\-_]", "_");
|
||||||
|
} else {
|
||||||
|
nameWithoutExtension = originalName.replaceAll("[^a-zA-Z0-9\\-_]", "_");
|
||||||
|
}
|
||||||
|
|
||||||
String timestamp = String.valueOf(System.currentTimeMillis());
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
||||||
String uuid = UUID.randomUUID().toString().substring(0, 8);
|
String uuid = UUID.randomUUID().toString().substring(0, 8);
|
||||||
|
|
||||||
int dotIndex = safeName.lastIndexOf('.');
|
return String.format("%s_%s_%s.%s",
|
||||||
if (dotIndex > 0) {
|
nameWithoutExtension, timestamp, uuid, extension);
|
||||||
String name = safeName.substring(0, dotIndex);
|
|
||||||
String extension = safeName.substring(dotIndex);
|
|
||||||
return String.format("%s_%s_%s%s", name, timestamp, uuid, extension);
|
|
||||||
} else {
|
|
||||||
return String.format("%s_%s_%s", safeName, timestamp, uuid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateAllChunksExist(FileUploadSession session) throws IOException {
|
private void validateAllChunksExist(FileUploadSession session) throws IOException {
|
||||||
@@ -409,7 +414,7 @@ public class FileUploadServiceImpl implements FileUploadService {
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
Path chunkDir = getChunkDirectory(session.getUserId(), session.getUploadId());
|
Path chunkDir = getChunkDirectory(session.getUserId(), session.getUploadId());
|
||||||
byte[] buffer = new byte[8192]; // 8KB буфер
|
byte[] buffer = new byte[8192];
|
||||||
|
|
||||||
try (BufferedOutputStream outputStream = new BufferedOutputStream(
|
try (BufferedOutputStream outputStream = new BufferedOutputStream(
|
||||||
Files.newOutputStream(finalPath, StandardOpenOption.CREATE_NEW))) {
|
Files.newOutputStream(finalPath, StandardOpenOption.CREATE_NEW))) {
|
||||||
@@ -596,18 +601,13 @@ public class FileUploadServiceImpl implements FileUploadService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String lowerType = fileType.toLowerCase();
|
String lowerType = fileType.toLowerCase();
|
||||||
if (lowerType.startsWith("image/")) {
|
if (lowerType.startsWith("image")) {
|
||||||
return "images";
|
return "images";
|
||||||
} else if (lowerType.startsWith("video/")) {
|
} else if (lowerType.startsWith("video")) {
|
||||||
return "videos";
|
return "videos";
|
||||||
} else if (lowerType.startsWith("audio/")) {
|
} else if (lowerType.startsWith("audio")) {
|
||||||
return "audio";
|
return "audio";
|
||||||
} else if (lowerType.contains("pdf") ||
|
} else if (lowerType.contains("document")) {
|
||||||
lowerType.contains("document") ||
|
|
||||||
lowerType.contains("text") ||
|
|
||||||
lowerType.contains("msword") ||
|
|
||||||
lowerType.contains("wordprocessing") ||
|
|
||||||
lowerType.contains("spreadsheet")) {
|
|
||||||
return "documents";
|
return "documents";
|
||||||
} else {
|
} else {
|
||||||
return "other";
|
return "other";
|
||||||
|
|||||||
Reference in New Issue
Block a user