package com.dsideal.Ai.Util.Liblib.Kit; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.Getter; import okhttp3.*; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.RandomStringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; public class LibLibCommon { // API基础URL protected static final String API_BASE_URL = "https://openapi.liblibai.cloud"; // API访问凭证 protected static final String accessKey="sOCtVLVTNOZkRMajlhzCmg"; // Access Key protected static final String secretKey="PUe8QTRG9i0G9EbpedHmIpLQ0FyxoYY9"; // Secret Key // 查询任务状态API路径 protected static final String QUERY_STATUS_PATH = "/api/generate/webui/status"; // 日志 private static final Logger log = LoggerFactory.getLogger(LibLibCommon.class); /** * 签名信息类,包含签名、时间戳和随机字符串 */ @Getter public static class SignatureInfo { private final String signature; private final long timestamp; private final String signatureNonce; public SignatureInfo(String signature, long timestamp, String signatureNonce) { this.signature = signature; this.timestamp = timestamp; this.signatureNonce = signatureNonce; } } /** * 创建OkHttpClient实例 * @return OkHttpClient实例 */ protected static OkHttpClient createHttpClient() { return new OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) .writeTimeout(60, TimeUnit.SECONDS) .build(); } /** * 生成完整的签名信息,包括签名、时间戳和随机字符串 * @param uri API接口的uri地址 * @return 签名信息对象 */ public static SignatureInfo sign(String uri) { // 当前毫秒时间戳 long timestamp = System.currentTimeMillis(); // 随机字符串 String signatureNonce = RandomStringUtils.randomAlphanumeric(10); // 拼接请求数据 String content = uri + "&" + timestamp + "&" + signatureNonce; try { // 生成签名 SecretKeySpec secret = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(secret); String signature = Base64.encodeBase64URLSafeString(mac.doFinal(content.getBytes())); return new SignatureInfo(signature, timestamp, signatureNonce); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("no such algorithm"); } catch (InvalidKeyException e) { throw new RuntimeException(e); } } /** * 清理URL,移除可能的反引号和多余空格 * @param url 原始URL * @return 清理后的URL */ protected static String cleanUrl(String url) { if (url == null || url.isEmpty()) { return url; } return url.trim().replace("`", ""); } /** * 构建带签名的URL * @param uri API路径 * @param signInfo 签名信息 * @return 构建好的HttpUrl.Builder */ protected static HttpUrl.Builder buildSignedUrl(String uri, SignatureInfo signInfo) { return HttpUrl.parse(API_BASE_URL + uri).newBuilder() .addQueryParameter("AccessKey", accessKey) .addQueryParameter("Signature", signInfo.getSignature()) .addQueryParameter("Timestamp", String.valueOf(signInfo.getTimestamp())) .addQueryParameter("SignatureNonce", signInfo.getSignatureNonce()); } /** * 发送HTTP请求并处理响应 * @param request HTTP请求 * @param logPrefix 日志前缀 * @return 响应的JSON对象 * @throws IOException 异常信息 */ protected static JSONObject sendRequest(Request request, String logPrefix) throws IOException { OkHttpClient client = createHttpClient(); // 执行请求 log.info("{}: {}", logPrefix, request.url()); Response response = client.newCall(request).execute(); // 处理响应 if (!response.isSuccessful()) { String errorMsg = logPrefix + "失败,状态码: " + response.code(); log.error(errorMsg); throw new IOException(errorMsg); } // 解析响应 String responseBody = response.body().string(); log.info("{}响应: {}", logPrefix, responseBody); JSONObject responseJson = JSON.parseObject(responseBody); int code = responseJson.getIntValue("code"); if (code != 0) { String errorMsg = logPrefix + "失败,错误码: " + code + ", 错误信息: " + responseJson.getString("msg"); log.error(errorMsg); throw new IOException(errorMsg); } return responseJson; } /** * 查询生图任务结果 * * @param generateUuid 生图任务UUID * @return 任务结果信息 * @throws IOException 异常信息 */ public static JSONObject queryTaskResult(String generateUuid) throws IOException { // 构建请求体 JSONObject requestBody = new JSONObject(); requestBody.put("generateUuid", generateUuid); // 获取API路径 String uri = QUERY_STATUS_PATH; // 生成签名信息 SignatureInfo signInfo = sign(uri); // 构建带签名的URL HttpUrl.Builder urlBuilder = buildSignedUrl(uri, signInfo); // 创建请求 MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, requestBody.toJSONString()); Request request = new Request.Builder() .url(urlBuilder.build()) .method("POST", body) .addHeader("Content-Type", "application/json") .build(); // 发送请求并获取响应 JSONObject responseJson = sendRequest(request, "查询生图任务结果"); return responseJson.getJSONObject("data"); } /** * 获取生成图片的URL列表 * * @param generateUuid 生图任务UUID * @return 图片URL列表 * @throws IOException 异常信息 */ public static List getGeneratedImageUrls(String generateUuid) throws IOException { JSONObject resultData = queryTaskResult(generateUuid); List imageUrls = new ArrayList<>(); // 检查生成状态 int generateStatus = resultData.getIntValue("generateStatus"); if (generateStatus == 5) { // 5表示生成成功 if (resultData.containsKey("images")) { for (Object imageObj : resultData.getJSONArray("images")) { JSONObject imageJson = (JSONObject) imageObj; String imageUrl = imageJson.getString("imageUrl"); if (imageUrl != null && !imageUrl.isEmpty()) { // 清理URL imageUrl = cleanUrl(imageUrl); imageUrls.add(imageUrl); } } } } else { log.info("生图任务尚未完成,当前状态: {}, 完成百分比: {}%", generateStatus, resultData.getIntValue("percentCompleted")); } return imageUrls; } /** * 创建通用的HTTP请求 * @param uri API路径 * @param requestBody 请求体JSON对象 * @return 构建好的Request对象 */ protected static Request createRequest(String uri, JSONObject requestBody) { // 生成签名信息 SignatureInfo signInfo = sign(uri); // 构建带签名的URL HttpUrl.Builder urlBuilder = buildSignedUrl(uri, signInfo); // 创建请求 MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, requestBody.toJSONString()); return new Request.Builder() .url(urlBuilder.build()) .method("POST", body) .addHeader("Content-Type", "application/json") .build(); } public static void main(String[] args) { String uri = "https://openapi.liblibai.cloud/api/model/version/get"; SignatureInfo signInfo = sign(uri); System.out.println(signInfo.toString()); } }