FileUploadController.java 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package com.xuekairui.user.controller;
  2. import com.xuekairui.common.Result;
  3. import com.xuekairui.user.service.OssService;
  4. import lombok.RequiredArgsConstructor;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.springframework.beans.factory.annotation.Value;
  7. import org.springframework.web.bind.annotation.*;
  8. import org.springframework.web.multipart.MultipartFile;
  9. import java.io.IOException;
  10. import java.nio.file.Files;
  11. import java.nio.file.Path;
  12. import java.nio.file.Paths;
  13. import java.util.UUID;
  14. /**
  15. * 通用文件上传控制器
  16. * <ul>
  17. * <li>POST /api/upload — 本地存储(兼容旧版)</li>
  18. * <li>POST /api/upload/oss — 阿里云 OSS 存储,返回公网 URL</li>
  19. * </ul>
  20. */
  21. @Slf4j
  22. @RestController
  23. @RequestMapping("/api/upload")
  24. @RequiredArgsConstructor
  25. public class FileUploadController {
  26. private final OssService ossService;
  27. @Value("${upload.path:/opt/uploads}")
  28. private String uploadPath;
  29. /**
  30. * 上传单个文件(本地存储)
  31. * POST /api/upload
  32. * Body: multipart/form-data, field: file
  33. *
  34. * @return 文件访问相对路径
  35. */
  36. @PostMapping
  37. public Result<String> upload(@RequestParam("file") MultipartFile file) throws IOException {
  38. if (file.isEmpty()) {
  39. return Result.error(400, "文件不能为空");
  40. }
  41. // 确保目录存在
  42. Path dir = Paths.get(uploadPath);
  43. if (!Files.exists(dir)) {
  44. Files.createDirectories(dir);
  45. log.info("创建上传目录: {}", dir.toAbsolutePath());
  46. }
  47. // 生成唯一文件名(保留扩展名)
  48. String originalFilename = file.getOriginalFilename();
  49. String extension = "";
  50. if (originalFilename != null && originalFilename.contains(".")) {
  51. extension = originalFilename.substring(originalFilename.lastIndexOf("."));
  52. }
  53. String fileName = UUID.randomUUID().toString().replace("-", "") + extension;
  54. // 写入文件
  55. Path targetPath = dir.resolve(fileName);
  56. file.transferTo(targetPath.toFile());
  57. log.info("文件上传成功: {}", targetPath.toAbsolutePath());
  58. // 返回可访问的相对路径
  59. String fileUrl = "/opt/uploads/" + fileName;
  60. return Result.success(fileUrl);
  61. }
  62. /**
  63. * 上传文件到阿里云 OSS
  64. * POST /api/upload/oss
  65. * Body: multipart/form-data, field: file
  66. *
  67. * @return 可公开访问的 OSS 文件 URL
  68. */
  69. @PostMapping("/oss")
  70. public Result<String> uploadToOss(@RequestParam("file") MultipartFile file) {
  71. if (file.isEmpty()) {
  72. return Result.error(400, "文件不能为空");
  73. }
  74. String fileUrl = ossService.upload(file);
  75. return Result.success(fileUrl);
  76. }
  77. }