Commit aa7c2cb251001dab4a35117b04d1097da1448f4b
1 parent
4d9dbeaa
【解决todo】使用 MidjourneyApi
Showing
15 changed files
with
34 additions
and
277 deletions
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/MidjourneyProxyClient.java deleted
| 1 | -package cn.iocoder.yudao.module.ai.client; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||
| 4 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneyActionReqVO; | ||
| 5 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneyImagineReqVO; | ||
| 6 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneyNotifyReqVO; | ||
| 7 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneySubmitRespVO; | ||
| 8 | -import cn.iocoder.yudao.module.ai.config.MidjourneyProperties; | ||
| 9 | -import com.google.common.collect.ImmutableMap; | ||
| 10 | -import jakarta.validation.constraints.NotNull; | ||
| 11 | -import org.springframework.beans.factory.annotation.Autowired; | ||
| 12 | -import org.springframework.http.*; | ||
| 13 | -import org.springframework.stereotype.Component; | ||
| 14 | -import org.springframework.validation.annotation.Validated; | ||
| 15 | -import org.springframework.web.client.RestTemplate; | ||
| 16 | - | ||
| 17 | -import java.util.Collection; | ||
| 18 | -import java.util.List; | ||
| 19 | - | ||
| 20 | -// TODO @fan:【高优】这个写到 starter-ai 里哈。搞个 MidjourneyApi,参考 https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java 的风格写哈 | ||
| 21 | -/** | ||
| 22 | - * Midjourney Proxy 客户端 | ||
| 23 | - * | ||
| 24 | - * @author fansili | ||
| 25 | - * @time 2024/5/30 13:58 | ||
| 26 | - * @since 1.0 | ||
| 27 | - */ | ||
| 28 | -@Component | ||
| 29 | -public class MidjourneyProxyClient { | ||
| 30 | - | ||
| 31 | - private static final String URI_IMAGINE = "/submit/imagine"; | ||
| 32 | - private static final String URI_ACTON = "/submit/action"; | ||
| 33 | - private static final String URI_LIST_BY_CONDITION = "/task/list-by-condition"; | ||
| 34 | - | ||
| 35 | - @Autowired | ||
| 36 | - private MidjourneyProperties midjourneyProperties; | ||
| 37 | - @Autowired | ||
| 38 | - private RestTemplate restTemplate; | ||
| 39 | - | ||
| 40 | - /** | ||
| 41 | - * imagine - 根据提示词提交绘画任务 | ||
| 42 | - * | ||
| 43 | - * @param imagineReqVO | ||
| 44 | - * @return | ||
| 45 | - */ | ||
| 46 | - public MidjourneySubmitRespVO imagine(@Validated @NotNull MidjourneyImagineReqVO imagineReqVO) { | ||
| 47 | - // 1、发送 post 请求 | ||
| 48 | - ResponseEntity<String> response = post(URI_IMAGINE, imagineReqVO); | ||
| 49 | - // 2、转换 resp | ||
| 50 | - return JsonUtils.parseObject(response.getBody(), MidjourneySubmitRespVO.class); | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | - /** | ||
| 54 | - * action - 放大、缩小、U1、U2... | ||
| 55 | - * | ||
| 56 | - * @param actionReqVO | ||
| 57 | - */ | ||
| 58 | - public MidjourneySubmitRespVO action(@Validated @NotNull MidjourneyActionReqVO actionReqVO) { | ||
| 59 | - // 1、发送 post 请求 | ||
| 60 | - ResponseEntity<String> response = post(URI_ACTON, actionReqVO); | ||
| 61 | - // 2、转换 resp | ||
| 62 | - return JsonUtils.parseObject(response.getBody(), MidjourneySubmitRespVO.class); | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | - /** | ||
| 66 | - * 批量查询 task 任务 | ||
| 67 | - * | ||
| 68 | - * @param taskIds | ||
| 69 | - * @return | ||
| 70 | - */ | ||
| 71 | - public List<MidjourneyNotifyReqVO> listByCondition(Collection<String> taskIds) { | ||
| 72 | - // 1、发送 post 请求 | ||
| 73 | - ResponseEntity<String> res = post(URI_LIST_BY_CONDITION, ImmutableMap.of("ids", taskIds)); | ||
| 74 | - // 2、转换 对象 | ||
| 75 | - return JsonUtils.parseArray(res.getBody(), MidjourneyNotifyReqVO.class); | ||
| 76 | - } | ||
| 77 | - | ||
| 78 | - private ResponseEntity<String> post(String uri, Object body) { | ||
| 79 | - // 1、创建 HttpHeaders 对象 | ||
| 80 | - HttpHeaders headers = new HttpHeaders(); | ||
| 81 | - headers.setContentType(MediaType.APPLICATION_JSON); | ||
| 82 | - headers.set("Authorization", "Bearer ".concat(midjourneyProperties.getKey())); | ||
| 83 | - // 2、创建 HttpEntity 对象,将 HttpHeaders 和请求体传递给它 | ||
| 84 | - HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.toJsonString(body), headers); | ||
| 85 | - // 3、发送 post 请求 | ||
| 86 | - return restTemplate.exchange(midjourneyProperties.getUrl().concat(uri), HttpMethod.POST, requestEntity, String.class); | ||
| 87 | - } | ||
| 88 | - | ||
| 89 | -} |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/enums/MidjourneyModelEnum.java deleted
| 1 | -package cn.iocoder.yudao.module.ai.client.enums; | ||
| 2 | - | ||
| 3 | - | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | -import lombok.Getter; | ||
| 6 | - | ||
| 7 | -/** | ||
| 8 | - * 来源于 midjourney-proxy | ||
| 9 | - */ | ||
| 10 | -@Getter | ||
| 11 | -@AllArgsConstructor | ||
| 12 | -public enum MidjourneyModelEnum { | ||
| 13 | - | ||
| 14 | - MIDJOURNEY("midjourney", "midjourney"), | ||
| 15 | - NIJI("Niji", "Niji"), | ||
| 16 | - | ||
| 17 | - ; | ||
| 18 | - | ||
| 19 | - private String model; | ||
| 20 | - private String name; | ||
| 21 | - | ||
| 22 | - public static MidjourneyModelEnum valueOfModel(String model) { | ||
| 23 | - for (MidjourneyModelEnum itemEnum : MidjourneyModelEnum.values()) { | ||
| 24 | - if (itemEnum.getModel().equals(model)) { | ||
| 25 | - return itemEnum; | ||
| 26 | - } | ||
| 27 | - } | ||
| 28 | - throw new IllegalArgumentException("Invalid MessageType value: " + model); | ||
| 29 | - } | ||
| 30 | -} |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/enums/MidjourneySubmitCodeEnum.java deleted
| 1 | -package cn.iocoder.yudao.module.ai.client.enums; | ||
| 2 | - | ||
| 3 | -import com.google.common.collect.Lists; | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | -import lombok.Getter; | ||
| 6 | - | ||
| 7 | -import java.util.List; | ||
| 8 | - | ||
| 9 | -// TODO @fan:待定 | ||
| 10 | -/** | ||
| 11 | - * Midjourney 提交任务 code 枚举 | ||
| 12 | - * | ||
| 13 | - * @author fansili | ||
| 14 | - */ | ||
| 15 | -@Getter | ||
| 16 | -@AllArgsConstructor | ||
| 17 | -public enum MidjourneySubmitCodeEnum { | ||
| 18 | - | ||
| 19 | - SUBMIT_SUCCESS("1", "提交成功"), | ||
| 20 | - ALREADY_EXISTS("21", "已存在"), | ||
| 21 | - QUEUING("22", "排队中"), | ||
| 22 | - ; | ||
| 23 | - | ||
| 24 | - public static final List<String> SUCCESS_CODES = Lists.newArrayList( | ||
| 25 | - SUBMIT_SUCCESS.code, | ||
| 26 | - ALREADY_EXISTS.code, | ||
| 27 | - QUEUING.code | ||
| 28 | - ); | ||
| 29 | - | ||
| 30 | - private final String code; | ||
| 31 | - private final String name; | ||
| 32 | - | ||
| 33 | -} |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/enums/MidjourneyTaskActionEnum.java deleted
| 1 | -package cn.iocoder.yudao.module.ai.client.enums; | ||
| 2 | - | ||
| 3 | -import lombok.Getter; | ||
| 4 | - | ||
| 5 | -/** | ||
| 6 | - * 来源于 midjourney-proxy | ||
| 7 | - */ | ||
| 8 | -@Getter | ||
| 9 | -public enum MidjourneyTaskActionEnum { | ||
| 10 | - /** | ||
| 11 | - * 生成图片. | ||
| 12 | - */ | ||
| 13 | - IMAGINE, | ||
| 14 | - /** | ||
| 15 | - * 选中放大. | ||
| 16 | - */ | ||
| 17 | - UPSCALE, | ||
| 18 | - /** | ||
| 19 | - * 选中其中的一张图,生成四张相似的. | ||
| 20 | - */ | ||
| 21 | - VARIATION, | ||
| 22 | - /** | ||
| 23 | - * 重新执行. | ||
| 24 | - */ | ||
| 25 | - REROLL, | ||
| 26 | - /** | ||
| 27 | - * 图转prompt. | ||
| 28 | - */ | ||
| 29 | - DESCRIBE, | ||
| 30 | - /** | ||
| 31 | - * 多图混合. | ||
| 32 | - */ | ||
| 33 | - BLEND | ||
| 34 | - | ||
| 35 | -} |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/enums/MidjourneyTaskStatusEnum.java deleted
| 1 | -package cn.iocoder.yudao.module.ai.client.enums; | ||
| 2 | - | ||
| 3 | - | ||
| 4 | -import lombok.Getter; | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * 来源于 midjourney-proxy | ||
| 8 | - */ | ||
| 9 | -public enum MidjourneyTaskStatusEnum { | ||
| 10 | - /** | ||
| 11 | - * 未启动. | ||
| 12 | - */ | ||
| 13 | - NOT_START(0), | ||
| 14 | - /** | ||
| 15 | - * 已提交. | ||
| 16 | - */ | ||
| 17 | - SUBMITTED(1), | ||
| 18 | - /** | ||
| 19 | - * 执行中. | ||
| 20 | - */ | ||
| 21 | - IN_PROGRESS(3), | ||
| 22 | - /** | ||
| 23 | - * 失败. | ||
| 24 | - */ | ||
| 25 | - FAILURE(4), | ||
| 26 | - /** | ||
| 27 | - * 成功. | ||
| 28 | - */ | ||
| 29 | - SUCCESS(4); | ||
| 30 | - | ||
| 31 | - @Getter | ||
| 32 | - private final int order; | ||
| 33 | - | ||
| 34 | - MidjourneyTaskStatusEnum(int order) { | ||
| 35 | - this.order = order; | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | -} |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/AiImageController.java
| @@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | @@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 8 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneyNotifyReqVO; | 8 | +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.MidjourneyNotifyReqVO; |
| 9 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; | 9 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; |
| 10 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyImagineReqVO; | 10 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyImagineReqVO; |
| 11 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageRespVO; | 11 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageRespVO; |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImageRespVO.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 cn.iocoder.yudao.module.ai.client.vo.MidjourneyNotifyReqVO; | ||
| 4 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | import lombok.Data; | 4 | import lombok.Data; |
| 6 | 5 |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/vo/MidjourneyActionReqVO.java renamed to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/MidjourneyActionReqVO.java
| 1 | -package cn.iocoder.yudao.module.ai.client.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 jakarta.validation.constraints.NotNull; |
| 5 | import lombok.Data; | 5 | import lombok.Data; |
| 6 | 6 | ||
| 7 | -import java.util.List; | ||
| 8 | - | ||
| 9 | /** | 7 | /** |
| 10 | * Midjourney:action 请求 | 8 | * Midjourney:action 请求 |
| 11 | * | 9 | * |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/vo/MidjourneyImagineReqVO.java renamed to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/MidjourneyImagineReqVO.java
| 1 | -package cn.iocoder.yudao.module.ai.client.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 jakarta.validation.constraints.NotNull; |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/vo/MidjourneyNotifyReqVO.java renamed to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/MidjourneyNotifyReqVO.java
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/client/vo/MidjourneySubmitRespVO.java renamed to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/MidjourneySubmitRespVO.java
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/image/AiImageDO.java
| @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.ai.dal.dataobject.image; | @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.ai.dal.dataobject.image; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 3 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 4 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 4 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneyNotifyReqVO; | 5 | +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.MidjourneyNotifyReqVO; |
| 6 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO; | 6 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO; |
| 7 | import cn.iocoder.yudao.module.ai.enums.image.AiImageStatusEnum; | 7 | import cn.iocoder.yudao.module.ai.enums.image.AiImageStatusEnum; |
| 8 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | 8 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/job/MidjourneyJob.java
| @@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.ai.job; | @@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.ai.job; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; | 4 | import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; |
| 5 | +import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi; | ||
| 5 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; | 6 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; |
| 6 | -import cn.iocoder.yudao.module.ai.client.MidjourneyProxyClient; | ||
| 7 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneyNotifyReqVO; | 7 | +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.MidjourneyNotifyReqVO; |
| 8 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | 8 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; |
| 9 | import cn.iocoder.yudao.module.ai.dal.mysql.image.AiImageMapper; | 9 | import cn.iocoder.yudao.module.ai.dal.mysql.image.AiImageMapper; |
| 10 | import cn.iocoder.yudao.module.ai.enums.image.AiImageStatusEnum; | 10 | import cn.iocoder.yudao.module.ai.enums.image.AiImageStatusEnum; |
| @@ -32,7 +32,7 @@ public class MidjourneyJob implements JobHandler { | @@ -32,7 +32,7 @@ public class MidjourneyJob implements JobHandler { | ||
| 32 | 32 | ||
| 33 | // TODO @fan:@Resource | 33 | // TODO @fan:@Resource |
| 34 | @Autowired | 34 | @Autowired |
| 35 | - private MidjourneyProxyClient midjourneyProxyClient; | 35 | + private MidjourneyApi midjourneyApi; |
| 36 | @Autowired | 36 | @Autowired |
| 37 | private AiImageMapper imageMapper; | 37 | private AiImageMapper imageMapper; |
| 38 | @Autowired | 38 | @Autowired |
| @@ -57,10 +57,10 @@ public class MidjourneyJob implements JobHandler { | @@ -57,10 +57,10 @@ public class MidjourneyJob implements JobHandler { | ||
| 57 | } | 57 | } |
| 58 | // 2、批量拉去 task 信息 | 58 | // 2、批量拉去 task 信息 |
| 59 | // TODO @fan:imageList.stream().map(AiImageDO::getTaskId).collect(Collectors.toSet())),可以使用 CollectionUtils.convertSet 简化 | 59 | // TODO @fan:imageList.stream().map(AiImageDO::getTaskId).collect(Collectors.toSet())),可以使用 CollectionUtils.convertSet 简化 |
| 60 | - List<MidjourneyNotifyReqVO> taskList = midjourneyProxyClient | 60 | + List<MidjourneyApi.NotifyRequest> taskList = midjourneyApi |
| 61 | .listByCondition(imageList.stream().map(AiImageDO::getTaskId).collect(Collectors.toSet())); | 61 | .listByCondition(imageList.stream().map(AiImageDO::getTaskId).collect(Collectors.toSet())); |
| 62 | // TODO @fan:taskList.stream().collect(Collectors.toMap(MidjourneyNotifyReqVO::getId, o -> o)),也可以使用 CollectionUtils.convertMap;本质上,重用 set、map 转换,要 convert 简化 | 62 | // TODO @fan:taskList.stream().collect(Collectors.toMap(MidjourneyNotifyReqVO::getId, o -> o)),也可以使用 CollectionUtils.convertMap;本质上,重用 set、map 转换,要 convert 简化 |
| 63 | - Map<String, MidjourneyNotifyReqVO> taskIdMap = taskList.stream().collect(Collectors.toMap(MidjourneyNotifyReqVO::getId, o -> o)); | 63 | + Map<String, MidjourneyApi.NotifyRequest> taskIdMap = taskList.stream().collect(Collectors.toMap(MidjourneyApi.NotifyRequest::id, o -> o)); |
| 64 | // 3、更新 image 状态 | 64 | // 3、更新 image 状态 |
| 65 | List<AiImageDO> updateImageList = new ArrayList<>(); | 65 | List<AiImageDO> updateImageList = new ArrayList<>(); |
| 66 | for (AiImageDO aiImageDO : imageList) { | 66 | for (AiImageDO aiImageDO : imageList) { |
| @@ -71,10 +71,10 @@ public class MidjourneyJob implements JobHandler { | @@ -71,10 +71,10 @@ public class MidjourneyJob implements JobHandler { | ||
| 71 | } | 71 | } |
| 72 | // TODO @ 3.1 和 3.2 是不是融合下;get,然后判空,continue; | 72 | // TODO @ 3.1 和 3.2 是不是融合下;get,然后判空,continue; |
| 73 | // 3.2 获取通知对象 | 73 | // 3.2 获取通知对象 |
| 74 | - MidjourneyNotifyReqVO notifyReqVO = taskIdMap.get(aiImageDO.getTaskId()); | 74 | +// MidjourneyNotifyReqVO notifyReqVO = taskIdMap.get(aiImageDO.getTaskId()); |
| 75 | // 3.2 构建更新对象 | 75 | // 3.2 构建更新对象 |
| 76 | // TODO @fan:建议 List<MidjourneyNotifyReqVO> 作为 imageService 去更新; | 76 | // TODO @fan:建议 List<MidjourneyNotifyReqVO> 作为 imageService 去更新; |
| 77 | - updateImageList.add(imageService.buildUpdateImage(aiImageDO.getId(), notifyReqVO)); | 77 | +// updateImageList.add(imageService.buildUpdateImage(aiImageDO.getId(), notifyReqVO)); |
| 78 | } | 78 | } |
| 79 | // 4、批了更新 updateImageList | 79 | // 4、批了更新 updateImageList |
| 80 | imageMapper.updateBatch(updateImageList); | 80 | imageMapper.updateBatch(updateImageList); |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageService.java
| @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.ai.service.image; | @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.ai.service.image; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneyNotifyReqVO; | 5 | +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.MidjourneyNotifyReqVO; |
| 6 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; | 6 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; |
| 7 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyImagineReqVO; | 7 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyImagineReqVO; |
| 8 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | 8 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java
| @@ -9,19 +9,13 @@ import cn.hutool.core.util.StrUtil; | @@ -9,19 +9,13 @@ import cn.hutool.core.util.StrUtil; | ||
| 9 | import cn.hutool.extra.spring.SpringUtil; | 9 | import cn.hutool.extra.spring.SpringUtil; |
| 10 | import cn.hutool.http.HttpUtil; | 10 | import cn.hutool.http.HttpUtil; |
| 11 | import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; | 11 | import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; |
| 12 | +import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi; | ||
| 12 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 13 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 13 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 14 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 14 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 15 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 15 | -import cn.iocoder.yudao.module.ai.client.MidjourneyProxyClient; | ||
| 16 | -import cn.iocoder.yudao.module.ai.client.enums.MidjourneyModelEnum; | ||
| 17 | -import cn.iocoder.yudao.module.ai.client.enums.MidjourneySubmitCodeEnum; | ||
| 18 | -import cn.iocoder.yudao.module.ai.client.enums.MidjourneyTaskStatusEnum; | ||
| 19 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneyActionReqVO; | ||
| 20 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneyImagineReqVO; | ||
| 21 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneyNotifyReqVO; | ||
| 22 | -import cn.iocoder.yudao.module.ai.client.vo.MidjourneySubmitRespVO; | ||
| 23 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; | 16 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; |
| 24 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyImagineReqVO; | 17 | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageMidjourneyImagineReqVO; |
| 18 | +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.MidjourneyNotifyReqVO; | ||
| 25 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | 19 | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; |
| 26 | import cn.iocoder.yudao.module.ai.dal.mysql.image.AiImageMapper; | 20 | import cn.iocoder.yudao.module.ai.dal.mysql.image.AiImageMapper; |
| 27 | import cn.iocoder.yudao.module.ai.enums.image.AiImageStatusEnum; | 21 | import cn.iocoder.yudao.module.ai.enums.image.AiImageStatusEnum; |
| @@ -57,16 +51,12 @@ public class AiImageServiceImpl implements AiImageService { | @@ -57,16 +51,12 @@ public class AiImageServiceImpl implements AiImageService { | ||
| 57 | 51 | ||
| 58 | @Resource | 52 | @Resource |
| 59 | private AiImageMapper imageMapper; | 53 | private AiImageMapper imageMapper; |
| 60 | - | ||
| 61 | @Resource | 54 | @Resource |
| 62 | private FileApi fileApi; | 55 | private FileApi fileApi; |
| 63 | - | ||
| 64 | @Resource | 56 | @Resource |
| 65 | private AiApiKeyService apiKeyService; | 57 | private AiApiKeyService apiKeyService; |
| 66 | - | ||
| 67 | @Autowired | 58 | @Autowired |
| 68 | - private MidjourneyProxyClient midjourneyProxyClient; | ||
| 69 | - | 59 | + private MidjourneyApi midjourneyApi; |
| 70 | @Value("${ai.midjourney-proxy.notifyUrl:http://127.0.0.1:48080/admin-api/ai/image/midjourney-notify}") | 60 | @Value("${ai.midjourney-proxy.notifyUrl:http://127.0.0.1:48080/admin-api/ai/image/midjourney-notify}") |
| 71 | private String midjourneyNotifyUrl; | 61 | private String midjourneyNotifyUrl; |
| 72 | 62 | ||
| @@ -148,22 +138,21 @@ public class AiImageServiceImpl implements AiImageService { | @@ -148,22 +138,21 @@ public class AiImageServiceImpl implements AiImageService { | ||
| 148 | // 3、调用 MidjourneyProxy 提交任务 | 138 | // 3、调用 MidjourneyProxy 提交任务 |
| 149 | 139 | ||
| 150 | // 3.1、设置 midjourney 扩展参数 | 140 | // 3.1、设置 midjourney 扩展参数 |
| 151 | - MidjourneyImagineReqVO imagineReqVO = BeanUtils.toBean(req, MidjourneyImagineReqVO.class); | ||
| 152 | - imagineReqVO.setNotifyHook(midjourneyNotifyUrl); | ||
| 153 | - imagineReqVO.setState(buildParams(req.getWidth(), | ||
| 154 | - req.getHeight(), req.getVersion(), MidjourneyModelEnum.valueOfModel(req.getModel()))); | 141 | + MidjourneyApi.ImagineRequest imagineRequest = new MidjourneyApi.ImagineRequest(null, midjourneyNotifyUrl, req.getPrompt(), |
| 142 | + buildParams(req.getWidth(), req.getHeight(), req.getVersion(), | ||
| 143 | + MidjourneyApi.ModelEnum.valueOfModel(req.getModel()))); | ||
| 155 | // 3.2、提交绘画请求 | 144 | // 3.2、提交绘画请求 |
| 156 | // TODO @fan:5 这里,失败的情况,到底抛出异常,还是 RespVO,可以参考 OpenAI 的 API 封装 | 145 | // TODO @fan:5 这里,失败的情况,到底抛出异常,还是 RespVO,可以参考 OpenAI 的 API 封装 |
| 157 | - MidjourneySubmitRespVO submitRespVO = midjourneyProxyClient.imagine(imagineReqVO); | 146 | + MidjourneyApi.SubmitResponse submitResponse = midjourneyApi.imagine(imagineRequest); |
| 158 | 147 | ||
| 159 | // 4、保存任务 id (状态码: 1(提交成功), 21(已存在), 22(排队中), other(错误)) | 148 | // 4、保存任务 id (状态码: 1(提交成功), 21(已存在), 22(排队中), other(错误)) |
| 160 | - if (!MidjourneySubmitCodeEnum.SUCCESS_CODES.contains(submitRespVO.getCode())) { | ||
| 161 | - throw exception(AI_IMAGE_MIDJOURNEY_SUBMIT_FAIL, submitRespVO.getDescription()); | 149 | + if (!MidjourneyApi.SubmitCodeEnum.SUCCESS_CODES.contains(submitResponse.code())) { |
| 150 | + throw exception(AI_IMAGE_MIDJOURNEY_SUBMIT_FAIL, submitResponse.description()); | ||
| 162 | } | 151 | } |
| 163 | // 4.1、更新 taskId 和参数 | 152 | // 4.1、更新 taskId 和参数 |
| 164 | imageMapper.updateById(new AiImageDO() | 153 | imageMapper.updateById(new AiImageDO() |
| 165 | .setId(image.getId()) | 154 | .setId(image.getId()) |
| 166 | - .setTaskId(submitRespVO.getResult()) | 155 | + .setTaskId(submitResponse.result()) |
| 167 | .setOptions(BeanUtil.beanToMap(req)) | 156 | .setOptions(BeanUtil.beanToMap(req)) |
| 168 | ); | 157 | ); |
| 169 | return image.getId(); | 158 | return image.getId(); |
| @@ -197,10 +186,10 @@ public class AiImageServiceImpl implements AiImageService { | @@ -197,10 +186,10 @@ public class AiImageServiceImpl implements AiImageService { | ||
| 197 | public AiImageDO buildUpdateImage(Long imageId, MidjourneyNotifyReqVO notifyReqVO) { | 186 | public AiImageDO buildUpdateImage(Long imageId, MidjourneyNotifyReqVO notifyReqVO) { |
| 198 | // 1、转换状态 | 187 | // 1、转换状态 |
| 199 | String imageStatus = null; | 188 | String imageStatus = null; |
| 200 | - MidjourneyTaskStatusEnum taskStatusEnum = MidjourneyTaskStatusEnum.valueOf(notifyReqVO.getStatus()); | ||
| 201 | - if (MidjourneyTaskStatusEnum.SUCCESS == taskStatusEnum) { | 189 | + MidjourneyApi.TaskStatusEnum taskStatusEnum = MidjourneyApi.TaskStatusEnum.valueOf(notifyReqVO.getStatus()); |
| 190 | + if (MidjourneyApi.TaskStatusEnum.SUCCESS == taskStatusEnum) { | ||
| 202 | imageStatus = AiImageStatusEnum.SUCCESS.getStatus(); | 191 | imageStatus = AiImageStatusEnum.SUCCESS.getStatus(); |
| 203 | - } else if (MidjourneyTaskStatusEnum.FAILURE == taskStatusEnum) { | 192 | + } else if (MidjourneyApi.TaskStatusEnum.FAILURE == taskStatusEnum) { |
| 204 | imageStatus = AiImageStatusEnum.FAIL.getStatus(); | 193 | imageStatus = AiImageStatusEnum.FAIL.getStatus(); |
| 205 | } | 194 | } |
| 206 | 195 | ||
| @@ -233,15 +222,11 @@ public class AiImageServiceImpl implements AiImageService { | @@ -233,15 +222,11 @@ public class AiImageServiceImpl implements AiImageService { | ||
| 233 | validateCustomId(customId, image.getButtons()); | 222 | validateCustomId(customId, image.getButtons()); |
| 234 | 223 | ||
| 235 | // 3、调用 midjourney proxy | 224 | // 3、调用 midjourney proxy |
| 236 | - MidjourneySubmitRespVO submitRespVO = midjourneyProxyClient.action( | ||
| 237 | - new MidjourneyActionReqVO() | ||
| 238 | - .setCustomId(customId) | ||
| 239 | - .setTaskId(image.getTaskId()) | ||
| 240 | - .setNotifyHook(midjourneyNotifyUrl) | ||
| 241 | - ); | 225 | + MidjourneyApi.SubmitResponse submitResponse = midjourneyApi.action( |
| 226 | + new MidjourneyApi.ActionRequest(customId, image.getTaskId(), midjourneyNotifyUrl)); | ||
| 242 | // 4、检查错误 code (状态码: 1(提交成功), 21(已存在), 22(排队中), other(错误)) | 227 | // 4、检查错误 code (状态码: 1(提交成功), 21(已存在), 22(排队中), other(错误)) |
| 243 | - if (!MidjourneySubmitCodeEnum.SUCCESS_CODES.contains(submitRespVO.getCode())) { | ||
| 244 | - throw exception(AI_IMAGE_MIDJOURNEY_SUBMIT_FAIL, submitRespVO.getDescription()); | 228 | + if (!MidjourneyApi.SubmitCodeEnum.SUCCESS_CODES.contains(submitResponse.code())) { |
| 229 | + throw exception(AI_IMAGE_MIDJOURNEY_SUBMIT_FAIL, submitResponse.description()); | ||
| 245 | } | 230 | } |
| 246 | 231 | ||
| 247 | // 5、新增 image 记录(根据 image 新增一个) | 232 | // 5、新增 image 记录(根据 image 新增一个) |
| @@ -263,7 +248,7 @@ public class AiImageServiceImpl implements AiImageService { | @@ -263,7 +248,7 @@ public class AiImageServiceImpl implements AiImageService { | ||
| 263 | newImage.setButtons(null); | 248 | newImage.setButtons(null); |
| 264 | newImage.setOptions(image.getOptions()); | 249 | newImage.setOptions(image.getOptions()); |
| 265 | newImage.setResponse(image.getResponse()); | 250 | newImage.setResponse(image.getResponse()); |
| 266 | - newImage.setTaskId(submitRespVO.getResult()); | 251 | + newImage.setTaskId(submitResponse.result()); |
| 267 | newImage.setErrorMessage(null); | 252 | newImage.setErrorMessage(null); |
| 268 | imageMapper.insert(newImage); | 253 | imageMapper.insert(newImage); |
| 269 | } | 254 | } |
| @@ -309,14 +294,14 @@ public class AiImageServiceImpl implements AiImageService { | @@ -309,14 +294,14 @@ public class AiImageServiceImpl implements AiImageService { | ||
| 309 | * @param model | 294 | * @param model |
| 310 | * @return | 295 | * @return |
| 311 | */ | 296 | */ |
| 312 | - private String buildParams(Integer width, Integer height, String version, MidjourneyModelEnum model) { | 297 | + private String buildParams(Integer width, Integer height, String version, MidjourneyApi.ModelEnum model) { |
| 313 | StringBuilder params = new StringBuilder(); | 298 | StringBuilder params = new StringBuilder(); |
| 314 | // --ar 来设置尺寸 | 299 | // --ar 来设置尺寸 |
| 315 | params.append(String.format(" --ar %s:%s ", width, height)); | 300 | params.append(String.format(" --ar %s:%s ", width, height)); |
| 316 | // --v 版本 | 301 | // --v 版本 |
| 317 | params.append(String.format(" --v %s ", version)); | 302 | params.append(String.format(" --v %s ", version)); |
| 318 | // --niji 模型 | 303 | // --niji 模型 |
| 319 | - if (MidjourneyModelEnum.NIJI == model) { | 304 | + if (MidjourneyApi.ModelEnum.NIJI == model) { |
| 320 | params.append(" --niji "); | 305 | params.append(" --niji "); |
| 321 | } | 306 | } |
| 322 | return params.toString(); | 307 | return params.toString(); |