Commit a1f738dd81dac8149a0004cc1003c76bb3236297
1 parent
782f1085
【增加】增加 midjourney 提交任务
Showing
6 changed files
with
127 additions
and
69 deletions
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/vo/MidjourneySubmitCodeEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.ai.client.vo; | ||
| 2 | + | ||
| 3 | +import com.google.common.collect.Lists; | ||
| 4 | +import lombok.AllArgsConstructor; | ||
| 5 | +import lombok.Getter; | ||
| 6 | + | ||
| 7 | +import java.util.List; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * Midjourney 提交任务 code 枚举 | ||
| 11 | + * | ||
| 12 | + * @author fansili | ||
| 13 | + * @time 2024/5/30 14:33 | ||
| 14 | + * @since 1.0 | ||
| 15 | + */ | ||
| 16 | +@Getter | ||
| 17 | +@AllArgsConstructor | ||
| 18 | +public enum MidjourneySubmitCodeEnum { | ||
| 19 | + | ||
| 20 | + // 状态码: 1(提交成功), 21(已存在), 22(排队中), other(错误) | ||
| 21 | + SUBMIT_SUCCESS("1", "提交成功"), | ||
| 22 | + ALREADY_EXISTS("1", "已存在"), | ||
| 23 | + QUEUING("22", "排队中"), | ||
| 24 | + | ||
| 25 | + ; | ||
| 26 | + | ||
| 27 | + public static final List<String> SUCCESS_CODES = Lists.newArrayList( | ||
| 28 | + SUBMIT_SUCCESS.code, | ||
| 29 | + ALREADY_EXISTS.code, | ||
| 30 | + QUEUING.code | ||
| 31 | + ); | ||
| 32 | + | ||
| 33 | + private String code; | ||
| 34 | + private String name; | ||
| 35 | + | ||
| 36 | +} |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/vo/MidjourneySubmitRespVO.java
| @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.ai.client.vo; | @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.ai.client.vo; | ||
| 3 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | import lombok.Data; | 4 | import lombok.Data; |
| 5 | 5 | ||
| 6 | +import java.util.Map; | ||
| 7 | + | ||
| 6 | /** | 8 | /** |
| 7 | * Midjourney:Imagine 请求 | 9 | * Midjourney:Imagine 请求 |
| 8 | * | 10 | * |
| @@ -20,7 +22,7 @@ public class MidjourneySubmitRespVO { | @@ -20,7 +22,7 @@ public class MidjourneySubmitRespVO { | ||
| 20 | private String description; | 22 | private String description; |
| 21 | 23 | ||
| 22 | @Schema(description = "扩展字段") | 24 | @Schema(description = "扩展字段") |
| 23 | - private String properties; | 25 | + private Map<String, Object> properties; |
| 24 | 26 | ||
| 25 | @Schema(description = "任务ID") | 27 | @Schema(description = "任务ID") |
| 26 | private String result; | 28 | private String result; |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/AiImageController.java
| @@ -3,13 +3,17 @@ package cn.iocoder.yudao.module.ai.controller.admin.image; | @@ -3,13 +3,17 @@ package cn.iocoder.yudao.module.ai.controller.admin.image; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | -import cn.iocoder.yudao.module.ai.controller.admin.image.vo.*; | 6 | +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDallReqVO; |
| 7 | +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageListReqVO; | ||
| 8 | +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyImagineReqVO; | ||
| 9 | +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImagePageMyRespVO; | ||
| 7 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | 10 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; |
| 8 | import cn.iocoder.yudao.module.ai.service.image.AiImageService; | 11 | import cn.iocoder.yudao.module.ai.service.image.AiImageService; |
| 9 | import io.swagger.v3.oas.annotations.Operation; | 12 | import io.swagger.v3.oas.annotations.Operation; |
| 10 | import io.swagger.v3.oas.annotations.Parameter; | 13 | import io.swagger.v3.oas.annotations.Parameter; |
| 11 | import io.swagger.v3.oas.annotations.tags.Tag; | 14 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 12 | import jakarta.annotation.Resource; | 15 | import jakarta.annotation.Resource; |
| 16 | +import jakarta.servlet.http.HttpServletRequest; | ||
| 13 | import lombok.extern.slf4j.Slf4j; | 17 | import lombok.extern.slf4j.Slf4j; |
| 14 | import org.springframework.validation.annotation.Validated; | 18 | import org.springframework.validation.annotation.Validated; |
| 15 | import org.springframework.web.bind.annotation.*; | 19 | import org.springframework.web.bind.annotation.*; |
| @@ -49,32 +53,17 @@ public class AiImageController { | @@ -49,32 +53,17 @@ public class AiImageController { | ||
| 49 | } | 53 | } |
| 50 | 54 | ||
| 51 | // TODO @fan:建议把 dallDrawing、midjourney 融合成一个 draw 接口,异步绘制;然后返回一个 id 给前端;前端通过 get 接口轮询,直到获取到生成成功 | 55 | // TODO @fan:建议把 dallDrawing、midjourney 融合成一个 draw 接口,异步绘制;然后返回一个 id 给前端;前端通过 get 接口轮询,直到获取到生成成功 |
| 56 | + // TODO @芋艿: 参数差异较大 | ||
| 52 | @Operation(summary = "dall2/dall3绘画", description = "openAi dall3是付费的!") | 57 | @Operation(summary = "dall2/dall3绘画", description = "openAi dall3是付费的!") |
| 53 | @PostMapping("/dall") | 58 | @PostMapping("/dall") |
| 54 | public CommonResult<Long> dall(@Validated @RequestBody AiImageDallReqVO req) { | 59 | public CommonResult<Long> dall(@Validated @RequestBody AiImageDallReqVO req) { |
| 55 | return success(aiImageService.dall(getLoginUserId(), req)); | 60 | return success(aiImageService.dall(getLoginUserId(), req)); |
| 56 | } | 61 | } |
| 57 | 62 | ||
| 58 | - @Operation(summary = "midjourney绘画", description = "midjourney图片绘画流程:1、提交任务 2、获取完成的任务 3、选择对应功能 4、获取最终结果") | ||
| 59 | - @PostMapping("/midjourney") | ||
| 60 | - public CommonResult<Void> midjourney(@Validated @RequestBody AiImageMidjourneyReqVO req) { | ||
| 61 | - aiImageService.midjourney(req); | ||
| 62 | - return success(null); | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | - @Operation(summary = "midjourney绘画操作", description = "一般有选择图片、放大、换一批...") | ||
| 66 | - @PostMapping("/midjourney-operate") | ||
| 67 | - public CommonResult<Void> midjourneyOperate(@Validated @RequestBody AiImageMidjourneyOperateReqVO req) { | ||
| 68 | - aiImageService.midjourneyOperate(req); | ||
| 69 | - return success(null); | ||
| 70 | - } | ||
| 71 | - | ||
| 72 | - // TODO @fan:要不先不要 midjourneyOperate、cancelMidjourney 接口哈 | ||
| 73 | - @Operation(summary = "取消 midjourney 绘画", description = "取消 midjourney 绘画") | ||
| 74 | - @PostMapping("/cancel-midjourney") | ||
| 75 | - public CommonResult<Void> cancelMidjourney(@RequestParam("id") Long id) { | ||
| 76 | - // @范 这里实现mj取消逻辑 | ||
| 77 | - return success(null); | 63 | + @Operation(summary = "midjourney-imagine 绘画", description = "...") |
| 64 | + @PostMapping("/midjourney/imagine") | ||
| 65 | + public CommonResult<Long> midjourneyImagine(@Validated @RequestBody AiImageMidjourneyImagineReqVO req) { | ||
| 66 | + return success(aiImageService.midjourneyImagine(getLoginUserId(), req)); | ||
| 78 | } | 67 | } |
| 79 | 68 | ||
| 80 | @Operation(summary = "删除【我的】绘画记录") | 69 | @Operation(summary = "删除【我的】绘画记录") |
| @@ -83,4 +72,10 @@ public class AiImageController { | @@ -83,4 +72,10 @@ public class AiImageController { | ||
| 83 | public CommonResult<Boolean> deleteIdMy(@RequestParam("id") Long id) { | 72 | public CommonResult<Boolean> deleteIdMy(@RequestParam("id") Long id) { |
| 84 | return success(aiImageService.deleteIdMy(id, getLoginUserId())); | 73 | return success(aiImageService.deleteIdMy(id, getLoginUserId())); |
| 85 | } | 74 | } |
| 75 | + | ||
| 76 | + @Operation(summary = "删除【我的】绘画记录") | ||
| 77 | + @RequestMapping("/midjourney-notify") | ||
| 78 | + public CommonResult<Boolean> midjourneyNotify(HttpServletRequest request) { | ||
| 79 | + return success(true); | ||
| 80 | + } | ||
| 86 | } | 81 | } |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImageMidjourneyReqVO.java renamed to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImageMidjourneyImagineReqVO.java
| 1 | package cn.iocoder.yudao.module.ai.controller.admin.image.vo; | 1 | package cn.iocoder.yudao.module.ai.controller.admin.image.vo; |
| 2 | 2 | ||
| 3 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | +import jakarta.validation.constraints.NotNull; | ||
| 4 | import lombok.Data; | 5 | import lombok.Data; |
| 5 | import lombok.experimental.Accessors; | 6 | import lombok.experimental.Accessors; |
| 6 | 7 | ||
| 8 | +import java.util.List; | ||
| 9 | + | ||
| 7 | /** | 10 | /** |
| 8 | * midjourney req | 11 | * midjourney req |
| 9 | * | 12 | * |
| @@ -13,17 +16,15 @@ import lombok.experimental.Accessors; | @@ -13,17 +16,15 @@ import lombok.experimental.Accessors; | ||
| 13 | */ | 16 | */ |
| 14 | @Data | 17 | @Data |
| 15 | @Accessors(chain = true) | 18 | @Accessors(chain = true) |
| 16 | -public class AiImageMidjourneyReqVO { | 19 | +public class AiImageMidjourneyImagineReqVO { |
| 17 | 20 | ||
| 18 | @Schema(description = "提示词") | 21 | @Schema(description = "提示词") |
| 22 | + @NotNull(message = "提示词不能为空!") | ||
| 19 | private String prompt; | 23 | private String prompt; |
| 20 | 24 | ||
| 21 | - @Schema(description = "绘画比例 1:1、3:4、4:3、9:16、16:9") | ||
| 22 | - private String size; | ||
| 23 | - | ||
| 24 | - @Schema(description = "风格") | ||
| 25 | - private String style; | 25 | + @Schema(description = "模型(midjourney、niji)") |
| 26 | + private String model; | ||
| 26 | 27 | ||
| 27 | - @Schema(description = "参考图") | ||
| 28 | - private String referImage; | 28 | + @Schema(description = "垫图(参考图)base64数组") |
| 29 | + private List<String> base64Array; | ||
| 29 | } | 30 | } |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageService.java
| @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.ai.service.image; | @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.ai.service.image; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDallReqVO; | 4 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDallReqVO; |
| 5 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageListReqVO; | 5 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageListReqVO; |
| 6 | +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyImagineReqVO; | ||
| 6 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyOperateReqVO; | 7 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyOperateReqVO; |
| 7 | -import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyReqVO; | ||
| 8 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | 8 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| @@ -44,10 +44,11 @@ public interface AiImageService { | @@ -44,10 +44,11 @@ public interface AiImageService { | ||
| 44 | /** | 44 | /** |
| 45 | * midjourney 图片生成 | 45 | * midjourney 图片生成 |
| 46 | * | 46 | * |
| 47 | + * @param loginUserId | ||
| 47 | * @param req | 48 | * @param req |
| 48 | * @return | 49 | * @return |
| 49 | */ | 50 | */ |
| 50 | - void midjourney(AiImageMidjourneyReqVO req); | 51 | + Long midjourneyImagine(Long loginUserId, AiImageMidjourneyImagineReqVO req); |
| 51 | 52 | ||
| 52 | /** | 53 | /** |
| 53 | * midjourney 操作(u1、u2、放大、换一批...) | 54 | * midjourney 操作(u1、u2、放大、换一批...) |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java
| 1 | package cn.iocoder.yudao.module.ai.service.image; | 1 | package cn.iocoder.yudao.module.ai.service.image; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.util.IdUtil; | ||
| 4 | import cn.hutool.http.HttpUtil; | 3 | import cn.hutool.http.HttpUtil; |
| 4 | +import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; | ||
| 5 | import cn.iocoder.yudao.framework.ai.core.enums.OpenAiImageModelEnum; | 5 | import cn.iocoder.yudao.framework.ai.core.enums.OpenAiImageModelEnum; |
| 6 | import cn.iocoder.yudao.framework.ai.core.enums.OpenAiImageStyleEnum; | 6 | import cn.iocoder.yudao.framework.ai.core.enums.OpenAiImageStyleEnum; |
| 7 | import cn.iocoder.yudao.framework.ai.core.exception.AiException; | 7 | import cn.iocoder.yudao.framework.ai.core.exception.AiException; |
| @@ -11,6 +11,10 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | @@ -11,6 +11,10 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 11 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | 11 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 12 | import cn.iocoder.yudao.module.ai.AiCommonConstants; | 12 | import cn.iocoder.yudao.module.ai.AiCommonConstants; |
| 13 | import cn.iocoder.yudao.module.ai.ErrorCodeConstants; | 13 | import cn.iocoder.yudao.module.ai.ErrorCodeConstants; |
| 14 | +import cn.iocoder.yudao.module.ai.client.MidjourneyProxyClient; | ||
| 15 | +import cn.iocoder.yudao.module.ai.client.vo.MidjourneyImagineReqVO; | ||
| 16 | +import cn.iocoder.yudao.module.ai.client.vo.MidjourneySubmitCodeEnum; | ||
| 17 | +import cn.iocoder.yudao.module.ai.client.vo.MidjourneySubmitRespVO; | ||
| 14 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.*; | 18 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.*; |
| 15 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | 19 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; |
| 16 | import cn.iocoder.yudao.module.ai.dal.mysql.image.AiImageMapper; | 20 | import cn.iocoder.yudao.module.ai.dal.mysql.image.AiImageMapper; |
| @@ -18,21 +22,22 @@ import cn.iocoder.yudao.module.ai.enums.AiImagePublicStatusEnum; | @@ -18,21 +22,22 @@ import cn.iocoder.yudao.module.ai.enums.AiImagePublicStatusEnum; | ||
| 18 | import cn.iocoder.yudao.module.ai.enums.AiImageStatusEnum; | 22 | import cn.iocoder.yudao.module.ai.enums.AiImageStatusEnum; |
| 19 | import cn.iocoder.yudao.module.infra.api.file.FileApi; | 23 | import cn.iocoder.yudao.module.infra.api.file.FileApi; |
| 20 | import com.google.common.collect.ImmutableMap; | 24 | import com.google.common.collect.ImmutableMap; |
| 21 | -import jakarta.annotation.PostConstruct; | ||
| 22 | import jakarta.annotation.Resource; | 25 | import jakarta.annotation.Resource; |
| 23 | import lombok.extern.slf4j.Slf4j; | 26 | import lombok.extern.slf4j.Slf4j; |
| 24 | import org.springframework.ai.image.ImageGeneration; | 27 | import org.springframework.ai.image.ImageGeneration; |
| 25 | import org.springframework.ai.image.ImagePrompt; | 28 | import org.springframework.ai.image.ImagePrompt; |
| 26 | import org.springframework.ai.image.ImageResponse; | 29 | import org.springframework.ai.image.ImageResponse; |
| 27 | -import org.springframework.ai.models.midjourney.api.MidjourneyInteractionsApi; | ||
| 28 | -import org.springframework.ai.models.midjourney.webSocket.MidjourneyWebSocketStarter; | ||
| 29 | import org.springframework.ai.openai.OpenAiImageClient; | 30 | import org.springframework.ai.openai.OpenAiImageClient; |
| 30 | import org.springframework.ai.openai.OpenAiImageOptions; | 31 | import org.springframework.ai.openai.OpenAiImageOptions; |
| 32 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 33 | +import org.springframework.beans.factory.annotation.Value; | ||
| 31 | import org.springframework.scheduling.annotation.Async; | 34 | import org.springframework.scheduling.annotation.Async; |
| 32 | import org.springframework.stereotype.Service; | 35 | import org.springframework.stereotype.Service; |
| 33 | import org.springframework.transaction.annotation.Transactional; | 36 | import org.springframework.transaction.annotation.Transactional; |
| 34 | 37 | ||
| 38 | +import java.util.HashMap; | ||
| 35 | import java.util.List; | 39 | import java.util.List; |
| 40 | +import java.util.Map; | ||
| 36 | 41 | ||
| 37 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 42 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 38 | 43 | ||
| @@ -59,28 +64,11 @@ public class AiImageServiceImpl implements AiImageService { | @@ -59,28 +64,11 @@ public class AiImageServiceImpl implements AiImageService { | ||
| 59 | private FileApi fileApi; | 64 | private FileApi fileApi; |
| 60 | @Resource | 65 | @Resource |
| 61 | private OpenAiImageClient openAiImageClient; | 66 | private OpenAiImageClient openAiImageClient; |
| 62 | - @Resource | ||
| 63 | - private MidjourneyWebSocketStarter midjourneyWebSocketStarter; | ||
| 64 | - @Resource | ||
| 65 | - private MidjourneyInteractionsApi midjourneyInteractionsApi; | ||
| 66 | - | ||
| 67 | - // TODO @fan:接 mj proxy | ||
| 68 | - @PostConstruct | ||
| 69 | - public void startMidjourney() { | ||
| 70 | - // todo @fan 暂时注释掉 | ||
| 71 | -// log.info("midjourney web socket starter..."); | ||
| 72 | -// midjourneyWebSocketStarter.start(new WssNotify() { | ||
| 73 | -// @Override | ||
| 74 | -// public void notify(int code, String message) { | ||
| 75 | -// log.info("code: {}, message: {}", code, message); | ||
| 76 | -// if (message.contains("Authentication failed")) { | ||
| 77 | -// // TODO 芋艿,这里看怎么处理,token无效的时候会认证失败! | ||
| 78 | -// // 认证失败 | ||
| 79 | -// log.error("midjourney socket 认证失败,检查token是否失效!"); | ||
| 80 | -// } | ||
| 81 | -// } | ||
| 82 | -// }); | ||
| 83 | - } | 67 | + @Autowired |
| 68 | + private MidjourneyProxyClient midjourneyProxyClient; | ||
| 69 | + | ||
| 70 | + @Value("${ai.midjourney-proxy.notifyUrl:http://127.0.0.1:48080/admin-api/ai/image/midjourney-notify}") | ||
| 71 | + private String midjourneyNotifyUrl; | ||
| 84 | 72 | ||
| 85 | @Override | 73 | @Override |
| 86 | public PageResult<AiImageDO> getImagePageMy(Long loginUserId, AiImageListReqVO req) { | 74 | public PageResult<AiImageDO> getImagePageMy(Long loginUserId, AiImageListReqVO req) { |
| @@ -143,18 +131,53 @@ public class AiImageServiceImpl implements AiImageService { | @@ -143,18 +131,53 @@ public class AiImageServiceImpl implements AiImageService { | ||
| 143 | 131 | ||
| 144 | @Override | 132 | @Override |
| 145 | @Transactional(rollbackFor = Exception.class) | 133 | @Transactional(rollbackFor = Exception.class) |
| 146 | - public void midjourney(AiImageMidjourneyReqVO req) { | ||
| 147 | - // 保存数据库 | ||
| 148 | - String messageId = String.valueOf(IdUtil.getSnowflakeNextId()); | ||
| 149 | - // todo | ||
| 150 | -// AiImageDO aiImageDO = doSave(req.getPrompt(), null, "midjoureny", | ||
| 151 | -// null, null, AiImageStatusEnum.SUBMIT, null, | ||
| 152 | -// messageId, null, null); | ||
| 153 | - // 提交 midjourney 任务 | ||
| 154 | - Boolean imagine = midjourneyInteractionsApi.imagine(messageId, req.getPrompt()); | ||
| 155 | - if (!imagine) { | ||
| 156 | - throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MIDJOURNEY_IMAGINE_FAIL); | 134 | + public Long midjourneyImagine(Long loginUserId, AiImageMidjourneyImagineReqVO req) { |
| 135 | + | ||
| 136 | + // 1、构建 AiImageDO | ||
| 137 | + AiImageDO aiImageDO = new AiImageDO(); | ||
| 138 | + aiImageDO.setId(null); | ||
| 139 | + aiImageDO.setUserId(loginUserId); | ||
| 140 | + aiImageDO.setPrompt(req.getPrompt()); | ||
| 141 | + aiImageDO.setPlatform(AiPlatformEnum.MIDJOURNEY.getPlatform()); | ||
| 142 | + // todo @范 平台需要转换(mj 模型一般分版本) | ||
| 143 | + aiImageDO.setModel(null); | ||
| 144 | + aiImageDO.setWidth(null); | ||
| 145 | + aiImageDO.setHeight(null); | ||
| 146 | + aiImageDO.setStatus(AiImageStatusEnum.IN_PROGRESS.getStatus()); | ||
| 147 | + aiImageDO.setPublicStatus(AiImagePublicStatusEnum.PRIVATE.getStatus()); | ||
| 148 | + aiImageDO.setPicUrl(null); | ||
| 149 | + aiImageDO.setOriginalPicUrl(null); | ||
| 150 | + aiImageDO.setDrawRequest(null); | ||
| 151 | + aiImageDO.setDrawResponse(null); | ||
| 152 | + aiImageDO.setErrorMessage(null); | ||
| 153 | + | ||
| 154 | + // 2、保存 image | ||
| 155 | + imageMapper.insert(aiImageDO); | ||
| 156 | + | ||
| 157 | + // 3、调用 MidjourneyProxy 提交任务 | ||
| 158 | + MidjourneyImagineReqVO imagineReqVO = BeanUtils.toBean(req, MidjourneyImagineReqVO.class); | ||
| 159 | + imagineReqVO.setNotifyHook(midjourneyNotifyUrl); | ||
| 160 | + imagineReqVO.setState(String.valueOf(aiImageDO.getId())); | ||
| 161 | + MidjourneySubmitRespVO submitRespVO = midjourneyProxyClient.imagine(imagineReqVO); | ||
| 162 | + | ||
| 163 | + // 4、保存任务 id (状态码: 1(提交成功), 21(已存在), 22(排队中), other(错误)) | ||
| 164 | + String updateStatus = null; | ||
| 165 | + String errorMessage = null; | ||
| 166 | + Map<String, Object> drawResponse = new HashMap<>(); | ||
| 167 | + | ||
| 168 | + if (!MidjourneySubmitCodeEnum.SUCCESS_CODES.contains(submitRespVO.getCode())) { | ||
| 169 | + updateStatus = AiImageStatusEnum.FAIL.getStatus(); | ||
| 170 | + errorMessage = submitRespVO.getDescription(); | ||
| 171 | + } else { | ||
| 172 | + drawResponse.put("jobId", submitRespVO.getResult()); | ||
| 157 | } | 173 | } |
| 174 | + imageMapper.updateById(new AiImageDO() | ||
| 175 | + .setId(aiImageDO.getId()) | ||
| 176 | + .setStatus(updateStatus) | ||
| 177 | + .setErrorMessage(errorMessage) | ||
| 178 | + .setDrawResponse(drawResponse) | ||
| 179 | + ); | ||
| 180 | + return aiImageDO.getId(); | ||
| 158 | } | 181 | } |
| 159 | 182 | ||
| 160 | @Transactional(rollbackFor = Exception.class) | 183 | @Transactional(rollbackFor = Exception.class) |