mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-06-20 23:42:00 +08:00
【临时提交】增加 MidjourneyApi
This commit is contained in:
parent
1ac1c007ad
commit
937992fd16
@ -0,0 +1,18 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.core.model.midjourney;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Midjourney 属性
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/6/5 15:02
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MidjourneyProperties {
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
private String url;
|
||||||
|
private String notifyUrl;
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.core.model.midjourney.api;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.ai.core.model.midjourney.MidjourneyProperties;
|
||||||
|
import cn.iocoder.yudao.framework.ai.core.model.midjourney.vo.MidjourneyActionRequest;
|
||||||
|
import cn.iocoder.yudao.framework.ai.core.model.midjourney.vo.MidjourneyImagineRequest;
|
||||||
|
import cn.iocoder.yudao.framework.ai.core.model.midjourney.vo.MidjourneyNotifyRequest;
|
||||||
|
import cn.iocoder.yudao.framework.ai.core.model.midjourney.vo.MidjourneySubmitResponse;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.ai.openai.api.ApiUtils;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Midjourney api
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/6/11 15:46
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class MidjourneyApi {
|
||||||
|
|
||||||
|
private static final String URI_IMAGINE = "/submit/imagine";
|
||||||
|
private static final String URI_ACTON = "/submit/action";
|
||||||
|
private static final String URI_LIST_BY_CONDITION = "/task/list-by-condition";
|
||||||
|
private final WebClient webClient;
|
||||||
|
private final MidjourneyProperties midjourneyProperties;
|
||||||
|
|
||||||
|
public MidjourneyApi(MidjourneyProperties midjourneyProperties) {
|
||||||
|
this.midjourneyProperties = midjourneyProperties;
|
||||||
|
this.webClient = WebClient.builder()
|
||||||
|
.baseUrl(midjourneyProperties.getUrl())
|
||||||
|
.defaultHeaders(ApiUtils.getJsonContentHeaders(midjourneyProperties.getKey()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* imagine - 根据提示词提交绘画任务
|
||||||
|
*
|
||||||
|
* @param imagineReqVO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public MidjourneySubmitResponse imagine(MidjourneyImagineRequest imagineReqVO) {
|
||||||
|
// 1、发送 post 请求
|
||||||
|
String res = post(URI_IMAGINE, imagineReqVO);
|
||||||
|
// 2、转换 resp
|
||||||
|
return JsonUtils.parseObject(res, MidjourneySubmitResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* action - 放大、缩小、U1、U2...
|
||||||
|
*
|
||||||
|
* @param actionReqVO
|
||||||
|
*/
|
||||||
|
public MidjourneySubmitResponse action(MidjourneyActionRequest actionReqVO) {
|
||||||
|
// 1、发送 post 请求
|
||||||
|
String res = post(URI_ACTON, actionReqVO);
|
||||||
|
// 2、转换 resp
|
||||||
|
return JsonUtils.parseObject(res, MidjourneySubmitResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询 task 任务
|
||||||
|
*
|
||||||
|
* @param taskIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<MidjourneyNotifyRequest> listByCondition(Collection<String> taskIds) {
|
||||||
|
// 1、发送 post 请求
|
||||||
|
String res = post(URI_LIST_BY_CONDITION, ImmutableMap.of("ids", taskIds));
|
||||||
|
// 2、转换 对象
|
||||||
|
return JsonUtils.parseArray(res, MidjourneyNotifyRequest.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String post(String uri, Object body) {
|
||||||
|
// 1、发送 post 请求
|
||||||
|
return webClient.post()
|
||||||
|
.uri(uri)
|
||||||
|
.body(Mono.just(JsonUtils.toJsonString(body)), String.class)
|
||||||
|
.retrieve()
|
||||||
|
.onStatus(status -> !status.is2xxSuccessful(),
|
||||||
|
response -> response.bodyToMono(String.class)
|
||||||
|
.handle((respBody, sink) -> {
|
||||||
|
log.error("【Midjourney api】调用失败!resp: 【{}】", respBody);
|
||||||
|
sink.error(new IllegalStateException("【Midjourney api】调用失败!"));
|
||||||
|
}))
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.block();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.core.model.midjourney.enums;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 来源于 midjourney-proxy
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum MidjourneyModelEnum {
|
||||||
|
|
||||||
|
MIDJOURNEY("midjourney", "midjourney"),
|
||||||
|
NIJI("Niji", "Niji"),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
private String model;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public static MidjourneyModelEnum valueOfModel(String model) {
|
||||||
|
for (MidjourneyModelEnum itemEnum : MidjourneyModelEnum.values()) {
|
||||||
|
if (itemEnum.getModel().equals(model)) {
|
||||||
|
return itemEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid MessageType value: " + model);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.core.model.midjourney.enums;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
// TODO @fan:待定
|
||||||
|
/**
|
||||||
|
* Midjourney 提交任务 code 枚举
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum MidjourneySubmitCodeEnum {
|
||||||
|
|
||||||
|
SUBMIT_SUCCESS("1", "提交成功"),
|
||||||
|
ALREADY_EXISTS("21", "已存在"),
|
||||||
|
QUEUING("22", "排队中"),
|
||||||
|
;
|
||||||
|
|
||||||
|
public static final List<String> SUCCESS_CODES = Lists.newArrayList(
|
||||||
|
SUBMIT_SUCCESS.code,
|
||||||
|
ALREADY_EXISTS.code,
|
||||||
|
QUEUING.code
|
||||||
|
);
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.core.model.midjourney.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 来源于 midjourney-proxy
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum MidjourneyTaskActionEnum {
|
||||||
|
/**
|
||||||
|
* 生成图片.
|
||||||
|
*/
|
||||||
|
IMAGINE,
|
||||||
|
/**
|
||||||
|
* 选中放大.
|
||||||
|
*/
|
||||||
|
UPSCALE,
|
||||||
|
/**
|
||||||
|
* 选中其中的一张图,生成四张相似的.
|
||||||
|
*/
|
||||||
|
VARIATION,
|
||||||
|
/**
|
||||||
|
* 重新执行.
|
||||||
|
*/
|
||||||
|
REROLL,
|
||||||
|
/**
|
||||||
|
* 图转prompt.
|
||||||
|
*/
|
||||||
|
DESCRIBE,
|
||||||
|
/**
|
||||||
|
* 多图混合.
|
||||||
|
*/
|
||||||
|
BLEND
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.core.model.midjourney.enums;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 来源于 midjourney-proxy
|
||||||
|
*/
|
||||||
|
public enum MidjourneyTaskStatusEnum {
|
||||||
|
/**
|
||||||
|
* 未启动.
|
||||||
|
*/
|
||||||
|
NOT_START(0),
|
||||||
|
/**
|
||||||
|
* 已提交.
|
||||||
|
*/
|
||||||
|
SUBMITTED(1),
|
||||||
|
/**
|
||||||
|
* 执行中.
|
||||||
|
*/
|
||||||
|
IN_PROGRESS(3),
|
||||||
|
/**
|
||||||
|
* 失败.
|
||||||
|
*/
|
||||||
|
FAILURE(4),
|
||||||
|
/**
|
||||||
|
* 成功.
|
||||||
|
*/
|
||||||
|
SUCCESS(4);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final int order;
|
||||||
|
|
||||||
|
MidjourneyTaskStatusEnum(int order) {
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.core.model.midjourney.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Midjourney:action 请求
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/5/30 14:02
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MidjourneyActionRequest {
|
||||||
|
|
||||||
|
@Schema(description = "操作按钮id", required = true)
|
||||||
|
private String customId;
|
||||||
|
|
||||||
|
@Schema(description = "操作按钮id", required = true)
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
@Schema(description = "通知地址", required = false)
|
||||||
|
private String notifyHook;
|
||||||
|
|
||||||
|
@Schema(description = "自定义参数", required = false)
|
||||||
|
private String state;
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.core.model.midjourney.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
// TODO @fan:待定
|
||||||
|
/**
|
||||||
|
* Midjourney:Imagine 请求
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/5/30 14:02
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MidjourneyImagineRequest {
|
||||||
|
|
||||||
|
@Schema(description = "垫图(参考图)base64数组", required = false)
|
||||||
|
private List<String> base64Array;
|
||||||
|
|
||||||
|
@Schema(description = "通知地址", required = false)
|
||||||
|
private String notifyHook;
|
||||||
|
|
||||||
|
@Schema(description = "提示词", required = true)
|
||||||
|
private String prompt;
|
||||||
|
|
||||||
|
@Schema(description = "自定义参数", required = false)
|
||||||
|
private String state;
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.core.model.midjourney.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Midjourney Proxy 通知回调
|
||||||
|
*
|
||||||
|
* - Midjourney Proxy:通知回调 bean 是 com.github.novicezk.midjourney.support.Task
|
||||||
|
* - 毫秒 api 通知回调文档地址:https://gpt-best.apifox.cn/doc-3530863
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/5/31 10:37
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MidjourneyNotifyRequest {
|
||||||
|
|
||||||
|
@Schema(description = "job id")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "任务类型 MidjourneyTaskActionEnum")
|
||||||
|
private String action;
|
||||||
|
@Schema(description = "任务状态 MidjourneyTaskStatusEnum")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "提示词")
|
||||||
|
private String prompt;
|
||||||
|
@Schema(description = "提示词-英文")
|
||||||
|
private String promptEn;
|
||||||
|
|
||||||
|
@Schema(description = "任务描述")
|
||||||
|
private String description;
|
||||||
|
@Schema(description = "自定义参数")
|
||||||
|
private String state;
|
||||||
|
|
||||||
|
@Schema(description = "提交时间")
|
||||||
|
private Long submitTime;
|
||||||
|
@Schema(description = "开始执行时间")
|
||||||
|
private Long startTime;
|
||||||
|
@Schema(description = "结束时间")
|
||||||
|
private Long finishTime;
|
||||||
|
|
||||||
|
@Schema(description = "图片url")
|
||||||
|
private String imageUrl;
|
||||||
|
|
||||||
|
@Schema(description = "任务进度")
|
||||||
|
private String progress;
|
||||||
|
@Schema(description = "失败原因")
|
||||||
|
private String failReason;
|
||||||
|
|
||||||
|
@Schema(description = "任务完成后的可执行按钮")
|
||||||
|
private List<Button> buttons;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Button {
|
||||||
|
|
||||||
|
@Schema(description = "MJ::JOB::upsample::1::85a4b4c1-8835-46c5-a15c-aea34fad1862 动作标识")
|
||||||
|
private String customId;
|
||||||
|
|
||||||
|
@Schema(description = "图标 emoji")
|
||||||
|
private String emoji;
|
||||||
|
|
||||||
|
@Schema(description = "Make Variations 文本")
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
@Schema(description = "类型,系统内部使用")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "样式: 2(Primary)、3(Green)")
|
||||||
|
private String style;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package cn.iocoder.yudao.framework.ai.core.model.midjourney.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
// TODO @fan:待定
|
||||||
|
/**
|
||||||
|
* Midjourney:Imagine 请求
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/5/30 14:02
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MidjourneySubmitResponse {
|
||||||
|
|
||||||
|
@Schema(description = "状态码: 1(提交成功), 21(已存在), 22(排队中), other(错误)")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
@Schema(description = "描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "扩展字段")
|
||||||
|
private Map<String, Object> properties;
|
||||||
|
|
||||||
|
@Schema(description = "任务ID")
|
||||||
|
private String result;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user