diff --git a/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java b/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java index 7fdf9cea..ab93ba3b 100644 --- a/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java +++ b/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java @@ -41,7 +41,7 @@ public enum CreditsEventsEnum { MOOD_BOARD("MoodBoard","5"), SKETCH_BOARD("SketchBoard","5"), TO_PRODUCT_IMAGE("ToProductImage","5"), - TO_PRODUCT_IMAGE_ADVANCED("ToProductImageAdvanced","10"), + TO_PRODUCT_IMAGE_ADVANCED("ToProductImageAdvanced","15"), RELIGHT("Relight","5"), RELIGHT_FLUX("RelightFlux","10"), QUESTIONNAIRE("Questionnaire","100"), @@ -50,9 +50,13 @@ public enum CreditsEventsEnum { POSE_TRANSFORMATION("PoseTransformation","10"), OTHER("Other","5"), + SCETCH_TEXT2IMG("SketchText2Image","10"), + SCETCH_IMG2IMG("SketchImg2Image","15"), WX_TEXT2IMG("WX_Text2Image", "5"), - QWEN_TEXT2IMG("QWEN_Text2Image", "5"), - DOUBAO_TEXT2IMG("Doubao_Text2Image", "5"), + QWEN_TEXT2IMG("QWEN_Text2Image", "10"), + DOUBAO_TEXT2IMG("Doubao_Text2Image", "10"), + DOUBAO_IMG2IMG_ADVANCED("Doubao_img2image_advanced", "10"), + DOUBAO_IMG2IMG_HIGH("Doubao_img2image_high", "15"), WX_ANIMATION("WX_Animation", "30"), FREEPIK_IMG2IMG("Freepik_img2img", "20"), FLUX_IMG2IMG("Flux_img2img","10"), diff --git a/src/main/java/com/ai/da/common/utils/MinioUtil.java b/src/main/java/com/ai/da/common/utils/MinioUtil.java index a2946fb1..906ebc7e 100644 --- a/src/main/java/com/ai/da/common/utils/MinioUtil.java +++ b/src/main/java/com/ai/da/common/utils/MinioUtil.java @@ -20,6 +20,8 @@ import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; +import java.awt.Graphics2D; +import java.awt.RenderingHints; import java.io.*; import java.net.URL; import java.security.InvalidKeyException; @@ -666,6 +668,168 @@ public class MinioUtil { } } + /** + * 获取压缩后的图片Base64编码 + * @param path 图片的minio路径 + * @param targetWidth 目标宽度 + * @param targetHeight 目标高度 + * @return 压缩后的图片Base64编码 + * @throws IOException + */ + public String getCompressedImageAsBase64(String path, int targetWidth, int targetHeight) throws IOException { + int index = path.indexOf("/"); + String bucketName = path.substring(0, index); + String fileName = path.substring(index + 1); + + // 检查桶是否存在 + boolean found = doesObjectExist(bucketName, fileName); + if (!found) { + throw new IOException("Bucket " + bucketName + " does not exist"); + } + + try (InputStream stream = minioClient.getObject( + GetObjectArgs.builder() + .bucket(bucketName) + .object(fileName) + .build())) { + + // 读取原始图片 + BufferedImage originalImage = ImageIO.read(stream); + if (originalImage == null) { + throw new IOException("无法读取图片: " + path); + } + + // 计算压缩比例,保持宽高比 + int originalWidth = originalImage.getWidth(); + int originalHeight = originalImage.getHeight(); + + double scaleX = (double) targetWidth / originalWidth; + double scaleY = (double) targetHeight / originalHeight; + double scale = Math.min(scaleX, scaleY); // 选择较小的缩放比例以保持宽高比 + + int newWidth = (int) (originalWidth * scale); + int newHeight = (int) (originalHeight * scale); + + // 创建压缩后的图片 + BufferedImage compressedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = compressedImage.createGraphics(); + + // 设置高质量渲染 + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // 绘制压缩后的图片 + g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null); + g2d.dispose(); + + // 转换为Base64 + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(compressedImage, "JPEG", baos); // 使用JPEG格式以减小文件大小 + byte[] imageBytes = baos.toByteArray(); + + log.info("图片压缩完成: {} -> {}x{} (原始: {}x{})", path, newWidth, newHeight, originalWidth, originalHeight); + return Base64.getEncoder().encodeToString(imageBytes); + + } catch (ServerException e) { + throw new RuntimeException(e); + } catch (InsufficientDataException e) { + throw new RuntimeException(e); + } catch (ErrorResponseException e) { + throw new RuntimeException(e); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } catch (InvalidKeyException e) { + throw new RuntimeException(e); + } catch (InvalidResponseException e) { + throw new RuntimeException(e); + } catch (XmlParserException e) { + throw new RuntimeException(e); + } catch (InternalException e) { + throw new RuntimeException(e); + } + } + + /** + * 压缩base64格式的图片 + * @param base64Image 包含前缀的base64图片字符串 (如: "data:image/png;base64,...") + * @param targetWidth 目标宽度 + * @param targetHeight 目标高度 + * @return 压缩后的base64图片字符串(保持原有前缀格式) + */ + public String compressBase64Image(String base64Image, int targetWidth, int targetHeight) { + if (base64Image == null || base64Image.isEmpty()) { + return base64Image; + } + + try { + // 解析base64字符串 + String[] parts = base64Image.split(","); + if (parts.length != 2) { + log.warn("无效的base64图片格式: {}", base64Image.substring(0, Math.min(50, base64Image.length()))); + return base64Image; + } + + String prefix = parts[0] + ","; // 保留前缀,如 "data:image/png;base64," + String base64Data = parts[1]; + + // 解码base64数据 + byte[] imageBytes = Base64.getDecoder().decode(base64Data); + + // 读取图片 + BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(imageBytes)); + if (originalImage == null) { + log.warn("无法读取base64图片数据"); + return base64Image; + } + + // 计算压缩比例,保持宽高比 + int originalWidth = originalImage.getWidth(); + int originalHeight = originalImage.getHeight(); + + double scaleX = (double) targetWidth / originalWidth; + double scaleY = (double) targetHeight / originalHeight; + double scale = Math.min(scaleX, scaleY); // 选择较小的缩放比例以保持宽高比 + + int newWidth = (int) (originalWidth * scale); + int newHeight = (int) (originalHeight * scale); + + // 如果图片已经比目标尺寸小,则不进行压缩 + if (scale >= 1.0) { + log.info("图片尺寸 {}x{} 已小于目标尺寸 {}x{},无需压缩", originalWidth, originalHeight, targetWidth, targetHeight); + return base64Image; + } + + // 创建压缩后的图片 + BufferedImage compressedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = compressedImage.createGraphics(); + + // 设置高质量渲染 + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // 绘制压缩后的图片 + g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null); + g2d.dispose(); + + // 转换为Base64 + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(compressedImage, "PNG", baos); // 保持PNG格式以支持透明度 + byte[] compressedBytes = baos.toByteArray(); + String compressedBase64 = Base64.getEncoder().encodeToString(compressedBytes); + + log.info("Base64图片压缩完成: {}x{} -> {}x{} (压缩比: {:.2f})", + originalWidth, originalHeight, newWidth, newHeight, scale); + + return prefix + compressedBase64; + + } catch (Exception e) { + log.error("压缩base64图片失败", e); + return base64Image; // 出错时返回原图 + } + } + public void uploadToMinio(byte[] data, String bucket, String objectName, String contentType) /*throws Exception*/ { try { minioClient.putObject(PutObjectArgs.builder() diff --git a/src/main/java/com/ai/da/mapper/primary/entity/CollectionElement.java b/src/main/java/com/ai/da/mapper/primary/entity/CollectionElement.java index 40ef64b8..315d0937 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/CollectionElement.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/CollectionElement.java @@ -111,4 +111,16 @@ public class CollectionElement implements Serializable { this.createDate = createDate; this.projectId = projectId; } + public CollectionElement(Long accountId, String level1Type, String level2Type, String level3Type,String name, String url, Byte hasPin, String md5, Date createDate, Long projectId) { + this.accountId = accountId; + this.level1Type = level1Type; + this.level2Type = level2Type; + this.level3Type = level3Type; + this.name = name; + this.url = url; + this.hasPin = hasPin; + this.md5 = md5; + this.createDate = createDate; + this.projectId = projectId; + } } diff --git a/src/main/java/com/ai/da/model/vo/MagicToolResultVO.java b/src/main/java/com/ai/da/model/vo/MagicToolResultVO.java index 6cc4392f..b1d19870 100644 --- a/src/main/java/com/ai/da/model/vo/MagicToolResultVO.java +++ b/src/main/java/com/ai/da/model/vo/MagicToolResultVO.java @@ -40,6 +40,8 @@ public class MagicToolResultVO { private String direction; + private String errorMessage; + @ApiModelProperty("用户输入的提示词") private String prompt; @@ -47,4 +49,9 @@ public class MagicToolResultVO { this.taskId = taskId; this.status = status; } + public MagicToolResultVO(String taskId, String status, String errorMessage) { + this.errorMessage = errorMessage; + this.taskId = taskId; + this.status = status; + } } diff --git a/src/main/java/com/ai/da/service/impl/CollectionSortServiceImpl.java b/src/main/java/com/ai/da/service/impl/CollectionSortServiceImpl.java index fe87c23f..fb54ad60 100644 --- a/src/main/java/com/ai/da/service/impl/CollectionSortServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/CollectionSortServiceImpl.java @@ -112,7 +112,13 @@ public class CollectionSortServiceImpl extends ServiceImpl result = baseMapper.selectMaps(qw).get(0); - return (Long) result.get("maxSort"); + Object maxSortObj = result.get("maxSort"); + if (maxSortObj instanceof Long) { + return ((Long) maxSortObj).intValue(); + } else if (maxSortObj instanceof Integer) { + return (Integer) maxSortObj; + } + return (Integer) result.get("maxSort"); } @Override diff --git a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java index 51282147..1ac99054 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -650,7 +650,7 @@ public class GenerateServiceImpl extends ServiceImpl i // ============== 以下是辅助方法 ============== private PrepareForGenerateVO handleImagenModelGeneration(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) { // 校验积分是否足够 -// validateCredits(CreditsEventsEnum.WX_TEXT2IMG); + validateCredits(CreditsEventsEnum.SCETCH_TEXT2IMG); // 创建生成任务 String taskId = null; try { @@ -658,13 +658,13 @@ public class GenerateServiceImpl extends ServiceImpl i } catch (Exception e) { e.printStackTrace(); } -// processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.WX_TEXT2IMG); + processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.SCETCH_TEXT2IMG); return new PrepareForGenerateVO(Collections.singletonList(taskId), 200); } private PrepareForGenerateVO handleNanoBananaModelGeneration(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) { // 校验积分是否足够 -// validateCredits(CreditsEventsEnum.WX_TEXT2IMG); + validateCredits(CreditsEventsEnum.SCETCH_IMG2IMG); // 创建生成任务 String taskId = null; try { @@ -672,7 +672,7 @@ public class GenerateServiceImpl extends ServiceImpl i } catch (Exception e) { e.printStackTrace(); } -// processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.WX_TEXT2IMG); + processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.SCETCH_IMG2IMG); return new PrepareForGenerateVO(Collections.singletonList(taskId), 200); } @@ -695,11 +695,15 @@ public class GenerateServiceImpl extends ServiceImpl i String finalImagePath = null; try { finalImagePath = addWhiteBackground(imagePath); - //去掉"data:image/png;base64," - finalImagePath = finalImagePath.replace("data:image/png;base64,", ""); - // 如果白色背景处理失败或不需要,直接获取原图的base64编码 - if (StringUtil.isNullOrEmpty(finalImagePath)) { - finalImagePath = minioUtil.getImageAsBase64(imagePath); + // 如果白色背景处理成功,对base64图片进行压缩以降低模型成本 + if (!StringUtil.isNullOrEmpty(finalImagePath)) { + // 压缩到512x512分辨率 + finalImagePath = minioUtil.compressBase64Image(finalImagePath, 512, 512); + //去掉"data:image/png;base64," + finalImagePath = finalImagePath.replace("data:image/png;base64,", ""); + } else { + // 如果白色背景处理失败或不需要,直接获取原图的压缩base64编码 + finalImagePath = minioUtil.getCompressedImageAsBase64(imagePath, 512, 512); } } catch (IOException e) { log.error("Error getting image as base64 taskId: {} ", taskId, e); @@ -741,7 +745,7 @@ public class GenerateServiceImpl extends ServiceImpl i JSONObject generationConfig = new JSONObject(); // generationConfig.set("temperature", 1); generationConfig.set("maxOutputTokens", 8192); - generationConfig.set("responseModalities", Arrays.asList("TEXT", "IMAGE")); + generationConfig.set("responseModalities", Arrays.asList("IMAGE")); // generationConfig.set("topP", 0.95); JSONObject imageConfig = new JSONObject(); imageConfig.set("aspectRatio", "9:16"); @@ -815,7 +819,7 @@ public class GenerateServiceImpl extends ServiceImpl i } String result = response.body().string(); -// log.info("Google 响应结果:{}", result); + log.info("Google 响应结果:{}", result); com.alibaba.fastjson.JSONObject jsonResponse = JSON.parseObject(result); String base64Data = null; @@ -826,18 +830,36 @@ public class GenerateServiceImpl extends ServiceImpl i 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"); + String finishReason = candidate.getString("finishReason"); + if (finishReason != null && finishReason.equals("STOP")) { + success = true; + 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; + // 遍历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; + } + } + } else if (finishReason != null && finishReason.equals("IMAGE_SAFETY")) { + String finishMessage = candidate.getString("finishMessage"); + if (finishMessage != null && finishMessage.contains("Try rephrasing the prompt or ")) { + finishMessage = "Try rephrasing the prompt or modifying the model image. If you think this was an error, send feedback."; + LambdaQueryWrapper select = new LambdaQueryWrapper().eq(Account::getId, userId).select(Account::getLanguage); + Account account = accountService.getOne(select); + if ("CHINESE_SIMPLIFIED".equals(account.getLanguage())) { + finishMessage = "请尝试重新表述提示词,或修改模特图。若您认为这是误判,可提交反馈。"; + } + GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, finishMessage, "Fail"); + redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); + return; } } + } } @@ -969,7 +991,7 @@ public class GenerateServiceImpl extends ServiceImpl i JSONObject generationConfig = new JSONObject(); // generationConfig.set("temperature", 1); generationConfig.set("maxOutputTokens", 8192); - generationConfig.set("responseModalities", Arrays.asList("TEXT", "IMAGE")); + generationConfig.set("responseModalities", Arrays.asList("IMAGE")); JSONObject imageConfig = new JSONObject(); imageConfig.set("aspectRatio", "9:16"); generationConfig.set("imageConfig", imageConfig); @@ -1075,17 +1097,34 @@ public class GenerateServiceImpl extends ServiceImpl i 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"); + String finishReason = candidate.getString("finishReason"); + if (finishReason != null && finishReason.equals("STOP")) { + 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; + // 遍历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 (finishReason != null && finishReason.equals("IMAGE_SAFETY")) { + String finishMessage = candidate.getString("finishMessage"); + if (finishMessage != null && finishMessage.contains("Try rephrasing the prompt or ")) { + finishMessage = "Try rephrasing the prompt or replacing the image. If you think this was an error, send feedback."; + LambdaQueryWrapper select = new LambdaQueryWrapper().eq(Account::getId, userId).select(Account::getLanguage); + Account account = accountService.getOne(select); + if ("CHINESE_SIMPLIFIED".equals(account.getLanguage())) { + finishMessage = "请尝试重新表述提示词,或更换图片。若您认为这是误判,可提交反馈。"; + } + GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, finishMessage, "Fail"); + redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); + } + return; } + } } else if (ModelConstants.IMAGEN_MODEL.equals(useModel)) { JSONArray predictions = jsonResponse.getJSONArray("predictions"); @@ -1093,6 +1132,17 @@ public class GenerateServiceImpl extends ServiceImpl i if (predictions != null && !predictions.isEmpty()) { com.alibaba.fastjson.JSONObject prediction = predictions.getJSONObject(0); base64Data = prediction.getString("bytesBase64Encoded"); + String raiFilteredReason = prediction.getString("raiFilteredReason"); + if (raiFilteredReason != null && raiFilteredReason.contains("Try rephrasing the prompt")) { + raiFilteredReason = "Input data may contain inappropriate content."; + LambdaQueryWrapper select = new LambdaQueryWrapper().eq(Account::getId, userId).select(Account::getLanguage); + Account account = accountService.getOne(select); + if ("CHINESE_SIMPLIFIED".equals(account.getLanguage())) { + raiFilteredReason = "输入数据可能包含不当内容。"; + } + GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, raiFilteredReason, "Fail"); + redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); + } } } @@ -1291,20 +1341,24 @@ public class GenerateServiceImpl extends ServiceImpl i private PrepareForGenerateVO handleQwenModelGeneration(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) { - //TODO:校验积分是否足够 validateCredits(CreditsEventsEnum.QWEN_TEXT2IMG); String taskId = createQwenAsyncTask(generateDTO, useModel, prompt); - // TODO:处理积分扣除 processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.QWEN_TEXT2IMG); return new PrepareForGenerateVO(Collections.singletonList(taskId), 200); } private PrepareForGenerateVO handleDouBaoModelGeneration(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) { - //TODO:校验积分是否足够 - validateCredits(CreditsEventsEnum.DOUBAO_TEXT2IMG); + CreditsEventsEnum creditsEvents = null; + if (useModel.equals(ModelConstants.PRINTBOARD_ADVANCED_I2I)){ + creditsEvents = CreditsEventsEnum.DOUBAO_IMG2IMG_ADVANCED; + }else if (useModel.equals(ModelConstants.PRINTBOARD_HIGH_I2I)){ + creditsEvents = CreditsEventsEnum.DOUBAO_IMG2IMG_HIGH; + }else if (useModel.equals(ModelConstants.PRINTBOARD_HIGH_T2I)||useModel.equals(ModelConstants.MOODBOARD_ADVANCED)){ + creditsEvents = CreditsEventsEnum.DOUBAO_TEXT2IMG; + } + validateCredits(creditsEvents); String taskId = createDouBaoAsyncTask(generateDTO, useModel, prompt); - // TODO:处理积分扣除 - processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.DOUBAO_TEXT2IMG); + processCreditDeduction(generateDTO.getUserId(), taskId, creditsEvents); return new PrepareForGenerateVO(Collections.singletonList(taskId), 200); } @@ -1344,20 +1398,20 @@ public class GenerateServiceImpl extends ServiceImpl i // 解析JSON格式的异常信息 JSONObject jsonObj = JSONUtil.parseObj(exceptionMessage); exceptionMessage = jsonObj.getStr("message"); - if ("Input data may contain inappropriate content.".equals(exceptionMessage)){ + if ("Input data may contain inappropriate content.".equals(exceptionMessage)) { LambdaQueryWrapper select = new LambdaQueryWrapper().eq(Account::getId, userId).select(Account::getLanguage); Account account = accountService.getOne(select); - if ("CHINESE_SIMPLIFIED".equals(account.getLanguage())){ + if ("CHINESE_SIMPLIFIED".equals(account.getLanguage())) { exceptionMessage = "输入数据可能包含不当内容。"; } } - throw new RuntimeException(exceptionMessage); + throw new BusinessException(exceptionMessage, ResultEnum.PROMPT.getCode()); } catch (Exception parseException) { // 如果解析失败,返回原始消息 - throw new RuntimeException(exceptionMessage); + throw new BusinessException(exceptionMessage, ResultEnum.PROMPT.getCode()); } } - throw new RuntimeException(e.getMessage()); + throw new BusinessException(e.getMessage(), ResultEnum.PROMPT.getCode()); } String taskId = result.getOutput().getTaskId(); log.info("qwen text2image 请求生成:{}, taskId:{}", JsonUtils.toJson(result), taskId); @@ -2320,7 +2374,7 @@ public class GenerateServiceImpl extends ServiceImpl i ? handleLibrarySave(accountId, originalId, minioPath, category, gender, isOverride, generateModifyDTO.getType()) : originalIdSource.equals("Generate") ? handleGenerateSave(originalId, pathInfo.generateId, minioPath, category, isOverride) - : handleUploadSave(accountId, originalId, minioPath, category, isOverride, generateModifyDTO.getType()); + : handleUploadSave(accountId, originalId, minioPath, category, generateModifyDTO.getGender(), isOverride, generateModifyDTO.getType()); } private static class PathInfo { @@ -2388,7 +2442,7 @@ public class GenerateServiceImpl extends ServiceImpl i } private GenerateResultVO handleUploadSave(Long accountId, Long originalId, String minioPath, - String category, boolean isOverride, String level1Type) { + String category, String gender, boolean isOverride, String level1Type) { CollectionElement collectionElement; String md5 = MD5Utils.encryptFile(minioUtil.getPreSignedUrl(minioPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME), false); if (isOverride) { @@ -2401,7 +2455,11 @@ public class GenerateServiceImpl extends ServiceImpl i } else { CollectionElement originalElement = collectionElementMapper.selectById(originalId); String name = minioPath.substring(minioPath.lastIndexOf("/") + 1, minioPath.lastIndexOf(".")); - collectionElement = new CollectionElement(accountId, level1Type, category, name, minioPath, (byte) 0, md5, new Date(), originalElement.getProjectId()); + if ("Sketchboard".equals(level1Type)) { + collectionElement = new CollectionElement(accountId, level1Type, category, gender, name, minioPath, (byte) 0, md5, new Date(), originalElement.getProjectId()); + } else { + collectionElement = new CollectionElement(accountId, level1Type, category, name, minioPath, (byte) 0, md5, new Date(), originalElement.getProjectId()); + } collectionElementMapper.insert(collectionElement); } return buildResultVO(collectionElement.getId(), minioPath, category); @@ -3262,6 +3320,12 @@ public class GenerateServiceImpl extends ServiceImpl i generateResultVO.setCategory(generateRecord.getLevel2Type()); } return generateResultVO; + } else if ("Fail".equals(cachedResult.getStatus())) { + // 获取失败原因 + String errorMessage = cachedResult.getUrl(); + if (errorMessage != null) { + throw new BusinessException(errorMessage, ResultEnum.PROMPT.getCode()); + } } else { throw new BusinessException("Unknown generate task"); } diff --git a/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java b/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java index 82672a12..d44afd67 100644 --- a/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java @@ -456,7 +456,7 @@ public class UserLikeGroupServiceImpl extends ServiceImpl().lambda().eq(CollectionSort::getRelationId, toProductImageResult.getId())); results.add(new MagicToolResultVO(taskId, "Fail")); - } else if ("Pending".equals(cachedResult.getStatus())||"Fail".equals(cachedResult.getStatus())) { + } else if ("Pending".equals(cachedResult.getStatus()) || "Fail".equals(cachedResult.getStatus())) { // 如果结果为失败或待处理状态,更新状态并返回对应结果 toProductImageResult.setStatus(cachedResult.getStatus()); toProductImageResultMapper.updateById(toProductImageResult); - if (cachedResult.getStatus().equals("Fail")){ + if (cachedResult.getStatus().equals("Fail")) { collectionSortMapper.delete(new QueryWrapper().lambda().eq(CollectionSort::getRelationId, toProductImageResult.getId())); } - results.add(new MagicToolResultVO(taskId, cachedResult.getStatus())); + String errorMessage = cachedResult.getUrl(); + if (errorMessage != null) { + results.add(new MagicToolResultVO(taskId, cachedResult.getStatus(), errorMessage)); + } else { + results.add(new MagicToolResultVO(taskId, cachedResult.getStatus())); + } } else { // 如果结果成功,处理flux结果并构建返回对象 results.add(processNanoBananaResult(cachedResult.getUrl(), toProductImageResult, taskId, toProductImageRecord.getPrompt())); @@ -1030,10 +1035,10 @@ public class UserLikeGroupServiceImpl extends ServiceImpl list = new ArrayList<>(); for (CollectionSort collectionSort : userLikeSortList) { @@ -2218,7 +2224,7 @@ public class UserLikeGroupServiceImpl extends ServiceImpl printBoards = moduleSaveDTO.getPrintBoard(); QueryWrapper qw = new QueryWrapper<>(); qw.lambda().eq(CollectionElement::getProjectId, projectId); @@ -2680,7 +2686,7 @@ public class UserLikeGroupServiceImpl extends ServiceImpl colorBoards = moduleSaveDTO.getColorBoard(); QueryWrapper qw = new QueryWrapper<>(); qw.lambda().eq(CollectionElement::getProjectId, projectId); @@ -2714,7 +2720,7 @@ public class UserLikeGroupServiceImpl extends ServiceImpl qw = new QueryWrapper<>(); qw.lambda().eq(CollectionElement::getProjectId, projectId);