UploadController.java 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package com.snapshot.controller;
  2. import com.snapshot.dto.ApiResponse;
  3. import com.snapshot.dto.UploadRequest;
  4. import com.snapshot.dto.UploadResponse;
  5. import com.snapshot.entity.FileEntry;
  6. import com.snapshot.service.FileStorageService;
  7. import com.snapshot.service.UploadRecordService;
  8. import lombok.RequiredArgsConstructor;
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.springframework.beans.factory.annotation.Value;
  11. import org.springframework.http.MediaType;
  12. import org.springframework.http.ResponseEntity;
  13. import org.springframework.web.bind.annotation.*;
  14. import org.springframework.web.multipart.MultipartFile;
  15. import javax.validation.Valid;
  16. import java.io.File;
  17. import java.io.IOException;
  18. import java.nio.file.Files;
  19. import java.nio.file.Path;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. /**
  24. * 上传控制器
  25. */
  26. @Slf4j
  27. @RestController
  28. @RequestMapping("/api/upload")
  29. @RequiredArgsConstructor
  30. public class UploadController {
  31. private final UploadRecordService uploadRecordService;
  32. private final FileStorageService fileStorageService;
  33. @Value("${app.file.max-size:52428800}")
  34. private long maxFileSize;
  35. @Value("${app.file.max-count:10}")
  36. private int maxFileCount;
  37. /**
  38. * 创建上传记录
  39. */
  40. @PostMapping
  41. public ResponseEntity<ApiResponse<UploadResponse>> createUpload(
  42. @Valid @RequestBody UploadRequest request) {
  43. log.info("创建上传记录: 过期时间={}小时, 最大下载次数={}",
  44. request.getExpirationHours(), request.getMaxDownloadCount());
  45. UploadResponse response = uploadRecordService.createUploadRecord(request);
  46. return ResponseEntity.ok(ApiResponse.success(response));
  47. }
  48. /**
  49. * 上传文件
  50. */
  51. @PostMapping(value = "/{id}/files", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  52. public ResponseEntity<ApiResponse<Map<String, Object>>> uploadFiles(
  53. @PathVariable String id,
  54. @RequestParam("files") List<MultipartFile> files) {
  55. log.info("上传文件到记录 {}: 文件数量={}", id, files.size());
  56. // 验证文件数量
  57. if (!fileStorageService.isValidFileCount(files, maxFileCount)) {
  58. return ResponseEntity.badRequest()
  59. .body(ApiResponse.error(400, "文件数量超过限制,最多" + maxFileCount + "个文件"));
  60. }
  61. // 验证文件大小
  62. for (MultipartFile file : files) {
  63. if (!fileStorageService.isValidFileSize(file, maxFileSize)) {
  64. return ResponseEntity.badRequest()
  65. .body(ApiResponse.error(400,
  66. "文件 " + file.getOriginalFilename() + " 超过大小限制,最大" + (maxFileSize / 1024 / 1024) + "MB"));
  67. }
  68. }
  69. try {
  70. List<FileEntry> fileEntries = fileStorageService.saveFiles(id, files);
  71. Map<String, Object> result = new HashMap<>();
  72. result.put("uploadId", id);
  73. result.put("fileCount", fileEntries.size());
  74. result.put("files", fileEntries);
  75. return ResponseEntity.ok(ApiResponse.success("文件上传成功", result));
  76. } catch (IOException e) {
  77. log.error("文件上传失败: {}", e.getMessage(), e);
  78. return ResponseEntity.status(500)
  79. .body(ApiResponse.error("文件上传失败: " + e.getMessage()));
  80. }
  81. }
  82. /**
  83. * 获取上传记录详情
  84. */
  85. @GetMapping("/{id}")
  86. public ResponseEntity<ApiResponse<UploadResponse>> getUploadRecord(@PathVariable String id) {
  87. try {
  88. log.info("查询上传记录: {}", id);
  89. UploadResponse response = uploadRecordService.getUploadRecord(id);
  90. return ResponseEntity.ok(ApiResponse.success(response));
  91. } catch (RuntimeException e) {
  92. log.error("查询上传记录失败: {}", e.getMessage());
  93. return ResponseEntity.status(404)
  94. .body(ApiResponse.error(404, e.getMessage()));
  95. }
  96. }
  97. /**
  98. * 验证密码
  99. */
  100. @PostMapping("/{id}/verify-password")
  101. public ResponseEntity<ApiResponse<Boolean>> verifyPassword(
  102. @PathVariable String id,
  103. @RequestBody Map<String, String> request) {
  104. String password = request.get("password");
  105. boolean valid = uploadRecordService.verifyPassword(id, password);
  106. return ResponseEntity.ok(ApiResponse.success(valid));
  107. }
  108. /**
  109. * 删除上传记录
  110. */
  111. @DeleteMapping("/{id}")
  112. public ResponseEntity<ApiResponse<Void>> deleteUploadRecord(@PathVariable String id) {
  113. log.info("删除上传记录: {}", id);
  114. uploadRecordService.deleteUploadRecord(id);
  115. return ResponseEntity.ok(ApiResponse.success("删除成功", null));
  116. }
  117. /**
  118. * 根据前缀查找ID
  119. */
  120. @GetMapping("/resolve/{prefix}")
  121. public ResponseEntity<ApiResponse<Map<String, String>>> resolveByPrefix(@PathVariable String prefix) {
  122. try {
  123. String fullId = uploadRecordService.resolveIdByPrefix(prefix);
  124. Map<String, String> result = new HashMap<>();
  125. result.put("prefix", prefix);
  126. result.put("fullId", fullId);
  127. return ResponseEntity.ok(ApiResponse.success(result));
  128. } catch (RuntimeException e) {
  129. return ResponseEntity.status(404)
  130. .body(ApiResponse.error(404, e.getMessage()));
  131. }
  132. }
  133. }