feat(aiot): 集成腾讯云 COS Java SDK,WVP 直接生成 presigned URL

- pom.xml 新增 cos_api 5.6.227 依赖
- 新建 CosUtil 工具类(读取 ai.cos.* 配置,初始化 COSClient,生成预签名 URL)
- application-dev.yml / application-docker.yml 增加 ai.cos 配置段

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-03 20:06:57 +08:00
parent 86518ab163
commit bdd69ce268
4 changed files with 113 additions and 0 deletions

View File

@@ -422,6 +422,13 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- 腾讯云 COS SDK截图/告警图片 presign -->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.227</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -0,0 +1,96 @@
package com.genersoft.iot.vmp.aiot.util;
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.http.HttpProtocol;
import com.qcloud.cos.region.Region;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.net.URL;
import java.util.Date;
@Slf4j
@Component
public class CosUtil {
@Value("${ai.cos.secret-id:${COS_SECRET_ID:}}")
private String secretId;
@Value("${ai.cos.secret-key:${COS_SECRET_KEY:}}")
private String secretKey;
@Value("${ai.cos.region:${COS_REGION:ap-beijing}}")
private String region;
@Value("${ai.cos.bucket:${COS_BUCKET:}}")
private String bucket;
private COSClient cosClient;
@PostConstruct
public void init() {
if (secretId == null || secretId.isEmpty() || secretKey == null || secretKey.isEmpty()) {
log.warn("[COS] 未配置 COS 凭证COS_SECRET_ID/COS_SECRET_KEY图片代理功能不可用");
return;
}
if (bucket == null || bucket.isEmpty()) {
log.warn("[COS] 未配置 COS_BUCKET图片代理功能不可用");
return;
}
try {
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
ClientConfig config = new ClientConfig(new Region(region));
config.setHttpProtocol(HttpProtocol.https);
cosClient = new COSClient(cred, config);
log.info("[COS] 客户端初始化成功: region={}, bucket={}", region, bucket);
} catch (Exception e) {
log.error("[COS] 客户端初始化失败: {}", e.getMessage());
}
}
@PreDestroy
public void destroy() {
if (cosClient != null) {
cosClient.shutdown();
}
}
/**
* 生成预签名下载 URL
*
* @param objectKey COS 对象路径
* @param expireSeconds 有效期(秒)
* @return presigned URL失败返回 null
*/
public String generatePresignedUrl(String objectKey, int expireSeconds) {
if (cosClient == null) {
log.warn("[COS] 客户端未初始化,无法生成 presigned URL");
return null;
}
try {
Date expiration = new Date(System.currentTimeMillis() + expireSeconds * 1000L);
URL url = cosClient.generatePresignedUrl(bucket, objectKey, expiration);
return url.toString();
} catch (Exception e) {
log.error("[COS] 生成 presigned URL 失败: key={}, error={}", objectKey, e.getMessage());
return null;
}
}
/**
* 生成预签名下载 URL默认 1 小时有效)
*/
public String generatePresignedUrl(String objectKey) {
return generatePresignedUrl(objectKey, 3600);
}
public boolean isAvailable() {
return cosClient != null;
}
}

View File

@@ -124,6 +124,11 @@ ai:
screenshot: screenshot:
# Edge截图回调地址WVP外部可访问地址Edge通过此地址回调截图结果 # Edge截图回调地址WVP外部可访问地址Edge通过此地址回调截图结果
callback-url: http://124.221.55.225:18080 callback-url: http://124.221.55.225:18080
cos:
secret-id:
secret-key:
region: ap-beijing
bucket:
mqtt: mqtt:
# MQTT推送开关 # MQTT推送开关
enabled: false enabled: false

View File

@@ -86,6 +86,11 @@ ai:
enabled: ${AI_SERVICE_ENABLED:false} enabled: ${AI_SERVICE_ENABLED:false}
screenshot: screenshot:
callback-url: ${AI_SCREENSHOT_CALLBACK_URL:} callback-url: ${AI_SCREENSHOT_CALLBACK_URL:}
cos:
secret-id: ${COS_SECRET_ID:}
secret-key: ${COS_SECRET_KEY:}
region: ${COS_REGION:ap-beijing}
bucket: ${COS_BUCKET:}
mqtt: mqtt:
enabled: ${AI_MQTT_ENABLED:false} enabled: ${AI_MQTT_ENABLED:false}
broker: ${AI_MQTT_BROKER:tcp://127.0.0.1:1883} broker: ${AI_MQTT_BROKER:tcp://127.0.0.1:1883}