package com.tcm.training.admin.upload; import com.tcm.training.admin.common.ApiResponse; 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 java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @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 ALLOWED_TYPES = new HashSet<>( Arrays.asList("image/jpeg", "image/png", "image/gif", "image/webp") ); private static final Set ALLOWED_VIDEO_TYPES = new HashSet<>( Arrays.asList("video/mp4", "video/quicktime", "video/x-msvideo", "video/x-matroska", "video/webm") ); private final ObsUploadService obsUploadService; private final UploadProgressService uploadProgressService; public UploadController(ObsUploadService obsUploadService, UploadProgressService uploadProgressService) { this.obsUploadService = obsUploadService; this.uploadProgressService = uploadProgressService; } /** * 图片上传 * POST /api/v1/upload/image * @return { url: "访问地址" } */ @PostMapping("/upload/image") public ApiResponse uploadImage( @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 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 uploadVideoProgress( @RequestParam("taskId") String taskId) { return ApiResponse.ok(uploadProgressService.get(taskId)); } private UploadResult storeFile(MultipartFile file, long maxSize, Set allowedTypes, String typeMessage, String bizPath, String uploadTaskId) throws IOException { if (file == null || file.isEmpty()) { throw new IllegalArgumentException("请选择要上传的文件"); } if (file.getSize() > maxSize) { throw new IllegalArgumentException("文件大小超出限制"); } String contentType = file.getContentType(); if (contentType == null || !allowedTypes.contains(contentType)) { throw new IllegalArgumentException(typeMessage); } 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; } } }