mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-26 17:21:53 +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…
Reference in New Issue
Block a user