refactor: migrate SysFile to manage-file module
This commit is contained in:
@@ -27,6 +27,11 @@
|
||||
<artifactId>manage-notify</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.novalon.manage</groupId>
|
||||
<artifactId>manage-file</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.novalon.manage</groupId>
|
||||
<artifactId>manage-common</artifactId>
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package cn.novalon.manage.db.converter;
|
||||
|
||||
import cn.novalon.manage.sys.core.domain.SysFile;
|
||||
import cn.novalon.manage.file.core.domain.SysFile;
|
||||
import cn.novalon.manage.db.entity.SysFileEntity;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package cn.novalon.manage.db.repository;
|
||||
|
||||
import cn.novalon.manage.sys.core.domain.SysFile;
|
||||
import cn.novalon.manage.sys.core.repository.ISysFileRepository;
|
||||
import cn.novalon.manage.file.core.domain.SysFile;
|
||||
import cn.novalon.manage.file.core.repository.ISysFileRepository;
|
||||
import cn.novalon.manage.db.converter.SysFileConverter;
|
||||
import cn.novalon.manage.db.dao.SysFileDao;
|
||||
import cn.novalon.manage.db.entity.SysFileEntity;
|
||||
|
||||
+1
-7
@@ -1,13 +1,7 @@
|
||||
package cn.novalon.manage.sys.core.domain;
|
||||
package cn.novalon.manage.file.core.domain;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 文件管理领域对象
|
||||
*
|
||||
* @author 张翔
|
||||
* @date 2026-03-13
|
||||
*/
|
||||
public class SysFile {
|
||||
|
||||
private Long id;
|
||||
+3
-9
@@ -1,15 +1,9 @@
|
||||
package cn.novalon.manage.sys.core.repository;
|
||||
package cn.novalon.manage.file.core.repository;
|
||||
|
||||
import cn.novalon.manage.sys.core.domain.SysFile;
|
||||
import cn.novalon.manage.file.core.domain.SysFile;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 文件仓储接口
|
||||
*
|
||||
* @author 张翔
|
||||
* @date 2026-03-13
|
||||
*/
|
||||
public interface ISysFileRepository {
|
||||
|
||||
Flux<SysFile> findByDeletedAtIsNullOrderByCreatedAtDesc();
|
||||
@@ -23,4 +17,4 @@ public interface ISysFileRepository {
|
||||
Mono<SysFile> save(SysFile sysFile);
|
||||
|
||||
Mono<Void> deleteByIdAndDeletedAtIsNull(Long id);
|
||||
}
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
package cn.novalon.manage.sys.core.service;
|
||||
|
||||
import cn.novalon.manage.sys.core.domain.SysFile;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import org.springframework.http.codec.multipart.FilePart;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 文件服务接口
|
||||
*
|
||||
* @author 张翔
|
||||
* @date 2026-03-13
|
||||
*/
|
||||
public interface ISysFileService {
|
||||
Flux<SysFile> findAll();
|
||||
Flux<SysFile> findByCreateBy(String createBy);
|
||||
Mono<SysFile> findById(Long id);
|
||||
Mono<SysFile> findByFileName(String fileName);
|
||||
Mono<SysFile> upload(MultipartFile file, String createBy);
|
||||
Mono<SysFile> uploadFilePart(FilePart filePart, String createBy);
|
||||
Mono<Void> deleteById(Long id);
|
||||
}
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
package cn.novalon.manage.sys.core.service.impl;
|
||||
|
||||
import cn.novalon.manage.sys.core.domain.SysFile;
|
||||
import cn.novalon.manage.sys.core.repository.ISysFileRepository;
|
||||
import cn.novalon.manage.sys.core.service.ISysFileService;
|
||||
import org.springframework.http.codec.multipart.FilePart;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
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;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class SysFileService implements ISysFileService {
|
||||
|
||||
private final ISysFileRepository repository;
|
||||
private final Path uploadPath = Paths.get("./uploads");
|
||||
|
||||
public SysFileService(ISysFileRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<SysFile> findAll() {
|
||||
return repository.findByDeletedAtIsNullOrderByCreatedAtDesc();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<SysFile> findByCreateBy(String createBy) {
|
||||
return repository.findByCreateByOrderByCreatedAtDesc(createBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<SysFile> findById(Long id) {
|
||||
return repository.findById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<SysFile> findByFileName(String fileName) {
|
||||
return repository.findByFilePathContaining(fileName)
|
||||
.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<SysFile> upload(MultipartFile file, String createBy) {
|
||||
try {
|
||||
if (!Files.exists(uploadPath)) {
|
||||
Files.createDirectories(uploadPath);
|
||||
}
|
||||
String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
|
||||
Path filePath = uploadPath.resolve(fileName);
|
||||
Files.copy(file.getInputStream(), filePath);
|
||||
|
||||
SysFile sysFile = new SysFile();
|
||||
sysFile.setFileName(file.getOriginalFilename());
|
||||
sysFile.setFilePath(filePath.toString());
|
||||
sysFile.setFileSize(String.valueOf(file.getSize()));
|
||||
sysFile.setFileType(file.getContentType());
|
||||
sysFile.setStorageType("local");
|
||||
sysFile.setCreateBy(createBy);
|
||||
sysFile.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
return repository.save(sysFile);
|
||||
} catch (Exception e) {
|
||||
return Mono.error(new RuntimeException("文件上传失败: " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteById(Long id) {
|
||||
return repository.deleteByIdAndDeletedAtIsNull(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<SysFile> uploadFilePart(FilePart filePart, String createBy) {
|
||||
try {
|
||||
if (!Files.exists(uploadPath)) {
|
||||
Files.createDirectories(uploadPath);
|
||||
}
|
||||
String fileName = UUID.randomUUID() + "_" + filePart.filename();
|
||||
Path filePath = uploadPath.resolve(fileName);
|
||||
|
||||
return filePart.transferTo(filePath.toFile())
|
||||
.then(Mono.fromCallable(() -> {
|
||||
SysFile sysFile = new SysFile();
|
||||
sysFile.setFileName(filePart.filename());
|
||||
sysFile.setFilePath(filePath.toString());
|
||||
sysFile.setFileSize("0");
|
||||
sysFile.setFileType(filePart.headers().getContentType().toString());
|
||||
sysFile.setStorageType("local");
|
||||
sysFile.setCreateBy(createBy);
|
||||
sysFile.setCreatedAt(LocalDateTime.now());
|
||||
return sysFile;
|
||||
}))
|
||||
.flatMap(sysFile -> repository.save(sysFile));
|
||||
} catch (Exception e) {
|
||||
return Mono.error(new RuntimeException("文件上传失败: " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
-184
@@ -1,184 +0,0 @@
|
||||
package cn.novalon.manage.sys.handler.file;
|
||||
|
||||
import cn.novalon.manage.sys.core.domain.SysFile;
|
||||
import cn.novalon.manage.sys.core.service.ISysFileService;
|
||||
import cn.novalon.manage.sys.dto.response.FilePreviewResponse;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.codec.multipart.FilePart;
|
||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||
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.Mono;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Base64;
|
||||
|
||||
@Component
|
||||
public class SysFileHandler {
|
||||
|
||||
private final ISysFileService fileService;
|
||||
|
||||
public SysFileHandler(ISysFileService fileService) {
|
||||
this.fileService = fileService;
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> getAllFiles(ServerRequest request) {
|
||||
return ServerResponse.ok()
|
||||
.body(fileService.findAll(), SysFile.class);
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> getFileById(ServerRequest request) {
|
||||
Long id = Long.valueOf(request.pathVariable("id"));
|
||||
return fileService.findById(id)
|
||||
.flatMap(file -> ServerResponse.ok().bodyValue(file))
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> uploadFile(ServerRequest request) {
|
||||
return request.multipartData()
|
||||
.flatMap(data -> {
|
||||
FilePart filePart = (FilePart) data.toSingleValueMap().get("file");
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map(securityContext -> {
|
||||
Object principal = securityContext.getAuthentication().getPrincipal();
|
||||
if (principal instanceof Long) {
|
||||
return principal.toString();
|
||||
}
|
||||
return "unknown";
|
||||
})
|
||||
.flatMap(createBy -> fileService.uploadFilePart(filePart, createBy))
|
||||
.flatMap(file -> ServerResponse.status(HttpStatus.CREATED).bodyValue(file));
|
||||
});
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> downloadFile(ServerRequest request) {
|
||||
Long id = Long.valueOf(request.pathVariable("id"));
|
||||
return fileService.findById(id)
|
||||
.flatMap(file -> {
|
||||
try {
|
||||
Path filePath = Paths.get(file.getFilePath());
|
||||
Resource resource = UrlResource.from(filePath.toUri());
|
||||
|
||||
if (resource.exists() && resource.isReadable()) {
|
||||
return ServerResponse.ok()
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
"attachment; filename=\"" + file.getFileName() + "\"")
|
||||
.bodyValue(resource);
|
||||
} else {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
})
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> downloadFileByName(ServerRequest request) {
|
||||
String fileName = request.pathVariable("fileName");
|
||||
return fileService.findByFileName(fileName)
|
||||
.flatMap(file -> {
|
||||
try {
|
||||
Path filePath = Paths.get(file.getFilePath());
|
||||
Resource resource = UrlResource.from(filePath.toUri());
|
||||
|
||||
if (resource.exists() && resource.isReadable()) {
|
||||
return ServerResponse.ok()
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
"attachment; filename=\"" + file.getFileName() + "\"")
|
||||
.bodyValue(resource);
|
||||
} else {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
})
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> previewFile(ServerRequest request) {
|
||||
Long id = Long.valueOf(request.pathVariable("id"));
|
||||
return fileService.findById(id)
|
||||
.flatMap(file -> {
|
||||
try {
|
||||
Path filePath = Paths.get(file.getFilePath());
|
||||
byte[] fileBytes = Files.readAllBytes(filePath);
|
||||
|
||||
FilePreviewResponse response = new FilePreviewResponse();
|
||||
response.setFileName(file.getFileName());
|
||||
response.setFileType(file.getFileType());
|
||||
response.setFileSize((long) fileBytes.length);
|
||||
|
||||
String fileType = file.getFileType().toLowerCase();
|
||||
if (fileType.startsWith("image/")) {
|
||||
response.setPreviewType("image");
|
||||
response.setPreviewData(Base64.getEncoder().encodeToString(fileBytes));
|
||||
} else if (fileType.equals("application/pdf")) {
|
||||
response.setPreviewType("pdf");
|
||||
response.setPreviewData(Base64.getEncoder().encodeToString(fileBytes));
|
||||
} else if (fileType.startsWith("text/")) {
|
||||
response.setPreviewType("text");
|
||||
response.setPreviewData(new String(fileBytes, java.nio.charset.StandardCharsets.UTF_8));
|
||||
} else {
|
||||
response.setPreviewType("unsupported");
|
||||
response.setPreviewData(null);
|
||||
}
|
||||
|
||||
return ServerResponse.ok().bodyValue(response);
|
||||
} catch (IOException e) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
})
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> previewFileByName(ServerRequest request) {
|
||||
String fileName = request.pathVariable("fileName");
|
||||
return fileService.findByFileName(fileName)
|
||||
.flatMap(file -> {
|
||||
try {
|
||||
Path filePath = Paths.get(file.getFilePath());
|
||||
byte[] fileBytes = Files.readAllBytes(filePath);
|
||||
|
||||
FilePreviewResponse response = new FilePreviewResponse();
|
||||
response.setFileName(file.getFileName());
|
||||
response.setFileType(file.getFileType());
|
||||
response.setFileSize((long) fileBytes.length);
|
||||
|
||||
String fileType = file.getFileType().toLowerCase();
|
||||
if (fileType.startsWith("image/")) {
|
||||
response.setPreviewType("image");
|
||||
response.setPreviewData(Base64.getEncoder().encodeToString(fileBytes));
|
||||
} else if (fileType.equals("application/pdf")) {
|
||||
response.setPreviewType("pdf");
|
||||
response.setPreviewData(Base64.getEncoder().encodeToString(fileBytes));
|
||||
} else if (fileType.startsWith("text/")) {
|
||||
response.setPreviewType("text");
|
||||
response.setPreviewData(new String(fileBytes, java.nio.charset.StandardCharsets.UTF_8));
|
||||
} else {
|
||||
response.setPreviewType("unsupported");
|
||||
response.setPreviewData(null);
|
||||
}
|
||||
|
||||
return ServerResponse.ok().bodyValue(response);
|
||||
} catch (IOException e) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
})
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> deleteFile(ServerRequest request) {
|
||||
Long id = Long.valueOf(request.pathVariable("id"));
|
||||
return fileService.deleteById(id)
|
||||
.then(ServerResponse.noContent().build());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user