package cn.iocoder.yudao.module.system.controller.admin.storage; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.system.controller.admin.storage.vo.SystemStorageBlobRespVO; import cn.iocoder.yudao.module.system.dal.dataobject.storage.SystemStorageBlobDO; import cn.iocoder.yudao.module.system.service.storage.SystemStorageBlobService; import cn.iocoder.yudao.module.system.util.storage.StorageFileUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import jakarta.annotation.security.PermitAll; import lombok.AllArgsConstructor; import org.springframework.core.io.FileSystemResource; import org.springframework.http.ContentDisposition; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; /** * 管理后台 - 文件上传/预览/下载 * * @author 芋道源码 */ @Tag(name = "管理后台 - 文件上传") @RestController @RequestMapping("/system/storage-blob") @Validated public class SystemStorageBlobController { @Resource private SystemStorageBlobService storageBlobService; @Resource private StorageFileUtil fileUtil; @PostMapping("/upload") @Operation(summary = "文件上传") public CommonResult> uploadFile( @RequestParam("files") List files) { return success(storageBlobService.upload(files, false)); } @PostMapping("/public-upload") @Operation(summary = "公共文件上传(永久有效,慎用)") public CommonResult> publicUploadFile( @RequestParam("files") List files) { return success(storageBlobService.upload(files, true)); } @GetMapping("/preview/{fileName}") @Operation(summary = "文件预览") @PermitAll public ResponseEntity preview( @PathVariable String fileName, @RequestParam(value = "token", required = false) String token, @RequestParam(value = "publicKey", required = false) String publicKey) throws Exception { File file; if (publicKey != null) { file = fileUtil.compressFile(storageBlobService.getPublicFile(fileName, publicKey)); } else { file = fileUtil.compressFile(storageBlobService.getFileByToken(fileName, token)); } String contentType = Files.probeContentType(file.toPath()); ContentDisposition contentDisposition = ContentDisposition.inline() .filename(fileName, StandardCharsets.UTF_8) .build(); return ResponseEntity.ok() .contentType(MediaType.parseMediaType(contentType != null ? contentType : "application/octet-stream")) .contentLength(file.length()) .header("Content-Disposition", contentDisposition.toString()) .body(new FileSystemResource(file)); } @GetMapping("/download/{fileName}") @Operation(summary = "文件下载") @PermitAll public void download( @PathVariable String fileName, @RequestParam(value = "token", required = false) String token, @RequestParam(value = "publicKey", required = false) String publicKey, HttpServletResponse response) throws Exception { File file; if (publicKey != null) { file = fileUtil.compressFile(storageBlobService.getPublicFile(fileName, publicKey)); } else { file = fileUtil.compressFile(storageBlobService.getFileByToken(fileName, token)); } String originalFileName = storageBlobService.getDownloadFileName(fileName); String encodedFileName = URLEncoder.encode(originalFileName, StandardCharsets.UTF_8.name()).replace("+", "%20"); response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + encodedFileName); response.setContentLengthLong(file.length()); Files.copy(file.toPath(), response.getOutputStream()); } }