lrj
2 天以前 c61d4fe27c97d2ecc907756aa571a4ef14a7b9b6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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<String, String> 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<String, String> 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();
        }
    }
}