From 9379f2722c01e32272c4ac28ca7ca82e9ff2af51 Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Tue, 13 May 2025 11:11:25 +0800 Subject: [PATCH] 'commit' --- .../aiSupport/Util/KeLing/KlAccount.java | 316 +++++++++++++++--- 1 file changed, 269 insertions(+), 47 deletions(-) diff --git a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/KeLing/KlAccount.java b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/KeLing/KlAccount.java index 0c8b0ee1..47970564 100644 --- a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/KeLing/KlAccount.java +++ b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/KeLing/KlAccount.java @@ -1,52 +1,274 @@ package com.dsideal.aiSupport.Util.KeLing; -public class KlAccount { - /* -查询账号下资源包列表及余量 -注:该接口免费调用,方便您查询账号下的资源包列表和余量,但请您注意控制请求速率(QPS<=1) - -网络协议 请求地址 请求方法 请求格式 响应格式 -https /account/costs GET application/json application/json - -请求头 -字段 值 描述 -Content-Type application/json 数据交换格式 -Authorization 鉴权信息,参考接口鉴权 鉴权信息,参考接口鉴权 - -请求路径参数 -字段 类型 必填 默认值 描述 -start_time int 是 无 查询的开始时间,Unix时间戳、单位ms -end_time int 是 无 查询的结束时间,Unix时间戳、单位ms -resource_pack_name string 否 无 资源包名称,用于精准指定查询某个资源包 - -请求体 -无 - -响应体 -{ - "code": 0, //错误码;具体定义错误码 - "message": "string", //错误信息 - "request_id": "string", //请求ID,系统生成,用于跟踪请求、排查问题 - "data": { - "code": 0, //错误码;具体定义错误码 - "msg": "string", //错误信息 - "resource_pack_subscribe_infos": [ - //资源包列表 - { - "resource_pack_name": "视频生成-10000条", //资源包名称 - "resource_pack_id": "509f3fd3d4ab4a3f9eec5db27aa44f27", //资源包ID - "resource_pack_type": "decreasing_total", //资源包类型,枚举值,"decreasing_toal" = 总量递减型,"constant_period" = 周期恒定型 - "total_quantity": 200.0, //总量 - "remaining_quantity": 118.0, //余量(请注意,余量统计有12h的延迟) - "purchase_time": 1726124664368, //购买时间,Unix时间戳、单位ms - "effective_time": 1726124664368, //生效时间,Unix时间戳、单位ms - "invalid_time": 1727366400000, //失效时间,Unix时间戳、单位ms - "status": "expired" //资源包状态,枚举值,"toBeOnline" = 待生效,"online" = 生效中,"expired" = 已到期,"runOut" = 已用完 - } - ] - } -} +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.dsideal.aiSupport.Util.KeLing.Kit.KlCommon; +import com.dsideal.aiSupport.Util.KeLing.Kit.KlErrorCode; +import lombok.Getter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * 可灵AI账户信息查询工具类 + */ +public class KlAccount extends KlCommon { + private static final Logger log = LoggerFactory.getLogger(KlAccount.class); + private static final String BASE_URL = "https://api.klingai.com"; + private static final String ACCOUNT_COSTS_PATH = "/account/costs"; + + /** + * 查询账号下资源包列表及余量 + * + * @param startTime 查询的开始时间,Unix时间戳、单位ms + * @param endTime 查询的结束时间,Unix时间戳、单位ms + * @return 资源包信息列表 + * @throws Exception 异常信息 + */ + public static List queryResourcePacks(long startTime, long endTime) throws Exception { + return queryResourcePacks(startTime, endTime, null); + } + + /** + * 查询账号下资源包列表及余量 + * + * @param startTime 查询的开始时间,Unix时间戳、单位ms + * @param endTime 查询的结束时间,Unix时间戳、单位ms + * @param resourcePackName 资源包名称,用于精准指定查询某个资源包,可为null + * @return 资源包信息列表 + * @throws Exception 异常信息 + */ + public static List queryResourcePacks(long startTime, long endTime, String resourcePackName) throws Exception { + // 获取JWT令牌 + String jwt = getJwt(); + + // 构建URL + StringBuilder urlBuilder = new StringBuilder(BASE_URL) + .append(ACCOUNT_COSTS_PATH) + .append("?start_time=").append(startTime) + .append("&end_time=").append(endTime); + + // 如果提供了资源包名称,则添加到URL中 + if (resourcePackName != null && !resourcePackName.isEmpty()) { + urlBuilder.append("&resource_pack_name=").append(resourcePackName); + } + + // 使用Hutool发送GET请求 + HttpResponse response = HttpRequest.get(urlBuilder.toString()) + .header("Content-Type", "application/json") + .header("Authorization", "Bearer " + jwt) + .execute(); + + log.info("查询账户资源包请求URL:{}", urlBuilder.toString()); + + // 检查响应状态码 + if (response.getStatus() != 200) { + throw new Exception("请求失败,状态码:" + response.getStatus()); + } + + // 解析响应 + String responseBody = response.body(); + JSONObject responseJson = JSONUtil.parseObj(responseBody); + log.info("查询账户资源包响应:{}", responseBody); + + // 检查响应状态 + int code = responseJson.getInt("code"); + if (code != 0) { + String message = responseJson.getStr("message"); + String solution = KlErrorCode.getSolutionByCode(code); + String errorMsg = String.format("查询账户资源包失败:[%d] %s - %s", code, message, solution); + throw new Exception(errorMsg); + } + + // 解析资源包信息 + List resourcePackInfoList = new ArrayList<>(); + JSONObject data = responseJson.getJSONObject("data"); + + // 检查data中的code + int dataCode = data.getInt("code"); + if (dataCode != 0) { + String dataMsg = data.getStr("msg"); + throw new Exception("查询账户资源包失败:" + dataMsg); + } + + // 获取资源包列表 + JSONArray resourcePackArray = data.getJSONArray("resource_pack_subscribe_infos"); + if (resourcePackArray != null && !resourcePackArray.isEmpty()) { + for (int i = 0; i < resourcePackArray.size(); i++) { + JSONObject resourcePackJson = resourcePackArray.getJSONObject(i); + ResourcePackInfo resourcePackInfo = new ResourcePackInfo(); + + resourcePackInfo.setResourcePackName(resourcePackJson.getStr("resource_pack_name")); + resourcePackInfo.setResourcePackId(resourcePackJson.getStr("resource_pack_id")); + resourcePackInfo.setResourcePackType(resourcePackJson.getStr("resource_pack_type")); + resourcePackInfo.setTotalQuantity(resourcePackJson.getDouble("total_quantity")); + resourcePackInfo.setRemainingQuantity(resourcePackJson.getDouble("remaining_quantity")); + resourcePackInfo.setPurchaseTime(resourcePackJson.getLong("purchase_time")); + resourcePackInfo.setEffectiveTime(resourcePackJson.getLong("effective_time")); + resourcePackInfo.setInvalidTime(resourcePackJson.getLong("invalid_time")); + resourcePackInfo.setStatus(resourcePackJson.getStr("status")); + + resourcePackInfoList.add(resourcePackInfo); + } + } + + return resourcePackInfoList; + } + + /** + * 打印资源包信息 + * + * @param resourcePackInfoList 资源包信息列表 + */ + public static void printResourcePackInfo(List resourcePackInfoList) { + if (resourcePackInfoList == null || resourcePackInfoList.isEmpty()) { + log.info("未查询到资源包信息"); + return; + } + + log.info("资源包信息列表:"); + for (ResourcePackInfo info : resourcePackInfoList) { + log.info("----------------------------------------"); + log.info("资源包名称: {}", info.getResourcePackName()); + log.info("资源包ID: {}", info.getResourcePackId()); + log.info("资源包类型: {}", getResourcePackTypeDesc(info.getResourcePackType())); + log.info("总量: {}", info.getTotalQuantity()); + log.info("余量: {}", info.getRemainingQuantity()); + log.info("购买时间: {}", formatTimestamp(info.getPurchaseTime())); + log.info("生效时间: {}", formatTimestamp(info.getEffectiveTime())); + log.info("失效时间: {}", formatTimestamp(info.getInvalidTime())); + log.info("状态: {}", getStatusDesc(info.getStatus())); + } + log.info("----------------------------------------"); + } + + /** + * 获取资源包类型描述 + * + * @param type 资源包类型 + * @return 资源包类型描述 + */ + private static String getResourcePackTypeDesc(String type) { + if ("decreasing_total".equals(type)) { + return "总量递减型"; + } else if ("constant_period".equals(type)) { + return "周期恒定型"; + } else { + return type; + } + } + + /** + * 获取资源包状态描述 + * + * @param status 资源包状态 + * @return 资源包状态描述 + */ + private static String getStatusDesc(String status) { + switch (status) { + case "toBeOnline": + return "待生效"; + case "online": + return "生效中"; + case "expired": + return "已到期"; + case "runOut": + return "已用完"; + default: + return status; + } + } + + /** + * 格式化时间戳 + * + * @param timestamp 时间戳(毫秒) + * @return 格式化后的时间字符串 + */ + private static String formatTimestamp(long timestamp) { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return sdf.format(new java.util.Date(timestamp)); + } + + /** + * 资源包信息类 + */ + @Getter + public static class ResourcePackInfo { + // Getters and Setters + private String resourcePackName; // 资源包名称 + private String resourcePackId; // 资源包ID + private String resourcePackType; // 资源包类型 + private double totalQuantity; // 总量 + private double remainingQuantity; // 余量 + private long purchaseTime; // 购买时间 + private long effectiveTime; // 生效时间 + private long invalidTime; // 失效时间 + private String status; // 资源包状态 + + public void setResourcePackName(String resourcePackName) { + this.resourcePackName = resourcePackName; + } + + public void setResourcePackId(String resourcePackId) { + this.resourcePackId = resourcePackId; + } + + public void setResourcePackType(String resourcePackType) { + this.resourcePackType = resourcePackType; + } + + public void setTotalQuantity(double totalQuantity) { + this.totalQuantity = totalQuantity; + } + + public void setRemainingQuantity(double remainingQuantity) { + this.remainingQuantity = remainingQuantity; + } + + public void setPurchaseTime(long purchaseTime) { + this.purchaseTime = purchaseTime; + } + + public void setEffectiveTime(long effectiveTime) { + this.effectiveTime = effectiveTime; + } + public void setInvalidTime(long invalidTime) { + this.invalidTime = invalidTime; + } - */ + public void setStatus(String status) { + this.status = status; + } + } + + public static void main(String[] args) { + try { + // 获取当前时间 + long currentTime = System.currentTimeMillis(); + // 设置查询时间范围为过去30天到当前 + long startTime = currentTime - 30 * 24 * 60 * 60 * 1000L; + long endTime = currentTime; + + // 查询所有资源包 + List resourcePackInfoList = queryResourcePacks(startTime, endTime); + + // 打印资源包信息 + printResourcePackInfo(resourcePackInfoList); + + // 如果需要查询特定资源包,可以使用以下代码 + // String specificPackName = "视频生成-10000条"; + // List specificResourcePackInfoList = queryResourcePacks(startTime, endTime, specificPackName); + // printResourcePackInfo(specificResourcePackInfoList); + + } catch (Exception e) { + log.error("查询账户资源包异常: {}", e.getMessage(), e); + } + } }