Commit 99d477ac0a4196eaa37cf5a6f6cfe12a862359be

Authored by cherishsince
1 parent 0311c77e

【增加】图片绘画增加 绘画失败状态,并保存绘画错误信息,同时可以将错误信息返回给前端

yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/AiChatDrawingStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.enums;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Getter;
  5 +
  6 +/**
  7 + * ai绘画状态
  8 + *
  9 + * @author fansili
  10 + * @time 2024/4/28 17:05
  11 + * @since 1.0
  12 + */
  13 +@AllArgsConstructor
  14 +@Getter
  15 +public enum AiChatDrawingStatusEnum {
  16 +
  17 + COMPLETE("complete", "完成"),
  18 + FAIL("fail", "失败"),
  19 +
  20 + ;
  21 +
  22 + private String status;
  23 +
  24 + private String name;
  25 +
  26 +
  27 + public static AiChatDrawingStatusEnum valueOfStatus(String status) {
  28 + for (AiChatDrawingStatusEnum itemEnum : AiChatDrawingStatusEnum.values()) {
  29 + if (itemEnum.getStatus().equals(status)) {
  30 + return itemEnum;
  31 + }
  32 + }
  33 + throw new IllegalArgumentException("Invalid MessageType value: " + status);
  34 + }
  35 +}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/AiImageDO.java
@@ -41,5 +41,8 @@ public class AiImageDO extends BaseDO { @@ -41,5 +41,8 @@ public class AiImageDO extends BaseDO {
41 @Schema(description = "绘画图片地址") 41 @Schema(description = "绘画图片地址")
42 private String drawingImageUrl; 42 private String drawingImageUrl;
43 43
  44 + @Schema(description = "绘画错误信息")
  45 + private String drawingError;
  46 +
44 } 47 }
45 48
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiImageServiceImpl.java
1 package cn.iocoder.yudao.module.ai.service.impl; 1 package cn.iocoder.yudao.module.ai.service.impl;
2 2
3 -import cn.iocoder.yudao.framework.ai.image.Image; 3 +import cn.iocoder.yudao.framework.ai.exception.AiException;
4 import cn.iocoder.yudao.framework.ai.image.ImageGeneration; 4 import cn.iocoder.yudao.framework.ai.image.ImageGeneration;
5 import cn.iocoder.yudao.framework.ai.image.ImagePrompt; 5 import cn.iocoder.yudao.framework.ai.image.ImagePrompt;
6 import cn.iocoder.yudao.framework.ai.image.ImageResponse; 6 import cn.iocoder.yudao.framework.ai.image.ImageResponse;
7 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageClient; 7 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageClient;
8 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageModelEnum; 8 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageModelEnum;
9 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageOptions; 9 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageOptions;
  10 +import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageStyleEnum;
10 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; 11 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
11 import cn.iocoder.yudao.module.ai.controller.Utf8SseEmitter; 12 import cn.iocoder.yudao.module.ai.controller.Utf8SseEmitter;
12 import cn.iocoder.yudao.module.ai.dal.dataobject.AiImageDO; 13 import cn.iocoder.yudao.module.ai.dal.dataobject.AiImageDO;
  14 +import cn.iocoder.yudao.module.ai.enums.AiChatDrawingStatusEnum;
13 import cn.iocoder.yudao.module.ai.mapper.AiImageMapper; 15 import cn.iocoder.yudao.module.ai.mapper.AiImageMapper;
14 import cn.iocoder.yudao.module.ai.service.AiImageService; 16 import cn.iocoder.yudao.module.ai.service.AiImageService;
15 import cn.iocoder.yudao.module.ai.vo.AiImageDallDrawingReq; 17 import cn.iocoder.yudao.module.ai.vo.AiImageDallDrawingReq;
@@ -39,25 +41,43 @@ public class AiImageServiceImpl implements AiImageService { @@ -39,25 +41,43 @@ public class AiImageServiceImpl implements AiImageService {
39 public void dallDrawing(AiImageDallDrawingReq req, Utf8SseEmitter sseEmitter) { 41 public void dallDrawing(AiImageDallDrawingReq req, Utf8SseEmitter sseEmitter) {
40 // 获取 model 42 // 获取 model
41 OpenAiImageModelEnum openAiImageModelEnum = OpenAiImageModelEnum.valueOfModel(req.getModal()); 43 OpenAiImageModelEnum openAiImageModelEnum = OpenAiImageModelEnum.valueOfModel(req.getModal());
  44 + OpenAiImageStyleEnum openAiImageStyleEnum = OpenAiImageStyleEnum.valueOfStyle(req.getStyle());
42 // 45 //
43 OpenAiImageOptions openAiImageOptions = new OpenAiImageOptions(); 46 OpenAiImageOptions openAiImageOptions = new OpenAiImageOptions();
44 openAiImageOptions.setModel(openAiImageModelEnum); 47 openAiImageOptions.setModel(openAiImageModelEnum);
45 - ImageResponse imageResponse = openAiImageClient.call(new ImagePrompt(req.getPrompt(), openAiImageOptions));  
46 - // 发送  
47 - ImageGeneration imageGeneration = imageResponse.getResult(); 48 + openAiImageOptions.setStyle(openAiImageStyleEnum);
  49 + openAiImageOptions.setSize(req.getSize());
  50 + ImageResponse imageResponse;
48 try { 51 try {
49 - sseEmitter.send(imageGeneration, MediaType.APPLICATION_JSON); 52 + imageResponse = openAiImageClient.call(new ImagePrompt(req.getPrompt(), openAiImageOptions));
  53 + // 发送
  54 + ImageGeneration imageGeneration = imageResponse.getResult();
  55 + // 发送信息
  56 + sendSseEmitter(sseEmitter, imageGeneration);
  57 + // 保存数据库
  58 + doSave(req, imageGeneration.getOutput().getUrl(), AiChatDrawingStatusEnum.COMPLETE, null);
  59 + } catch (AiException aiException) {
  60 + // 保存数据库
  61 + doSave(req, null, AiChatDrawingStatusEnum.FAIL, aiException.getMessage());
  62 + // 发送错误信息
  63 + sendSseEmitter(sseEmitter, aiException.getMessage());
  64 + }
  65 + }
  66 +
  67 + private static void sendSseEmitter(Utf8SseEmitter sseEmitter, Object object) {
  68 + try {
  69 + sseEmitter.send(object, MediaType.APPLICATION_JSON);
50 } catch (IOException e) { 70 } catch (IOException e) {
51 throw new RuntimeException(e); 71 throw new RuntimeException(e);
52 } finally { 72 } finally {
53 // 发送 complete 73 // 发送 complete
54 sseEmitter.complete(); 74 sseEmitter.complete();
55 } 75 }
56 - Long loginUserId = SecurityFrameworkUtils.getLoginUserId();  
57 - // 76 + }
  77 +
  78 + private void doSave(AiImageDallDrawingReq req, String imageUrl, AiChatDrawingStatusEnum drawingStatusEnum, String drawingError) {
58 // 保存数据库 79 // 保存数据库
59 - Image output = imageGeneration.getOutput();  
60 - String imageUrl = output.getUrl(); 80 + Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
61 AiImageDO aiImageDO = new AiImageDO(); 81 AiImageDO aiImageDO = new AiImageDO();
62 aiImageDO.setId(null); 82 aiImageDO.setId(null);
63 aiImageDO.setPrompt(req.getPrompt()); 83 aiImageDO.setPrompt(req.getPrompt());
@@ -65,6 +85,8 @@ public class AiImageServiceImpl implements AiImageService { @@ -65,6 +85,8 @@ public class AiImageServiceImpl implements AiImageService {
65 aiImageDO.setModal(req.getModal()); 85 aiImageDO.setModal(req.getModal());
66 aiImageDO.setUserId(loginUserId); 86 aiImageDO.setUserId(loginUserId);
67 aiImageDO.setDrawingImageUrl(imageUrl); 87 aiImageDO.setDrawingImageUrl(imageUrl);
  88 + aiImageDO.setDrawingStatus(drawingStatusEnum.getStatus());
  89 + aiImageDO.setDrawingError(drawingError);
68 aiImageMapper.insert(aiImageDO); 90 aiImageMapper.insert(aiImageDO);
69 } 91 }
70 } 92 }
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/vo/AiImageDallDrawingReq.java
@@ -24,6 +24,10 @@ public class AiImageDallDrawingReq { @@ -24,6 +24,10 @@ public class AiImageDallDrawingReq {
24 @NotNull(message = "模型不能为空") 24 @NotNull(message = "模型不能为空")
25 private String modal; 25 private String modal;
26 26
  27 + @Schema(description = "图像生成的风格。可为vivid(生动)或natural(自然)")
  28 + @NotNull(message = "图像生成的风格,不能为空!")
  29 + private String style;
  30 +
27 @Schema(description = "生成图像的尺寸大小。对于dall-e-2模型,尺寸可为256x256, 512x512, 或 1024x1024。对于dall-e-3模型,尺寸可为1024x1024, 1792x1024, 或 1024x1792。") 31 @Schema(description = "生成图像的尺寸大小。对于dall-e-2模型,尺寸可为256x256, 512x512, 或 1024x1024。对于dall-e-3模型,尺寸可为1024x1024, 1792x1024, 或 1024x1792。")
28 @NotNull(message = "size不能为空!") 32 @NotNull(message = "size不能为空!")
29 private String size; 33 private String size;