package com.xuekairui.user.controller; import com.xuekairui.common.Result; import com.xuekairui.user.service.OssService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.UUID; /** * 通用文件上传控制器 * */ @Slf4j @RestController @RequestMapping("/api/upload") @RequiredArgsConstructor public class FileUploadController { private final OssService ossService; @Value("${upload.path:/opt/uploads}") private String uploadPath; /** * 上传单个文件(本地存储) * POST /api/upload * Body: multipart/form-data, field: file * * @return 文件访问相对路径 */ @PostMapping public Result upload(@RequestParam("file") MultipartFile file) throws IOException { if (file.isEmpty()) { return Result.error(400, "文件不能为空"); } // 确保目录存在 Path dir = Paths.get(uploadPath); if (!Files.exists(dir)) { Files.createDirectories(dir); log.info("创建上传目录: {}", dir.toAbsolutePath()); } // 生成唯一文件名(保留扩展名) String originalFilename = file.getOriginalFilename(); String extension = ""; if (originalFilename != null && originalFilename.contains(".")) { extension = originalFilename.substring(originalFilename.lastIndexOf(".")); } String fileName = UUID.randomUUID().toString().replace("-", "") + extension; // 写入文件 Path targetPath = dir.resolve(fileName); file.transferTo(targetPath.toFile()); log.info("文件上传成功: {}", targetPath.toAbsolutePath()); // 返回可访问的相对路径 String fileUrl = "/opt/uploads/" + fileName; return Result.success(fileUrl); } /** * 上传文件到阿里云 OSS * POST /api/upload/oss * Body: multipart/form-data, field: file * * @return 可公开访问的 OSS 文件 URL */ @PostMapping("/oss") public Result uploadToOss(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return Result.error(400, "文件不能为空"); } String fileUrl = ossService.upload(file); return Result.success(fileUrl); } }