From 059892a0ac18e8c5739b43e02411e4d7dc9cbfdd Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Tue, 13 Jan 2026 17:57:15 +0800
Subject: [PATCH] fix(file-upload): 修复文件上传组件的交互问题
---
src/main/java/cc/mrbird/febs/ai/controller/fileUpload/FileUploadController.java | 237 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 237 insertions(+), 0 deletions(-)
diff --git a/src/main/java/cc/mrbird/febs/ai/controller/fileUpload/FileUploadController.java b/src/main/java/cc/mrbird/febs/ai/controller/fileUpload/FileUploadController.java
new file mode 100644
index 0000000..1f1c849
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/controller/fileUpload/FileUploadController.java
@@ -0,0 +1,237 @@
+package cc.mrbird.febs.ai.controller.fileUpload;
+
+import cc.mrbird.febs.common.controller.BaseController;
+import cc.mrbird.febs.common.entity.FebsResponse;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author Administrator
+ */
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+@RequestMapping(value = "/fileUpload")
+public class FileUploadController extends BaseController {
+
+ // @Value("${file.upload.dir}")
+ private String uploadDir = "d:/upload/files";
+
+ // @Value("${file.chunk.dir}")
+ private String chunkDir = "d:/upload/chunks";
+
+ /**
+ * 上传文件分片
+ */
+ @PostMapping("/uploadChunk")
+ public FebsResponse uploadChunk(@RequestParam("file") MultipartFile file,
+ @RequestParam("fileName") String fileName,
+ @RequestParam("chunk") int chunk,
+ @RequestParam("chunks") int chunks,
+ @RequestParam("fileMd5") String fileMd5) {
+ try {
+ // 确保分片目录存在
+ Path chunkPath = Paths.get(chunkDir, fileMd5);
+ if (!Files.exists(chunkPath)) {
+ Files.createDirectories(chunkPath);
+ }
+
+ // 保存分片文件
+ Path chunkFilePath = chunkPath.resolve(chunk + ".part");
+ Files.write(chunkFilePath, file.getBytes());
+
+ return new FebsResponse().success().message("分片上传成功");
+ } catch (Exception e) {
+ e.printStackTrace();
+ return new FebsResponse().fail().message("分片上传失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 合并文件分片
+ */
+ @PostMapping("/mergeChunks")
+ public FebsResponse mergeChunks(@RequestParam("fileName") String fileName,
+ @RequestParam("fileMd5") String fileMd5,
+ @RequestParam("chunks") int chunks) {
+ try {
+ // 确保上传目录存在
+ Path uploadPath = Paths.get(uploadDir);
+ if (!Files.exists(uploadPath)) {
+ Files.createDirectories(uploadPath);
+ }
+
+ // 生成唯一文件名
+ String uniqueFileName = UUID.randomUUID().toString() + "_" + fileName;
+ Path targetFilePath = uploadPath.resolve(uniqueFileName);
+
+ // 确保分片目录存在
+ Path chunkPath = Paths.get(chunkDir, fileMd5);
+ if (!Files.exists(chunkPath)) {
+ return new FebsResponse().fail().message("分片目录不存在");
+ }
+
+ // 合并分片
+ try (FileOutputStream outputStream = new FileOutputStream(targetFilePath.toFile())) {
+ for (int i = 0; i < chunks; i++) {
+ Path chunkFilePath = chunkPath.resolve(i + ".part");
+ if (!Files.exists(chunkFilePath)) {
+ return new FebsResponse().fail().message("分片文件不存在: " + chunkFilePath);
+ }
+ byte[] chunkBytes = Files.readAllBytes(chunkFilePath);
+ outputStream.write(chunkBytes);
+ // 删除已合并的分片
+ Files.deleteIfExists(chunkFilePath);
+ }
+ }
+
+ // 删除分片目录
+ Files.deleteIfExists(chunkPath);
+
+ // 保存文件信息到数据库或文件系统(这里简化处理)
+ saveFileInfo(uniqueFileName, targetFilePath.toFile().length());
+
+ return new FebsResponse().success().message("文件上传成功").data(uniqueFileName);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return new FebsResponse().fail().message("文件合并失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 播放视频文件
+ */
+ @GetMapping("/play/{fileName}")
+ public void playVideo(@PathVariable("fileName") String fileName, HttpServletResponse response) {
+ try {
+ Path filePath = Paths.get(uploadDir, fileName);
+ if (!Files.exists(filePath)) {
+ response.setStatus(HttpStatus.NOT_FOUND.value());
+ return;
+ }
+
+ // 设置响应头
+ response.setContentType("video/mp4");
+ response.setContentLengthLong(Files.size(filePath));
+ response.setHeader("Content-Disposition", "inline; filename=\"" + fileName + "\"");
+
+ // 流式传输文件
+ try (InputStream inputStream = Files.newInputStream(filePath);
+ OutputStream outputStream = response.getOutputStream()) {
+ byte[] buffer = new byte[8192];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+ }
+ }
+
+ /**
+ * 获取文件列表
+ */
+ @GetMapping("/list")
+ public FebsResponse getFileList() {
+ try {
+ Path uploadPath = Paths.get(uploadDir);
+ if (!Files.exists(uploadPath)) {
+ return new FebsResponse().data(new ArrayList<>());
+ }
+
+ List<FileInfo> fileList = new ArrayList<>();
+ Files.list(uploadPath).forEach(path -> {
+ if (Files.isRegularFile(path)) {
+ try {
+ FileInfo fileInfo = new FileInfo();
+ fileInfo.setFileName(path.getFileName().toString());
+ fileInfo.setFileSize(Files.size(path));
+ fileInfo.setUploadTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(Files.getLastModifiedTime(path).toMillis())));
+ fileList.add(fileInfo);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ return new FebsResponse().success().data(fileList);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return new FebsResponse().fail().message("获取文件列表失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 删除文件
+ */
+ @PostMapping("/delete")
+ public FebsResponse deleteFile(@RequestParam("fileName") String fileName) {
+ try {
+ Path filePath = Paths.get(uploadDir, fileName);
+ if (Files.exists(filePath)) {
+ Files.delete(filePath);
+ }
+ return new FebsResponse().success().message("文件删除成功");
+ } catch (Exception e) {
+ e.printStackTrace();
+ return new FebsResponse().fail().message("文件删除失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 保存文件信息
+ */
+ private void saveFileInfo(String fileName, long fileSize) {
+ // 这里可以实现保存文件信息到数据库的逻辑
+ // 简化处理,暂时不做数据库操作
+ }
+
+ /**
+ * 文件信息实体类
+ */
+ public static class FileInfo {
+ private String fileName;
+ private long fileSize;
+ private String uploadTime;
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public long getFileSize() {
+ return fileSize;
+ }
+
+ public void setFileSize(long fileSize) {
+ this.fileSize = fileSize;
+ }
+
+ public String getUploadTime() {
+ return uploadTime;
+ }
+
+ public void setUploadTime(String uploadTime) {
+ this.uploadTime = uploadTime;
+ }
+ }
+}
--
Gitblit v1.9.1