From ba3233a5b685f0ae6856d8dc5a2bf904296cf8b7 Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期四, 26 三月 2026 15:08:46 +0800
Subject: [PATCH] feat:交易与流水-订单-会员购买订单、交易与流水-订单-养生课程购买订单、交易与流水-财务流水-支付流水、交易与流水-财务流水-退费流水、课程管理-健康科普
---
backend/src/main/java/com/tcm/training/admin/upload/UploadController.java | 102 ++++++++++++++++++++++++--------------------------
1 files changed, 49 insertions(+), 53 deletions(-)
diff --git a/backend/src/main/java/com/tcm/training/admin/upload/UploadController.java b/backend/src/main/java/com/tcm/training/admin/upload/UploadController.java
index ad5030b..fdf149b 100644
--- a/backend/src/main/java/com/tcm/training/admin/upload/UploadController.java
+++ b/backend/src/main/java/com/tcm/training/admin/upload/UploadController.java
@@ -1,37 +1,38 @@
package com.tcm.training.admin.upload;
import com.tcm.training.admin.common.ApiResponse;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
-import javax.servlet.http.HttpServletRequest;
-import java.io.File;
import java.io.IOException;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
-import java.util.UUID;
@RestController
@RequestMapping({"/api/v1", "/api"})
public class UploadController {
private static final long MAX_SIZE = 5 * 1024 * 1024L; // 5MB
+ private static final long VIDEO_MAX_SIZE = 200 * 1024 * 1024L; // 200MB
private static final Set<String> ALLOWED_TYPES = new HashSet<>(
Arrays.asList("image/jpeg", "image/png", "image/gif", "image/webp")
);
+ private static final Set<String> ALLOWED_VIDEO_TYPES = new HashSet<>(
+ Arrays.asList("video/mp4", "video/quicktime", "video/x-msvideo", "video/x-matroska", "video/webm")
+ );
- @Value("${app.upload.dir:uploads}")
- private String uploadDir;
+ private final ObsUploadService obsUploadService;
+ private final UploadProgressService uploadProgressService;
- @Value("${app.upload.path-prefix:/uploads}")
- private String pathPrefix;
+ public UploadController(ObsUploadService obsUploadService, UploadProgressService uploadProgressService) {
+ this.obsUploadService = obsUploadService;
+ this.uploadProgressService = uploadProgressService;
+ }
/**
* 图片上传
@@ -40,67 +41,62 @@
*/
@PostMapping("/upload/image")
public ApiResponse<UploadResult> uploadImage(
- @RequestParam("file") MultipartFile file,
- HttpServletRequest request) throws IOException {
+ @RequestParam("file") MultipartFile file) throws IOException {
+ return ApiResponse.ok(storeFile(file, MAX_SIZE, ALLOWED_TYPES, "仅支持 JPG、PNG、GIF、WebP 格式", "image", null));
+ }
- // 校验文件非空
+ @PostMapping("/upload/video")
+ public ApiResponse<UploadResult> uploadVideo(
+ @RequestParam("file") MultipartFile file,
+ @RequestParam(value = "uploadTaskId", required = false) String uploadTaskId) throws IOException {
+ return ApiResponse.ok(storeFile(file, VIDEO_MAX_SIZE, ALLOWED_VIDEO_TYPES, "仅支持 MP4、MOV、AVI、MKV、WebM 格式", "video", uploadTaskId));
+ }
+
+ @GetMapping("/upload/video/progress")
+ public ApiResponse<UploadProgressInfo> uploadVideoProgress(
+ @RequestParam("taskId") String taskId) {
+ return ApiResponse.ok(uploadProgressService.get(taskId));
+ }
+
+ private UploadResult storeFile(MultipartFile file,
+ long maxSize,
+ Set<String> allowedTypes,
+ String typeMessage,
+ String bizPath,
+ String uploadTaskId) throws IOException {
if (file == null || file.isEmpty()) {
throw new IllegalArgumentException("请选择要上传的文件");
}
-
- // 校验文件大小
- if (file.getSize() > MAX_SIZE) {
- throw new IllegalArgumentException("文件大小不能超过 5MB");
+ if (file.getSize() > maxSize) {
+ throw new IllegalArgumentException("文件大小超出限制");
}
-
- // 校验文件类型
String contentType = file.getContentType();
- if (contentType == null || !ALLOWED_TYPES.contains(contentType)) {
- throw new IllegalArgumentException("仅支持 JPG、PNG、GIF、WebP 格式");
+ if (contentType == null || !allowedTypes.contains(contentType)) {
+ throw new IllegalArgumentException(typeMessage);
}
-
- // 生成子目录(按日期)和唯一文件名
- String dateDir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
- String originalName = file.getOriginalFilename();
- String ext = "";
- if (originalName != null && originalName.contains(".")) {
- ext = originalName.substring(originalName.lastIndexOf("."));
- }
- String fileName = UUID.randomUUID().toString().replace("-", "") + ext;
-
- // 创建目录并保存文件(强制绝对路径,规避 transferTo 临时文件问题)
- File dir = new File(uploadDir, dateDir).getAbsoluteFile();
- if (!dir.exists() && !dir.mkdirs()) {
- throw new IOException("创建上传目录失败: " + dir.getAbsolutePath());
- }
- File dest = new File(dir, fileName);
- // 用 InputStream 手动拷贝,避免 Spring transferTo 依赖临时文件的问题
- try (java.io.InputStream in = file.getInputStream();
- java.io.OutputStream out = new java.io.FileOutputStream(dest)) {
- byte[] buf = new byte[8192];
- int n;
- while ((n = in.read(buf)) != -1) {
- out.write(buf, 0, n);
- }
- }
-
- // 构造访问 URL
- String baseUrl = request.getScheme() + "://" + request.getServerName()
- + ":" + request.getServerPort();
- String url = baseUrl + pathPrefix + "/" + dateDir + "/" + fileName;
-
- return ApiResponse.ok(new UploadResult(url));
+ UploadFileResult uploadResult = obsUploadService.upload(file, bizPath, uploadTaskId);
+ return new UploadResult(uploadResult.getUrl(), uploadResult.getFileName());
}
public static class UploadResult {
private final String url;
+ private final String fileName;
public UploadResult(String url) {
+ this(url, null);
+ }
+
+ public UploadResult(String url, String fileName) {
this.url = url;
+ this.fileName = fileName;
}
public String getUrl() {
return url;
}
+
+ public String getFileName() {
+ return fileName;
+ }
}
}
--
Gitblit v1.7.1