feat:增强文件预览功能

- 新增视频文件预览
- 新增Pdf文件预览
This commit is contained in:
czhqwer
2025-03-21 01:33:58 +08:00
parent 8a9373867f
commit eafbc82b5e
4 changed files with 331 additions and 8 deletions
@@ -4,8 +4,9 @@ import cn.czh.base.Result;
import cn.czh.entity.StorageConfig;
import cn.czh.service.IFileService;
import cn.czh.service.IStorageConfigService;
import cn.czh.utils.FileTypeUtil;
import org.springframework.core.io.ByteArrayResource;
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.GetMapping;
@@ -18,6 +19,7 @@ import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
@RestController
@RequestMapping("/file")
@@ -29,7 +31,7 @@ public class FileController {
private IFileService fileService;
@GetMapping("/preview/{storageType}/**")
public ResponseEntity<byte[]> previewFile(
public ResponseEntity<?> previewFile(
@PathVariable String storageType,
HttpServletRequest request) throws IOException {
// 从请求中提取剩余路径作为 objectKey
@@ -39,16 +41,37 @@ public class FileController {
if (StorageConfig.LOCAL.equals(storageType)) {
StorageConfig storageConfig = storageConfigService.getStorageConfigByType(storageType);
String filePath = storageConfig.getBucket() + "\\" + objectKey;
// 使用 Paths.get 拼接路径,避免反斜杠问题
String filePath = Paths.get(storageConfig.getBucket(), objectKey).toString();
File file = new File(filePath);
// 检查文件是否存在
if (!file.exists()) {
return ResponseEntity.notFound().build();
}
// 读取文件内容
byte[] fileBytes = Files.readAllBytes(file.toPath());
ByteArrayResource resource = new ByteArrayResource(fileBytes);
// 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<>(fileBytes, headers, HttpStatus.OK);
String fileName = file.getName().toLowerCase();
String fileSuffix = FileTypeUtil.getFileSuffix(fileName).toLowerCase();
// 根据文件类型设置 Content-Type
MediaType contentType = FileTypeUtil.determineContentType(fileSuffix);
headers.setContentType(contentType);
// 设置 Content-Disposition 为 inline,浏览器直接预览
headers.add(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + file.getName() + "\"");
headers.setContentLength(fileBytes.length);
return ResponseEntity.ok()
.headers(headers)
.body(resource);
}
return ResponseEntity.badRequest().build();
}
@@ -1,5 +1,7 @@
package cn.czh.utils;
import org.springframework.http.MediaType;
/**
* 文件类型的工具类
*/
@@ -158,4 +160,61 @@ public class FileTypeUtil {
}
return false;
}
/**
* 根据文件后缀确定 Content-Type
*/
public static MediaType determineContentType(String fileSuffix) {
// 使用 FileTypeUtil 判断文件类型
if (FileTypeUtil.isImgType(fileSuffix)) {
switch (fileSuffix) {
case "jpg":
case "jpeg":
return MediaType.IMAGE_JPEG;
case "png":
return MediaType.IMAGE_PNG;
case "gif":
return MediaType.IMAGE_GIF;
default:
return MediaType.APPLICATION_OCTET_STREAM;
}
} else if (FileTypeUtil.bVideoFileType("example." + fileSuffix)) {
switch (fileSuffix) {
case "mp4":
return MediaType.valueOf("video/mp4");
case "avi":
return MediaType.valueOf("video/x-msvideo");
case "wmv":
return MediaType.valueOf("video/x-ms-wmv");
default:
return MediaType.APPLICATION_OCTET_STREAM;
}
} else if (FileTypeUtil.bAudioFileType("example." + fileSuffix)) {
switch (fileSuffix) {
case "mp3":
return MediaType.valueOf("audio/mpeg");
case "wav":
return MediaType.valueOf("audio/wav");
default:
return MediaType.APPLICATION_OCTET_STREAM;
}
} else if (FileTypeUtil.bLogFileType("example." + fileSuffix)) {
switch (fileSuffix) {
case "txt":
return MediaType.TEXT_PLAIN;
case "log":
return MediaType.valueOf("text/plain");
case "doc":
case "docx":
return MediaType.valueOf("application/msword");
default:
return MediaType.APPLICATION_OCTET_STREAM;
}
} else if ("pdf".equals(fileSuffix)) {
return MediaType.APPLICATION_PDF;
}
// 默认类型
return MediaType.APPLICATION_OCTET_STREAM;
}
}