package com.backendsys.controller.Upload; import com.backendsys.entity.System.SysFile.SysFileDTO; import com.backendsys.entity.Tencent.TencentCos.MultipartUploadDTO; import com.backendsys.service.SDKService.SDKTencent.SDKTencentCOSService; import com.backendsys.utils.CommonUtil; import com.backendsys.utils.response.Result; import com.backendsys.utils.response.ResultEnum; import com.qcloud.cos.COSClient; import com.qcloud.cos.ClientConfig; import com.qcloud.cos.auth.BasicCOSCredentials; import com.qcloud.cos.auth.COSCredentials; import com.qcloud.cos.model.*; import com.qcloud.cos.region.Region; import com.qcloud.cos.utils.IOUtils; import jakarta.validation.constraints.NotEmpty; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.prepost.PreAuthorize; 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.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; @Validated @RestController public class UploadTencentCOSController { @Value("${tencent.cos.max-size}") private long maxSize; @Value("${tencent.cos.secret-id}") private String secretId; @Value("${tencent.cos.secret-key}") private String secretKey; @Value("${tencent.cos.region}") private String region; @Value("${tencent.cos.bucket-name}") private String bucketName; @Value("${tencent.cos.accessible-domain}") private String accessibleDomain; @Autowired private SDKTencentCOSService sdkTencentCOSService; /** * 权限:待定 * 获得临时上传密钥 (用于前端单文件上传、分片上传) */ @GetMapping("/api/upload/getTempCredentials") public Result getTempCredentials() { return Result.success(sdkTencentCOSService.getTempCredentials("*")); } // /** // * 权限:待定 // * 获得素材文件列表 // */ // @GetMapping("/api/upload/getBucketList") // public Result getBucketList(String next_marker) { // return Result.success(sdkTencentCOSService.getBucketList(next_marker)); // } // 【腾讯云 COS】 // 文档中心 > 对象存储 > API 文档 > Object 接口 > 基本操作 > PUT Object // https://cloud.tencent.com/document/product/436/7749 // https://github.com/tencentyun/cos-java-sdk-v5/blob/master/src/main/java/com/qcloud/cos/demo/PutObjectDemo.java /** * 上传文件 (旧) */ @PreAuthorize("@ss.hasPermi(1.1)") @PostMapping("/api/tencent/cosUpload") public Result uploadTencentCOS(@RequestParam("file") MultipartFile file) { // 检查上传的文件是否为空 if (file.isEmpty()) { return Result.error(ResultEnum.INTERNAL_ERROR.getCode(), "文件不能为空"); } // 判断文件大小是否超过 if (file.getSize() > maxSize) { return Result.error(ResultEnum.INTERNAL_ERROR.getCode(), "文件不能大于 " + maxSize/1024/1024 + " MB"); } // 按日期作为文件目录 (腾讯云使用 /,所以不需要配置 File.separator) String dateDir = new SimpleDateFormat("yyyyMMdd").format(new Date()) + '/'; // 生成后缀名 String originalFileName = file.getOriginalFilename(); String suffix = originalFileName.substring(originalFileName.lastIndexOf(".")); // 生成新的文件名 String newFileName = CommonUtil.generateFilename(suffix); // String objectName = dateDir + newFileName; // -- COS ------------------------------------------------------------------ // 初始化用户身份信息(secretId, secretKey) COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); // 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224 Region region1 = new Region(region); ClientConfig clientConfig = new ClientConfig(region1); clientConfig.setRegion(region1); // 生成cos客户端 COSClient cosClient = new COSClient(cred, clientConfig); try { // 获取文件内容 InputStream inputStream = file.getInputStream(); // 将文件内容写入临时文件 File tempFile = File.createTempFile("temp", null); try (FileOutputStream outputStream = new FileOutputStream(tempFile)) { IOUtils.copy(inputStream, outputStream); } // 创建 PutObjectRequest 对象。 PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, tempFile); ObjectMetadata objectMetadata = new ObjectMetadata(); putObjectRequest.withMetadata(objectMetadata); // 创建 PutObject 请求。(异步) PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest); } catch (IOException e) { System.out.println("IOException e:"); System.out.println(e); } finally { if (cosClient != null) { cosClient.shutdown(); } } // 返回值 结构 Map map = new LinkedHashMap<>(); map.put("filename", newFileName); map.put("url", accessibleDomain + "/" + objectName); // File.separator map.put("type", suffix.replace(".", "")); map.put("size", file.getSize()); return Result.success(map); } /** * 简单上传文件 */ @PreAuthorize("@ss.hasPermi(1.1)") @PostMapping("/api/upload/simpleUpload") public Result simpleUpload(@RequestParam("file") MultipartFile file) { return Result.success(sdkTencentCOSService.simpleUpload(file)); } /** * 大文件分块上传 */ @PreAuthorize("@ss.hasPermi(1.1)") @PostMapping("/api/upload/multipartUpload") public Result multipartUpload(@Validated(MultipartUploadDTO.Upload.class) MultipartUploadDTO multipartUploadDTO) { return Result.success(sdkTencentCOSService.multipartUpload(multipartUploadDTO)); } /** * 查询已上传分块 */ @PreAuthorize("@ss.hasPermi(1.1)") @GetMapping("/api/upload/listParts") public Result listParts(@NotEmpty(message="upload_id 不能为空") String upload_id, @NotEmpty(message="key 不能为空") String key) { return Result.success(sdkTencentCOSService.listParts(upload_id, key)); } /** * 查询分块上传任务ID */ @PreAuthorize("@ss.hasPermi(1.1)") @GetMapping("/api/upload/getMultipartUploadIds") public Result getMultipartUploadIds(@NotEmpty(message="key 不能为空") String key) { return Result.success(sdkTencentCOSService.listMultipartUploads(key)); } /** * 终止分块上传任务 */ @PreAuthorize("@ss.hasPermi(1.1)") @PostMapping("/api/upload/abortMultipartUpload") public Result abortMultipartUpload(@Validated(MultipartUploadDTO.Abort.class) @RequestBody MultipartUploadDTO multipartUploadDTO) { return Result.success(sdkTencentCOSService.abortMultipartUpload(multipartUploadDTO)); } /** * 删除文件 */ @PreAuthorize("@ss.hasPermi(1.1)") @DeleteMapping("/api/upload/removeUploadFile") public Result removeUploadFile(@Validated(SysFileDTO.Remove.class) @RequestBody SysFileDTO sysFileDTO) { return Result.success(sdkTencentCOSService.removeUploadFile(sysFileDTO)); } }