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:
7
pom.xml
7
pom.xml
@@ -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>
|
||||||
|
|||||||
96
src/main/java/com/genersoft/iot/vmp/aiot/util/CosUtil.java
Normal file
96
src/main/java/com/genersoft/iot/vmp/aiot/util/CosUtil.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user