Commit 99d477ac0a4196eaa37cf5a6f6cfe12a862359be
1 parent
0311c77e
【增加】图片绘画增加 绘画失败状态,并保存绘画错误信息,同时可以将错误信息返回给前端
Showing
4 changed files
with
73 additions
and
9 deletions
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
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiImageServiceImpl.java
| 1 | 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 | 4 | import cn.iocoder.yudao.framework.ai.image.ImageGeneration; |
| 5 | 5 | import cn.iocoder.yudao.framework.ai.image.ImagePrompt; |
| 6 | 6 | import cn.iocoder.yudao.framework.ai.image.ImageResponse; |
| 7 | 7 | import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageClient; |
| 8 | 8 | import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageModelEnum; |
| 9 | 9 | import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageOptions; |
| 10 | +import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageStyleEnum; | |
| 10 | 11 | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; |
| 11 | 12 | import cn.iocoder.yudao.module.ai.controller.Utf8SseEmitter; |
| 12 | 13 | import cn.iocoder.yudao.module.ai.dal.dataobject.AiImageDO; |
| 14 | +import cn.iocoder.yudao.module.ai.enums.AiChatDrawingStatusEnum; | |
| 13 | 15 | import cn.iocoder.yudao.module.ai.mapper.AiImageMapper; |
| 14 | 16 | import cn.iocoder.yudao.module.ai.service.AiImageService; |
| 15 | 17 | import cn.iocoder.yudao.module.ai.vo.AiImageDallDrawingReq; |
| ... | ... | @@ -39,25 +41,43 @@ public class AiImageServiceImpl implements AiImageService { |
| 39 | 41 | public void dallDrawing(AiImageDallDrawingReq req, Utf8SseEmitter sseEmitter) { |
| 40 | 42 | // 获取 model |
| 41 | 43 | OpenAiImageModelEnum openAiImageModelEnum = OpenAiImageModelEnum.valueOfModel(req.getModal()); |
| 44 | + OpenAiImageStyleEnum openAiImageStyleEnum = OpenAiImageStyleEnum.valueOfStyle(req.getStyle()); | |
| 42 | 45 | // |
| 43 | 46 | OpenAiImageOptions openAiImageOptions = new OpenAiImageOptions(); |
| 44 | 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 | 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 | 70 | } catch (IOException e) { |
| 51 | 71 | throw new RuntimeException(e); |
| 52 | 72 | } finally { |
| 53 | 73 | // 发送 complete |
| 54 | 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 | 81 | AiImageDO aiImageDO = new AiImageDO(); |
| 62 | 82 | aiImageDO.setId(null); |
| 63 | 83 | aiImageDO.setPrompt(req.getPrompt()); |
| ... | ... | @@ -65,6 +85,8 @@ public class AiImageServiceImpl implements AiImageService { |
| 65 | 85 | aiImageDO.setModal(req.getModal()); |
| 66 | 86 | aiImageDO.setUserId(loginUserId); |
| 67 | 87 | aiImageDO.setDrawingImageUrl(imageUrl); |
| 88 | + aiImageDO.setDrawingStatus(drawingStatusEnum.getStatus()); | |
| 89 | + aiImageDO.setDrawingError(drawingError); | |
| 68 | 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 | 24 | @NotNull(message = "模型不能为空") |
| 25 | 25 | private String modal; |
| 26 | 26 | |
| 27 | + @Schema(description = "图像生成的风格。可为vivid(生动)或natural(自然)") | |
| 28 | + @NotNull(message = "图像生成的风格,不能为空!") | |
| 29 | + private String style; | |
| 30 | + | |
| 27 | 31 | @Schema(description = "生成图像的尺寸大小。对于dall-e-2模型,尺寸可为256x256, 512x512, 或 1024x1024。对于dall-e-3模型,尺寸可为1024x1024, 1792x1024, 或 1024x1792。") |
| 28 | 32 | @NotNull(message = "size不能为空!") |
| 29 | 33 | private String size; | ... | ... |