feat: implement file service and handler in manage-file module
This commit is contained in:
@@ -26,6 +26,10 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package cn.novalon.manage.file.core.service;
|
||||
|
||||
import cn.novalon.manage.file.core.domain.SysFile;
|
||||
import org.springframework.http.codec.multipart.FilePart;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface ISysFileService {
|
||||
|
||||
Flux<SysFile> getAllFiles();
|
||||
|
||||
Mono<SysFile> getFileById(Long id);
|
||||
|
||||
Flux<SysFile> getFilesByUser(String username);
|
||||
|
||||
Mono<SysFile> uploadFile(FilePart filePart, String username);
|
||||
|
||||
Mono<Void> downloadFile(Long id);
|
||||
|
||||
Mono<Void> deleteFile(Long id);
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
package cn.novalon.manage.file.core.service.impl;
|
||||
|
||||
import cn.novalon.manage.file.core.domain.SysFile;
|
||||
import cn.novalon.manage.file.core.repository.ISysFileRepository;
|
||||
import cn.novalon.manage.file.core.service.ISysFileService;
|
||||
import org.springframework.http.codec.multipart.FilePart;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class SysFileServiceImpl implements ISysFileService {
|
||||
|
||||
private final ISysFileRepository fileRepository;
|
||||
private final String uploadDir = "/app/uploads";
|
||||
|
||||
public SysFileServiceImpl(ISysFileRepository fileRepository) {
|
||||
this.fileRepository = fileRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<SysFile> getAllFiles() {
|
||||
return fileRepository.findByDeletedAtIsNullOrderByCreatedAtDesc();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<SysFile> getFileById(Long id) {
|
||||
return fileRepository.findById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<SysFile> getFilesByUser(String username) {
|
||||
return fileRepository.findByCreateByOrderByCreatedAtDesc(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<SysFile> uploadFile(FilePart filePart, String username) {
|
||||
String originalFilename = filePart.filename();
|
||||
String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||
String newFileName = UUID.randomUUID().toString() + fileExtension;
|
||||
|
||||
Path uploadPath = Paths.get(uploadDir);
|
||||
return Mono.fromCallable(() -> {
|
||||
if (!Files.exists(uploadPath)) {
|
||||
Files.createDirectories(uploadPath);
|
||||
}
|
||||
return uploadPath;
|
||||
})
|
||||
.flatMap(path -> {
|
||||
Path filePath = path.resolve(newFileName);
|
||||
return filePart.transferTo(filePath.toFile())
|
||||
.thenReturn(filePath);
|
||||
})
|
||||
.flatMap(filePath -> {
|
||||
try {
|
||||
long fileSize = Files.size(filePath);
|
||||
String contentType = filePart.headers().getContentType() != null
|
||||
? filePart.headers().getContentType().toString()
|
||||
: "application/octet-stream";
|
||||
|
||||
SysFile sysFile = new SysFile();
|
||||
sysFile.setFileName(originalFilename);
|
||||
sysFile.setFilePath(filePath.toString());
|
||||
sysFile.setFileSize(String.valueOf(fileSize));
|
||||
sysFile.setFileType(contentType);
|
||||
sysFile.setStorageType("LOCAL");
|
||||
sysFile.setCreateBy(username);
|
||||
sysFile.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
return fileRepository.save(sysFile);
|
||||
} catch (IOException e) {
|
||||
return Mono.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> downloadFile(Long id) {
|
||||
return fileRepository.findById(id)
|
||||
.flatMap(file -> {
|
||||
try {
|
||||
Path filePath = Paths.get(file.getFilePath());
|
||||
byte[] fileContent = Files.readAllBytes(filePath);
|
||||
return Mono.empty();
|
||||
} catch (IOException e) {
|
||||
return Mono.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteFile(Long id) {
|
||||
return fileRepository.findById(id)
|
||||
.flatMap(file -> {
|
||||
try {
|
||||
Path filePath = Paths.get(file.getFilePath());
|
||||
Files.deleteIfExists(filePath);
|
||||
return fileRepository.deleteByIdAndDeletedAtIsNull(id);
|
||||
} catch (IOException e) {
|
||||
return Mono.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
package cn.novalon.manage.file.handler;
|
||||
|
||||
import cn.novalon.manage.file.core.domain.SysFile;
|
||||
import cn.novalon.manage.file.core.service.ISysFileService;
|
||||
import org.springframework.http.codec.multipart.FilePart;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@Component
|
||||
public class SysFileHandler {
|
||||
|
||||
private final ISysFileService fileService;
|
||||
|
||||
public SysFileHandler(ISysFileService fileService) {
|
||||
this.fileService = fileService;
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> getAllFiles(ServerRequest request) {
|
||||
Flux<SysFile> files = fileService.getAllFiles();
|
||||
return ServerResponse.ok().body(files, SysFile.class);
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> getFileById(ServerRequest request) {
|
||||
Long id = Long.parseLong(request.pathVariable("id"));
|
||||
return fileService.getFileById(id)
|
||||
.flatMap(file -> ServerResponse.ok().bodyValue(file))
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> uploadFile(ServerRequest request) {
|
||||
String username = request.headers().firstHeader("X-Username");
|
||||
if (username == null) {
|
||||
username = "system";
|
||||
}
|
||||
final String finalUsername = username;
|
||||
|
||||
return request.multipartData()
|
||||
.flatMap(multipartData -> {
|
||||
var part = multipartData.getFirst("file");
|
||||
if (part == null) {
|
||||
return ServerResponse.badRequest().bodyValue("No file uploaded");
|
||||
}
|
||||
|
||||
if (!(part instanceof FilePart)) {
|
||||
return ServerResponse.badRequest().bodyValue("Invalid file part");
|
||||
}
|
||||
|
||||
final FilePart filePart = (FilePart) part;
|
||||
return fileService.uploadFile(filePart, finalUsername)
|
||||
.flatMap(file -> ServerResponse.ok().bodyValue(file));
|
||||
})
|
||||
.switchIfEmpty(ServerResponse.badRequest().bodyValue("No file data"));
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> downloadFile(ServerRequest request) {
|
||||
Long id = Long.parseLong(request.pathVariable("id"));
|
||||
return fileService.getFileById(id)
|
||||
.flatMap(file -> {
|
||||
try {
|
||||
Path filePath = Paths.get(file.getFilePath());
|
||||
byte[] fileContent = Files.readAllBytes(filePath);
|
||||
return ServerResponse.ok()
|
||||
.header("Content-Disposition", "attachment; filename=\"" + file.getFileName() + "\"")
|
||||
.header("Content-Type", file.getFileType())
|
||||
.bodyValue(fileContent);
|
||||
} catch (Exception e) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
})
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> downloadFileByName(ServerRequest request) {
|
||||
String fileName = request.pathVariable("fileName");
|
||||
return fileService.getAllFiles()
|
||||
.filter(file -> file.getFileName().equals(fileName))
|
||||
.next()
|
||||
.flatMap(file -> {
|
||||
try {
|
||||
Path filePath = Paths.get(file.getFilePath());
|
||||
byte[] fileContent = Files.readAllBytes(filePath);
|
||||
return ServerResponse.ok()
|
||||
.header("Content-Disposition", "attachment; filename=\"" + file.getFileName() + "\"")
|
||||
.header("Content-Type", file.getFileType())
|
||||
.bodyValue(fileContent);
|
||||
} catch (Exception e) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
})
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> previewFile(ServerRequest request) {
|
||||
Long id = Long.parseLong(request.pathVariable("id"));
|
||||
return fileService.getFileById(id)
|
||||
.flatMap(file -> {
|
||||
try {
|
||||
Path filePath = Paths.get(file.getFilePath());
|
||||
byte[] fileContent = Files.readAllBytes(filePath);
|
||||
return ServerResponse.ok()
|
||||
.header("Content-Type", file.getFileType())
|
||||
.bodyValue(fileContent);
|
||||
} catch (Exception e) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
})
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> previewFileByName(ServerRequest request) {
|
||||
String fileName = request.pathVariable("fileName");
|
||||
return fileService.getAllFiles()
|
||||
.filter(file -> file.getFileName().equals(fileName))
|
||||
.next()
|
||||
.flatMap(file -> {
|
||||
try {
|
||||
Path filePath = Paths.get(file.getFilePath());
|
||||
byte[] fileContent = Files.readAllBytes(filePath);
|
||||
return ServerResponse.ok()
|
||||
.header("Content-Type", file.getFileType())
|
||||
.bodyValue(fileContent);
|
||||
} catch (Exception e) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
})
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> deleteFile(ServerRequest request) {
|
||||
Long id = Long.parseLong(request.pathVariable("id"));
|
||||
return fileService.deleteFile(id)
|
||||
.then(ServerResponse.ok().build())
|
||||
.onErrorResume(e -> ServerResponse.badRequest().bodyValue(e.getMessage()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user