feat: 添加SysFileHandler文件管理API(含文件预览)~

This commit is contained in:
张翔
2026-03-12 07:47:41 +08:00
parent 3072378d2d
commit 5a4ac80018
2 changed files with 166 additions and 0 deletions
@@ -0,0 +1,49 @@
package cn.novalon.manage.sys.dto.response;
public class FilePreviewResponse {
private String fileName;
private String fileType;
private Long fileSize;
private String previewType;
private String previewData;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFileType() {
return fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
public Long getFileSize() {
return fileSize;
}
public void setFileSize(Long fileSize) {
this.fileSize = fileSize;
}
public String getPreviewType() {
return previewType;
}
public void setPreviewType(String previewType) {
this.previewType = previewType;
}
public String getPreviewData() {
return previewData;
}
public void setPreviewData(String previewData) {
this.previewData = previewData;
}
}
@@ -0,0 +1,117 @@
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.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
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.util.Base64;
@RestController
@RequestMapping("/api/files")
public class SysFileHandler {
private final ISysFileService fileService;
public SysFileHandler(ISysFileService fileService) {
this.fileService = fileService;
}
@GetMapping
public Flux<SysFile> getAllFiles() {
return fileService.findAll();
}
@GetMapping("/{id}")
public Mono<ResponseEntity<SysFile>> getFileById(@PathVariable Long id) {
return fileService.findById(id)
.map(ResponseEntity::ok)
.defaultIfEmpty(ResponseEntity.notFound().build());
}
@PostMapping("/upload")
public Mono<ResponseEntity<SysFile>> uploadFile(
@RequestParam("file") MultipartFile file,
@RequestParam(value = "createBy", required = false) String createBy) {
return fileService.upload(file, createBy)
.map(f -> ResponseEntity.status(HttpStatus.CREATED).body(f));
}
@GetMapping("/{id}/download")
public Mono<ResponseEntity<Resource>> downloadFile(@PathVariable Long 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 Mono.<ResponseEntity<Resource>>just(ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getFileName() + "\"")
.body(resource));
} else {
return Mono.<ResponseEntity<Resource>>just(ResponseEntity.notFound().build());
}
} catch (Exception e) {
return Mono.<ResponseEntity<Resource>>just(ResponseEntity.notFound().build());
}
})
.switchIfEmpty(Mono.<ResponseEntity<Resource>>just(ResponseEntity.notFound().build()));
}
@GetMapping("/{id}/preview")
public Mono<ResponseEntity<FilePreviewResponse>> previewFile(@PathVariable Long 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));
} else {
response.setPreviewType("unsupported");
response.setPreviewData(null);
}
return Mono.<ResponseEntity<FilePreviewResponse>>just(ResponseEntity.ok(response));
} catch (IOException e) {
return Mono.<ResponseEntity<FilePreviewResponse>>just(ResponseEntity.notFound().build());
}
})
.switchIfEmpty(Mono.<ResponseEntity<FilePreviewResponse>>just(ResponseEntity.notFound().build()));
}
@DeleteMapping("/{id}")
public Mono<ResponseEntity<Void>> deleteFile(@PathVariable Long id) {
return fileService.deleteById(id)
.then(Mono.just(ResponseEntity.noContent().build()));
}
}