From bdd69ce26894a58dc039c58ce320575a562c0708 Mon Sep 17 00:00:00 2001 From: 16337 <1633794139@qq.com> Date: Tue, 3 Mar 2026 20:06:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(aiot):=20=E9=9B=86=E6=88=90=E8=85=BE?= =?UTF-8?q?=E8=AE=AF=E4=BA=91=20COS=20Java=20SDK=EF=BC=8CWVP=20=E7=9B=B4?= =?UTF-8?q?=E6=8E=A5=E7=94=9F=E6=88=90=20presigned=20URL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- pom.xml | 7 ++ .../genersoft/iot/vmp/aiot/util/CosUtil.java | 96 +++++++++++++++++++ src/main/resources/application-dev.yml | 5 + src/main/resources/application-docker.yml | 5 + 4 files changed, 113 insertions(+) create mode 100644 src/main/java/com/genersoft/iot/vmp/aiot/util/CosUtil.java diff --git a/pom.xml b/pom.xml index 573c936a8..3616f1cfd 100644 --- a/pom.xml +++ b/pom.xml @@ -422,6 +422,13 @@ spring-boot-starter-test test + + + + com.qcloud + cos_api + 5.6.227 + diff --git a/src/main/java/com/genersoft/iot/vmp/aiot/util/CosUtil.java b/src/main/java/com/genersoft/iot/vmp/aiot/util/CosUtil.java new file mode 100644 index 000000000..0b0d1aaac --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/aiot/util/CosUtil.java @@ -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; + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 59d170601..671512501 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -124,6 +124,11 @@ ai: screenshot: # Edge截图回调地址(WVP外部可访问地址,Edge通过此地址回调截图结果) callback-url: http://124.221.55.225:18080 + cos: + secret-id: + secret-key: + region: ap-beijing + bucket: mqtt: # MQTT推送开关 enabled: false diff --git a/src/main/resources/application-docker.yml b/src/main/resources/application-docker.yml index 4a24fa674..fb16a68b0 100644 --- a/src/main/resources/application-docker.yml +++ b/src/main/resources/application-docker.yml @@ -86,6 +86,11 @@ ai: enabled: ${AI_SERVICE_ENABLED:false} screenshot: 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: enabled: ${AI_MQTT_ENABLED:false} broker: ${AI_MQTT_BROKER:tcp://127.0.0.1:1883}