package com.rongyichuang.judge.service; 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.auth.COSSigner; import com.qcloud.cos.http.HttpMethodName; import com.qcloud.cos.region.Region; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.HashMap; import java.util.Map; @Service public class CosService { @Value("${cos.secret-id}") private String secretId; @Value("${cos.secret-key}") private String secretKey; @Value("${cos.bucket}") private String bucket; @Value("${cos.region}") private String region; /** * 生成腾讯云 COS 临时上传凭证 */ public Map generateUploadCredentials(String fileName) { // 生成文件路径:按日期分目录 String dateDir = new java.text.SimpleDateFormat("yyyyMMdd").format(new Date()); String key = dateDir + "/" + fileName; // 设置临时密钥有效期(5分钟,减少时间以避免时间同步问题) long currentTime = System.currentTimeMillis(); Date expiration = new Date(currentTime + 5 * 60 * 1000); System.out.println("=== COS预签名URL生成调试信息 ==="); System.out.println("当前系统时间: " + new Date(currentTime)); System.out.println("过期时间: " + expiration); System.out.println("当前Unix时间戳: " + (currentTime / 1000)); System.out.println("过期Unix时间戳: " + ((currentTime + 5 * 60 * 1000) / 1000)); System.out.println("文件Key: " + key); System.out.println("存储桶: " + bucket); System.out.println("地域: " + region); // 创建COS客户端 COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); ClientConfig clientConfig = new ClientConfig(new Region(region)); COSClient cosClient = new COSClient(cred, clientConfig); try { // 生成预签名URL java.net.URL url = cosClient.generatePresignedUrl(bucket, key, expiration, HttpMethodName.PUT); String presignedUrl = url.toString(); // 格式化过期时间 String expirationStr = Instant.ofEpochMilli(expiration.getTime()) .atZone(ZoneId.of("Asia/Shanghai")) .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); Map credentials = new HashMap<>(); credentials.put("bucket", bucket); credentials.put("region", region); credentials.put("key", key); credentials.put("presignedUrl", presignedUrl); credentials.put("expiration", expirationStr); return credentials; } finally { cosClient.shutdown(); } } /** * 直接上传文件到COS */ public String uploadFile(org.springframework.web.multipart.MultipartFile file, String fileName) throws Exception { // 生成文件路径:按日期分目录 String dateDir = new java.text.SimpleDateFormat("yyyyMMdd").format(new Date()); String key = dateDir + "/" + fileName; System.out.println("=== COS文件上传调试信息 ==="); System.out.println("文件Key: " + key); System.out.println("文件大小: " + file.getSize()); System.out.println("文件类型: " + file.getContentType()); // 创建COS客户端 COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); ClientConfig clientConfig = new ClientConfig(new Region(region)); COSClient cosClient = new COSClient(cred, clientConfig); try { // 创建上传请求 com.qcloud.cos.model.PutObjectRequest putObjectRequest = new com.qcloud.cos.model.PutObjectRequest(bucket, key, file.getInputStream(), null); // 设置文件元数据 com.qcloud.cos.model.ObjectMetadata metadata = new com.qcloud.cos.model.ObjectMetadata(); metadata.setContentLength(file.getSize()); if (file.getContentType() != null) { metadata.setContentType(file.getContentType()); } putObjectRequest.setMetadata(metadata); // 执行上传 com.qcloud.cos.model.PutObjectResult result = cosClient.putObject(putObjectRequest); System.out.println("上传成功,ETag: " + result.getETag()); return key; // 返回相对路径 } finally { cosClient.shutdown(); } } /** * 获取文件访问 URL */ public String getFileUrl(String key) { COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); ClientConfig clientConfig = new ClientConfig(new Region(region)); COSClient cosClient = new COSClient(cred, clientConfig); try { return cosClient.getObjectUrl(bucket, key).toString(); } finally { cosClient.shutdown(); } } }