Merge remote-tracking branch 'origin/dev-ltx' into dev/3.1_release_merge
This commit is contained in:
@@ -23,7 +23,7 @@ public class ModelConstants {
|
|||||||
public static final String PRINTBOARD_HIGH_I2I = "doubao-seededit-3-0-i2i-250628";
|
public static final String PRINTBOARD_HIGH_I2I = "doubao-seededit-3-0-i2i-250628";
|
||||||
public static final String PRINTBOARD_ADVANCED_I2I = "doubao-seedream-4-0-250828";
|
public static final String PRINTBOARD_ADVANCED_I2I = "doubao-seedream-4-0-250828";
|
||||||
public static final String IMAGEN_MODEL = "imagen-4.0-generate-001";
|
public static final String IMAGEN_MODEL = "imagen-4.0-generate-001";
|
||||||
public static final String NANO_BANANA = "gemini-2.5-flash-image-preview";
|
public static final String NANO_BANANA = "gemini-2.5-flash-image";
|
||||||
public static final String LOCAL_MODEL = "local";
|
public static final String LOCAL_MODEL = "local";
|
||||||
|
|
||||||
// 风格常量
|
// 风格常量
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ public class CollectionElementVO {
|
|||||||
@ApiModelProperty("二级类型 Outwear Dress Blouse Skirt Trousers(只争对Sketchboard一级类型)")
|
@ApiModelProperty("二级类型 Outwear Dress Blouse Skirt Trousers(只争对Sketchboard一级类型)")
|
||||||
private String level2Type;
|
private String level2Type;
|
||||||
|
|
||||||
|
@ApiModelProperty("三级类型 性别")
|
||||||
|
private String level3Type;
|
||||||
|
|
||||||
@ApiModelProperty("design类型 用户design生成时候区别library和collection")
|
@ApiModelProperty("design类型 用户design生成时候区别library和collection")
|
||||||
private String designType;
|
private String designType;
|
||||||
|
|
||||||
|
|||||||
@@ -675,7 +675,15 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
return new PrepareForGenerateVO(Collections.singletonList(taskId), 200);
|
return new PrepareForGenerateVO(Collections.singletonList(taskId), 200);
|
||||||
}
|
}
|
||||||
public String toProductAsyncTask(String imagePath, String useModel, String prompt) {
|
public String toProductAsyncTask(String imagePath, String useModel, String prompt) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
log.info("开始执行toProductAsyncTask - model: {}, imagePath: {}, prompt: {}",
|
||||||
|
useModel, imagePath, prompt);
|
||||||
|
|
||||||
|
System.setProperty("https.proxyHost", "127.0.0.1");
|
||||||
|
System.setProperty("https.proxyPort", "10809");
|
||||||
|
|
||||||
if (StringUtil.isNullOrEmpty(imagePath)||StringUtil.isNullOrEmpty(useModel)||StringUtil.isNullOrEmpty(prompt)){
|
if (StringUtil.isNullOrEmpty(imagePath)||StringUtil.isNullOrEmpty(useModel)||StringUtil.isNullOrEmpty(prompt)){
|
||||||
|
log.error("参数验证失败 - imagePath: {}, useModel: {}, prompt: {}", imagePath, useModel, prompt);
|
||||||
throw new BusinessException("Parameter Exception");
|
throw new BusinessException("Parameter Exception");
|
||||||
}
|
}
|
||||||
AuthPrincipalVo userHolder = UserContext.getUserHolder();
|
AuthPrincipalVo userHolder = UserContext.getUserHolder();
|
||||||
@@ -740,7 +748,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
generationConfig.set("imageConfig", imageConfig);
|
generationConfig.set("imageConfig", imageConfig);
|
||||||
requestBody.set("generationConfig", generationConfig);
|
requestBody.set("generationConfig", generationConfig);
|
||||||
String jsonBody = requestBody.toString();
|
String jsonBody = requestBody.toString();
|
||||||
log.info("Google 请求入参:{}", jsonBody);
|
// log.info("Google 请求入参:{}", jsonBody);
|
||||||
|
|
||||||
GenerateResultVO resultVO = new GenerateResultVO(taskId, null, null, "Pending");
|
GenerateResultVO resultVO = new GenerateResultVO(taskId, null, null, "Pending");
|
||||||
redisUtil.addToString(key, new Gson().toJson(resultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
redisUtil.addToString(key, new Gson().toJson(resultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
@@ -762,60 +770,111 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
throw new RuntimeException("google token error");
|
throw new RuntimeException("google token error");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 异步发送API请求
|
// 异步发送API请求 - 优化网络配置以解决连接中断问题
|
||||||
|
ConnectionPool connectionPool = new ConnectionPool(10, 5, TimeUnit.MINUTES);
|
||||||
OkHttpClient client = new OkHttpClient.Builder()
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
.connectTimeout(30, TimeUnit.SECONDS) // 连接超时时间
|
.connectTimeout(45, TimeUnit.SECONDS) // 增加连接超时时间
|
||||||
.readTimeout(60, TimeUnit.SECONDS) // 读取超时时间
|
.readTimeout(120, TimeUnit.SECONDS) // 增加读取超时时间
|
||||||
.writeTimeout(60, TimeUnit.SECONDS) // 写入超时时间
|
.writeTimeout(120, TimeUnit.SECONDS) // 增加写入超时时间
|
||||||
.retryOnConnectionFailure(true)
|
.callTimeout(180, TimeUnit.SECONDS) // 添加总调用超时时间
|
||||||
|
.connectionPool(connectionPool) // 使用连接池
|
||||||
|
.retryOnConnectionFailure(true) // 启用连接失败重试
|
||||||
.build();
|
.build();
|
||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
.url(endpoint)
|
.url(endpoint)
|
||||||
|
// 移除Connection: close头,使用Keep-Alive连接
|
||||||
.addHeader("Authorization", "Bearer " + tokenValue)
|
.addHeader("Authorization", "Bearer " + tokenValue)
|
||||||
.addHeader("Content-Type", "application/json")
|
.addHeader("Content-Type", "application/json")
|
||||||
|
.addHeader("User-Agent", "AIDA-Client/1.0")
|
||||||
|
.addHeader("Accept", "application/json")
|
||||||
.post(RequestBody.create(MediaType.parse("application/json"), jsonBody))
|
.post(RequestBody.create(MediaType.parse("application/json"), jsonBody))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
try (Response response = client.newCall(request).execute()) {
|
// 实现重试逻辑来处理网络连接问题
|
||||||
String result = response.body().string();
|
int maxRetries = 3;
|
||||||
|
int retryDelay = 2000; // 2秒
|
||||||
|
boolean success = false;
|
||||||
|
|
||||||
log.info("Google 响应结果:{}", result);
|
for (int attempt = 1; attempt <= maxRetries && !success; attempt++) {
|
||||||
com.alibaba.fastjson.JSONObject jsonResponse = JSON.parseObject(result);
|
try {
|
||||||
|
log.info("发起HTTP请求 - 尝试次数: {}/{}, URL: {}, taskId: {}", attempt, maxRetries, request.url(), taskId);
|
||||||
|
long requestStartTime = System.currentTimeMillis();
|
||||||
|
|
||||||
String base64Data = null;
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
long requestEndTime = System.currentTimeMillis();
|
||||||
//根据模型类别按照api取出结果
|
log.info("HTTP请求完成 - 响应状态: {}, 耗时: {}ms, taskId: {}",
|
||||||
if (ModelConstants.NANO_BANANA.equals(useModel)) {
|
response.code(), (requestEndTime - requestStartTime), taskId);
|
||||||
JSONArray candidates = jsonResponse.getJSONArray("candidates");
|
if (!response.isSuccessful()) {
|
||||||
|
log.warn("Google API响应失败,状态码: {} for taskId: {}", response.code(), taskId);
|
||||||
if (candidates != null && !candidates.isEmpty()) {
|
if (attempt < maxRetries) {
|
||||||
com.alibaba.fastjson.JSONObject candidate = candidates.getJSONObject(0);
|
Thread.sleep(retryDelay * attempt); // 递增延迟
|
||||||
com.alibaba.fastjson.JSONObject contentResult = candidate.getJSONObject("content");
|
continue;
|
||||||
JSONArray parts = contentResult.getJSONArray("parts");
|
} else {
|
||||||
|
throw new IOException("HTTP error code: " + response.code());
|
||||||
// 遍历parts数组找到包含inlineData的对象
|
|
||||||
for (int i = 0; i < parts.size(); i++) {
|
|
||||||
com.alibaba.fastjson.JSONObject part = parts.getJSONObject(i);
|
|
||||||
if (part.containsKey("inlineData")) {
|
|
||||||
com.alibaba.fastjson.JSONObject inlineDataResult= part.getJSONObject("inlineData");
|
|
||||||
base64Data = inlineDataResult.getString("data");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (base64Data != null && !base64Data.isEmpty()) {
|
String result = response.body().string();
|
||||||
String resultPath = userId + "/product_image" + "/" + uuid;
|
// log.info("Google 响应结果:{}", result);
|
||||||
String minioPath = minioUtil.base64UploadToPath("data:image/png;base64," + base64Data, userBucket, resultPath);
|
com.alibaba.fastjson.JSONObject jsonResponse = JSON.parseObject(result);
|
||||||
// 生成成功,更新Redis状态和URL
|
|
||||||
GenerateResultVO successResultVO = new GenerateResultVO(taskId, null, minioPath, "Success");
|
String base64Data = null;
|
||||||
redisUtil.addToString(key, new Gson().toJson(successResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
|
||||||
} else {
|
//根据模型类别按照api取出结果
|
||||||
// 没有找到图像数据或数据为空,标记为失败
|
if (ModelConstants.NANO_BANANA.equals(useModel)) {
|
||||||
log.warn("Google generation response does not contain valid image data for taskId: {}", taskId);
|
JSONArray candidates = jsonResponse.getJSONArray("candidates");
|
||||||
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
|
||||||
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
if (candidates != null && !candidates.isEmpty()) {
|
||||||
|
com.alibaba.fastjson.JSONObject candidate = candidates.getJSONObject(0);
|
||||||
|
com.alibaba.fastjson.JSONObject contentResult = candidate.getJSONObject("content");
|
||||||
|
JSONArray parts = contentResult.getJSONArray("parts");
|
||||||
|
|
||||||
|
// 遍历parts数组找到包含inlineData的对象
|
||||||
|
for (int i = 0; i < parts.size(); i++) {
|
||||||
|
com.alibaba.fastjson.JSONObject part = parts.getJSONObject(i);
|
||||||
|
if (part.containsKey("inlineData")) {
|
||||||
|
com.alibaba.fastjson.JSONObject inlineDataResult= part.getJSONObject("inlineData");
|
||||||
|
base64Data = inlineDataResult.getString("data");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base64Data != null && !base64Data.isEmpty()) {
|
||||||
|
String resultPath = userId + "/product_image" + "/" + uuid;
|
||||||
|
String minioPath = minioUtil.base64UploadToPath("data:image/png;base64," + base64Data, userBucket, resultPath);
|
||||||
|
// 生成成功,更新Redis状态和URL
|
||||||
|
GenerateResultVO successResultVO = new GenerateResultVO(taskId, null, minioPath, "Success");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(successResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
success = true;
|
||||||
|
log.info("Google API调用成功 for taskId: {}", taskId);
|
||||||
|
} else {
|
||||||
|
// 没有找到图像数据或数据为空,标记为失败
|
||||||
|
log.warn("Google generation response does not contain valid image data for taskId: {}", taskId);
|
||||||
|
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
success = true; // 这是业务逻辑失败,不需要重试
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("网络连接问题 - 异常类型: {}, 尝试: {}/{}, taskId: {}, 错误详情: {}",
|
||||||
|
e.getClass().getSimpleName(), attempt, maxRetries, taskId, e.getMessage());
|
||||||
|
if (attempt < maxRetries) {
|
||||||
|
int delayMs = retryDelay * attempt;
|
||||||
|
log.info("准备重试 - 延迟: {}ms, 下次尝试: {}/{}, taskId: {}",
|
||||||
|
delayMs, (attempt + 1), maxRetries, taskId);
|
||||||
|
try {
|
||||||
|
Thread.sleep(delayMs); // 递增延迟重试
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
log.error("重试被中断 - taskId: {}", taskId, ie);
|
||||||
|
throw new RuntimeException("重试被中断", ie);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("Google API调用最终失败 - 已达到最大重试次数: {}, taskId: {}", maxRetries, taskId, e);
|
||||||
|
throw e; // 最后一次尝试失败,抛出异常
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -825,6 +884,9 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
}
|
}
|
||||||
}, asyncTaskExecutor);
|
}, asyncTaskExecutor);
|
||||||
|
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
log.info("toProductAsyncTask执行完成 - taskId: {}, 总耗时: {}ms", taskId, (endTime - startTime));
|
||||||
return taskId;
|
return taskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -909,6 +971,9 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
// generationConfig.set("temperature", 1);
|
// generationConfig.set("temperature", 1);
|
||||||
generationConfig.set("maxOutputTokens", 8192);
|
generationConfig.set("maxOutputTokens", 8192);
|
||||||
generationConfig.set("responseModalities", Arrays.asList("TEXT", "IMAGE"));
|
generationConfig.set("responseModalities", Arrays.asList("TEXT", "IMAGE"));
|
||||||
|
JSONObject imageConfig = new JSONObject();
|
||||||
|
imageConfig.set("aspectRatio", "9:16");
|
||||||
|
generationConfig.set("imageConfig", imageConfig);
|
||||||
// generationConfig.set("topP", 0.95);
|
// generationConfig.set("topP", 0.95);
|
||||||
requestBody.set("generationConfig", generationConfig);
|
requestBody.set("generationConfig", generationConfig);
|
||||||
|
|
||||||
@@ -933,7 +998,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
|
|
||||||
String jsonBody = requestBody.toString();
|
String jsonBody = requestBody.toString();
|
||||||
|
|
||||||
log.info("Google 请求入参:{}", jsonBody);
|
// log.info("Google 请求入参:{}", jsonBody);
|
||||||
|
|
||||||
// 生成唯一的任务ID
|
// 生成唯一的任务ID
|
||||||
String taskId = uuid + "-" + userId;
|
String taskId = uuid + "-" + userId;
|
||||||
@@ -945,91 +1010,145 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
|
|
||||||
// 异步处理token获取和API调用
|
// 异步处理token获取和API调用
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
try {
|
long startTime = System.currentTimeMillis();
|
||||||
// 异步获取token
|
log.info("开始执行 createGoogleAsyncTask 方法,taskId: {}, model: {}, prompt: {}", taskId, useModel, prompt);
|
||||||
String tokenValue = null;
|
|
||||||
try (InputStream inputStream = GenerateServiceImpl.class.getClassLoader()
|
|
||||||
.getResourceAsStream("aida-461108-b4afaabebb84.json")) {
|
|
||||||
|
|
||||||
GoogleCredentials credentials = GoogleCredentials
|
final int maxRetries = 3;
|
||||||
.fromStream(inputStream)
|
final int retryDelayMs = 2000;
|
||||||
.createScoped(Collections.singletonList("https://www.googleapis.com/auth/cloud-platform"));
|
|
||||||
|
|
||||||
credentials.refreshIfExpired();
|
for (int attempt = 1; attempt <= maxRetries; attempt++) {
|
||||||
tokenValue = credentials.getAccessToken().getTokenValue();
|
try {
|
||||||
}
|
log.info("Google API 调用尝试 {}/{} - taskId: {}", attempt, maxRetries, taskId);
|
||||||
if (tokenValue == null) {
|
|
||||||
throw new RuntimeException("google token error");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 异步发送API请求
|
// 异步获取token
|
||||||
OkHttpClient client = new OkHttpClient.Builder()
|
String tokenValue = null;
|
||||||
.connectTimeout(30, TimeUnit.SECONDS) // 连接超时时间
|
try (InputStream inputStream = GenerateServiceImpl.class.getClassLoader()
|
||||||
.readTimeout(60, TimeUnit.SECONDS) // 读取超时时间
|
.getResourceAsStream("aida-461108-b4afaabebb84.json")) {
|
||||||
.writeTimeout(60, TimeUnit.SECONDS) // 写入超时时间
|
|
||||||
.retryOnConnectionFailure(true)
|
|
||||||
.build();
|
|
||||||
Request request = new Request.Builder()
|
|
||||||
.url(endpoint)
|
|
||||||
.addHeader("Authorization", "Bearer " + tokenValue)
|
|
||||||
.addHeader("Content-Type", "application/json")
|
|
||||||
.post(RequestBody.create(MediaType.parse("application/json"), jsonBody))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
try (Response response = client.newCall(request).execute()) {
|
GoogleCredentials credentials = GoogleCredentials
|
||||||
String result = response.body().string();
|
.fromStream(inputStream)
|
||||||
|
.createScoped(Collections.singletonList("https://www.googleapis.com/auth/cloud-platform"));
|
||||||
|
|
||||||
log.info("Google 响应结果:{}", result);
|
credentials.refreshIfExpired();
|
||||||
com.alibaba.fastjson.JSONObject jsonResponse = JSON.parseObject(result);
|
tokenValue = credentials.getAccessToken().getTokenValue();
|
||||||
|
}
|
||||||
String base64Data = null;
|
if (tokenValue == null) {
|
||||||
|
throw new RuntimeException("google token error");
|
||||||
//根据模型类别按照api取出结果
|
|
||||||
if (ModelConstants.NANO_BANANA.equals(useModel)) {
|
|
||||||
JSONArray candidates = jsonResponse.getJSONArray("candidates");
|
|
||||||
|
|
||||||
if (candidates != null && !candidates.isEmpty()) {
|
|
||||||
com.alibaba.fastjson.JSONObject candidate = candidates.getJSONObject(0);
|
|
||||||
com.alibaba.fastjson.JSONObject content = candidate.getJSONObject("content");
|
|
||||||
JSONArray parts = content.getJSONArray("parts");
|
|
||||||
|
|
||||||
// 遍历parts数组找到包含inlineData的对象
|
|
||||||
for (int i = 0; i < parts.size(); i++) {
|
|
||||||
com.alibaba.fastjson.JSONObject part = parts.getJSONObject(i);
|
|
||||||
if (part.containsKey("inlineData")) {
|
|
||||||
com.alibaba.fastjson.JSONObject inlineData = part.getJSONObject("inlineData");
|
|
||||||
base64Data = inlineData.getString("data");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ModelConstants.IMAGEN_MODEL.equals(useModel)) {
|
|
||||||
JSONArray predictions = jsonResponse.getJSONArray("predictions");
|
|
||||||
|
|
||||||
if (predictions != null && !predictions.isEmpty()) {
|
|
||||||
com.alibaba.fastjson.JSONObject prediction = predictions.getJSONObject(0);
|
|
||||||
base64Data = prediction.getString("bytesBase64Encoded");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base64Data != null && !base64Data.isEmpty()) {
|
// 异步发送API请求
|
||||||
String minioPath = minioUtil.base64UploadToPath("data:image/png;base64," + base64Data, userBucket, resultPath);
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
// 生成成功,更新Redis状态和URL
|
.connectionPool(new ConnectionPool(10, 5, TimeUnit.MINUTES))
|
||||||
GenerateResultVO successResultVO = new GenerateResultVO(taskId, null, minioPath, "Success");
|
.connectTimeout(45, TimeUnit.SECONDS)
|
||||||
redisUtil.addToString(key, new Gson().toJson(successResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
.readTimeout(120, TimeUnit.SECONDS)
|
||||||
|
.writeTimeout(120, TimeUnit.SECONDS)
|
||||||
|
.callTimeout(180, TimeUnit.SECONDS)
|
||||||
|
.retryOnConnectionFailure(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(endpoint)
|
||||||
|
.addHeader("Authorization", "Bearer " + tokenValue)
|
||||||
|
.addHeader("Content-Type", "application/json")
|
||||||
|
.addHeader("User-Agent", "AIDA-Backend/1.0")
|
||||||
|
.addHeader("Accept", "application/json")
|
||||||
|
.post(RequestBody.create(MediaType.parse("application/json"), jsonBody))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
long requestStartTime = System.currentTimeMillis();
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
long requestDuration = System.currentTimeMillis() - requestStartTime;
|
||||||
|
log.info("Google API 请求完成 - taskId: {}, 尝试: {}, URL: {}, 状态码: {}, 耗时: {}ms",
|
||||||
|
taskId, attempt, endpoint, response.code(), requestDuration);
|
||||||
|
|
||||||
|
String result = response.body().string();
|
||||||
|
|
||||||
|
// log.info("Google 响应结果:{}", result);
|
||||||
|
com.alibaba.fastjson.JSONObject jsonResponse = JSON.parseObject(result);
|
||||||
|
|
||||||
|
String base64Data = null;
|
||||||
|
|
||||||
|
//根据模型类别按照api取出结果
|
||||||
|
if (ModelConstants.NANO_BANANA.equals(useModel)) {
|
||||||
|
JSONArray candidates = jsonResponse.getJSONArray("candidates");
|
||||||
|
|
||||||
|
if (candidates != null && !candidates.isEmpty()) {
|
||||||
|
com.alibaba.fastjson.JSONObject candidate = candidates.getJSONObject(0);
|
||||||
|
com.alibaba.fastjson.JSONObject content = candidate.getJSONObject("content");
|
||||||
|
JSONArray parts = content.getJSONArray("parts");
|
||||||
|
|
||||||
|
// 遍历parts数组找到包含inlineData的对象
|
||||||
|
for (int i = 0; i < parts.size(); i++) {
|
||||||
|
com.alibaba.fastjson.JSONObject part = parts.getJSONObject(i);
|
||||||
|
if (part.containsKey("inlineData")) {
|
||||||
|
com.alibaba.fastjson.JSONObject inlineData = part.getJSONObject("inlineData");
|
||||||
|
base64Data = inlineData.getString("data");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ModelConstants.IMAGEN_MODEL.equals(useModel)) {
|
||||||
|
JSONArray predictions = jsonResponse.getJSONArray("predictions");
|
||||||
|
|
||||||
|
if (predictions != null && !predictions.isEmpty()) {
|
||||||
|
com.alibaba.fastjson.JSONObject prediction = predictions.getJSONObject(0);
|
||||||
|
base64Data = prediction.getString("bytesBase64Encoded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base64Data != null && !base64Data.isEmpty()) {
|
||||||
|
String minioPath = minioUtil.base64UploadToPath("data:image/png;base64," + base64Data, userBucket, resultPath);
|
||||||
|
// 生成成功,更新Redis状态和URL
|
||||||
|
GenerateResultVO successResultVO = new GenerateResultVO(taskId, null, minioPath, "Success");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(successResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
|
||||||
|
long totalDuration = System.currentTimeMillis() - startTime;
|
||||||
|
log.info("Google 图片生成成功 - taskId: {}, 总耗时: {}ms", taskId, totalDuration);
|
||||||
|
return; // 成功后立即返回
|
||||||
|
} else {
|
||||||
|
// 没有找到图像数据或数据为空,标记为失败(业务逻辑失败,不重试)
|
||||||
|
log.warn("Google generation response does not contain valid image data for taskId: {}", taskId);
|
||||||
|
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
return; // 业务逻辑失败,直接返回不重试
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// 只对 IOException 进行重试
|
||||||
|
log.warn("Google API 调用发生 IOException - taskId: {}, 尝试: {}/{}, 异常: {}",
|
||||||
|
taskId, attempt, maxRetries, e.getMessage());
|
||||||
|
|
||||||
|
if (attempt < maxRetries) {
|
||||||
|
try {
|
||||||
|
long delay = retryDelayMs * attempt; // 递增延迟
|
||||||
|
log.info("等待 {}ms 后进行第 {} 次重试 - taskId: {}", delay, attempt + 1, taskId);
|
||||||
|
Thread.sleep(delay);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
log.error("重试等待被中断 - taskId: {}", taskId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 没有找到图像数据或数据为空,标记为失败
|
// 达到最大重试次数,记录错误并更新Redis状态
|
||||||
log.warn("Google generation response does not contain valid image data for taskId: {}", taskId);
|
log.error("Google API 调用最终失败,已达到最大重试次数 {} - taskId: {}", maxRetries, taskId, e);
|
||||||
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 对于其他异常(非IOException),记录错误并直接返回,不重试
|
||||||
|
log.error("Google API 调用发生意外异常 - taskId: {}, 异常类型: {}, 异常信息: {}",
|
||||||
|
taskId, e.getClass().getSimpleName(), e.getMessage(), e);
|
||||||
|
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
return; // 非网络异常,直接返回不重试
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Google generation failed for taskId: {}", taskId, e);
|
|
||||||
// 生成失败,更新Redis状态
|
|
||||||
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
|
||||||
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果所有重试都失败了,记录最终失败日志
|
||||||
|
long totalDuration = System.currentTimeMillis() - startTime;
|
||||||
|
log.error("Google API 调用最终失败,所有重试都已用尽 - taskId: {}, 总耗时: {}ms", taskId, totalDuration);
|
||||||
|
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
}, asyncTaskExecutor);
|
}, asyncTaskExecutor);
|
||||||
|
|
||||||
// 保存生成记录到数据库
|
// 保存生成记录到数据库
|
||||||
@@ -1044,6 +1163,9 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
new Date()
|
new Date()
|
||||||
);
|
);
|
||||||
save(generate);
|
save(generate);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return taskId;
|
return taskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user