From 316d2db484ffc2f22d698483f1f7486d5b843e3d Mon Sep 17 00:00:00 2001 From: cherishsince Date: Mon, 8 Apr 2024 14:34:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0mj=E7=94=9F=E6=88=90=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ai/midjourney/MidjourneyConfig.java | 13 +- .../ai/midjourney/constants/MjConstants.java | 4 + .../ai/midjourney/interactions/MjClient.java | 47 ------- .../interactions/MjInteractions.java | 126 +++++++++++++++++- .../framework/ai/midjourney/util/MjUtil.java | 21 ++- .../ai/midjourney/vo/Attachments.java | 22 +++ .../framework/ai/midjourney/vo/Describe.java | 26 ++++ .../framework/ai/midjourney/vo/ReRoll.java | 6 + .../midjourney/vo/UploadAttachmentsRes.java | 36 +++++ .../framework/ai/mj/MjInteractionsTests.java | 24 ++++ 10 files changed, 265 insertions(+), 60 deletions(-) delete mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/interactions/MjClient.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/Attachments.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/Describe.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/UploadAttachmentsRes.java diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/MidjourneyConfig.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/MidjourneyConfig.java index dd8a599c6..8f749baf4 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/MidjourneyConfig.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/MidjourneyConfig.java @@ -42,14 +42,20 @@ public class MidjourneyConfig { * 发送命令 */ private String apiInteractions = "api/v9/interactions"; - + /** + * 附件 + */ + private String apiAttachments = "/api/v9/channels/%s/attachments"; + /** + * 文件上传 + */ + private String apiAttachmentsUpload = "https://discord-attachments-uploads-prd.storage.googleapis.com/"; // // 浏览器配置 private String userAage = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"; - // // 请求 json 文件 @@ -65,9 +71,6 @@ public class MidjourneyConfig { this.token = token; this.guildId = guildId; this.channelId = channelId; - this.serverUrl = serverUrl; - this.apiInteractions = apiInteractions; - this.userAage = userAage; this.requestTemplates = requestTemplates; // 生成 session id diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MjConstants.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MjConstants.java index 884f2626c..751652b08 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MjConstants.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MjConstants.java @@ -34,4 +34,8 @@ public final class MjConstants { public static final String MSG_ATTACHMENTS = "attachments"; + // + // + + public static final String HTTP_COOKIE = "__dcfduid=6ca536c0e3fa11eeb7cbe34c31b49caf; __sdcfduid=6ca536c1e3fa11eeb7cbe34c31b49caf52cce5ffd8983d2a052cf6aba75fe5fe566f2c265902e283ce30dbf98b8c9c93; _gcl_au=1.1.245923998.1710853617; _ga=GA1.1.111061823.1710853617; __cfruid=6385bb3f48345a006b25992db7dcf984e395736d-1712124666; _cfuvid=O09la5ms0ypNptiG0iD8A6BKWlTxz1LG0WR7qRStD7o-1712124666575-0.0.1.1-604800000; locale=zh-CN; cf_clearance=l_YGod1_SUtYxpDVeZXiX7DLLPl1DYrquZe8WVltvYs-1712124668-1.0.1.1-Hl2.fToel23EpF2HCu9J20rB4D7OhhCzoajPSdo.9Up.wPxhvq22DP9RHzEBKuIUlKyH.kJLxXJfAt2N.LD5WQ; OptanonConsent=isIABGlobal=false&datestamp=Wed+Apr+03+2024+14%3A11%3A15+GMT%2B0800+(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4)&version=6.33.0&hosts=&landingPath=https%3A%2F%2Fdiscord.com%2F&groups=C0001%3A1%2CC0002%3A1%2CC0003%3A1; _ga_Q149DFWHT7=GS1.1.1712124668.4.1.1712124679.0.0.0"; } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/interactions/MjClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/interactions/MjClient.java deleted file mode 100644 index 67ce684f2..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/interactions/MjClient.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.framework.ai.midjourney.interactions; - -import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.web.client.RestTemplate; - -import java.util.Map; - -/** - * mj client - *

- * author: fansili - * time: 2024/4/3 17:37 - */ -public class MjClient { - - private static RestTemplate restTemplate = new RestTemplate(); - private static HttpHeaders headers = new HttpHeaders(); - - private static final String HEADER_REFERER = "https://discord.com/channels/%s/%s"; - - static { - headers.setContentType(MediaType.APPLICATION_JSON); // 设置内容类型为JSON - headers.set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"); - headers.set("Cookie", "__dcfduid=6ca536c0e3fa11eeb7cbe34c31b49caf; __sdcfduid=6ca536c1e3fa11eeb7cbe34c31b49caf52cce5ffd8983d2a052cf6aba75fe5fe566f2c265902e283ce30dbf98b8c9c93; _gcl_au=1.1.245923998.1710853617; _ga=GA1.1.111061823.1710853617; __cfruid=6385bb3f48345a006b25992db7dcf984e395736d-1712124666; _cfuvid=O09la5ms0ypNptiG0iD8A6BKWlTxz1LG0WR7qRStD7o-1712124666575-0.0.1.1-604800000; locale=zh-CN; cf_clearance=l_YGod1_SUtYxpDVeZXiX7DLLPl1DYrquZe8WVltvYs-1712124668-1.0.1.1-Hl2.fToel23EpF2HCu9J20rB4D7OhhCzoajPSdo.9Up.wPxhvq22DP9RHzEBKuIUlKyH.kJLxXJfAt2N.LD5WQ; OptanonConsent=isIABGlobal=false&datestamp=Wed+Apr+03+2024+14%3A11%3A15+GMT%2B0800+(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4)&version=6.33.0&hosts=&landingPath=https%3A%2F%2Fdiscord.com%2F&groups=C0001%3A1%2CC0002%3A1%2CC0003%3A1; _ga_Q149DFWHT7=GS1.1.1712124668.4.1.1712124679.0.0.0"); - } - - public static String post(String url, MidjourneyConfig config, String body) { - // 设置 header - headers.set("Referer", String.format(HEADER_REFERER, config.getGuildId(), config.getChannelId())); - headers.set("Authorization", config.getToken()); - // 封装请求体和头部信息 - HttpEntity requestEntity = new HttpEntity<>(body, headers); - // 发送请求 - return restTemplate.postForObject(url, requestEntity, String.class); - } - - - public static String setParams(String requestTemplate, Map requestParams) { - for (Map.Entry entry : requestParams.entrySet()) { - requestTemplate = requestTemplate.replace("$".concat(entry.getKey()), entry.getValue()); - } - return requestTemplate; - } -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/interactions/MjInteractions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/interactions/MjInteractions.java index 1a4d0d817..07827e978 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/interactions/MjInteractions.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/interactions/MjInteractions.java @@ -3,10 +3,25 @@ package cn.iocoder.yudao.framework.ai.midjourney.interactions; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; +import cn.iocoder.yudao.framework.ai.midjourney.constants.MjConstants; +import cn.iocoder.yudao.framework.ai.midjourney.util.MjUtil; +import cn.iocoder.yudao.framework.ai.midjourney.vo.Attachments; +import cn.iocoder.yudao.framework.ai.midjourney.vo.Describe; import cn.iocoder.yudao.framework.ai.midjourney.vo.ReRoll; +import cn.iocoder.yudao.framework.ai.midjourney.vo.UploadAttachmentsRes; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; +import java.io.IOException; import java.util.HashMap; /** @@ -18,9 +33,12 @@ import java.util.HashMap; @Slf4j public class MjInteractions { - private MidjourneyConfig midjourneyConfig; - private String url; + private final String url; + private final MidjourneyConfig midjourneyConfig; + private final RestTemplate restTemplate = new RestTemplate(); + private static final String HEADER_REFERER = "https://discord.com/channels/%s/%s"; + public MjInteractions(MidjourneyConfig midjourneyConfig) { this.midjourneyConfig = midjourneyConfig; @@ -37,10 +55,13 @@ public class MjInteractions { requestParams.put("session_id", midjourneyConfig.getSessionId()); requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); requestParams.put("prompt", prompt); - // 设置参数 - String requestBody = MjClient.setParams(requestTemplate, requestParams); + // 解析 template 参数占位符 + String requestBody = MjUtil.parseTemplate(requestTemplate, requestParams); + // 获取 header + HttpHeaders httpHeaders = getHttpHeaders(); // 发送请求 - String res = MjClient.post(url, midjourneyConfig, requestBody); + HttpEntity requestEntity = new HttpEntity<>(requestBody, httpHeaders); + String res = restTemplate.postForObject(url, requestEntity, String.class); // 这个 res 只要不返回值,就是成功! boolean isSuccess = StrUtil.isBlank(res); if (isSuccess) { @@ -50,6 +71,8 @@ public class MjInteractions { return isSuccess; } + + public Boolean reRoll(ReRoll reRoll) { // 获取请求模板 String requestTemplate = midjourneyConfig.getRequestTemplates().get("reroll"); @@ -61,10 +84,13 @@ public class MjInteractions { requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); requestParams.put("custom_id", reRoll.getCustomId()); requestParams.put("message_id", reRoll.getMessageId()); + // 获取 header + HttpHeaders httpHeaders = getHttpHeaders(); // 设置参数 - String requestBody = MjClient.setParams(requestTemplate, requestParams); + String requestBody = MjUtil.parseTemplate(requestTemplate, requestParams); // 发送请求 - String res = MjClient.post(url, midjourneyConfig, requestBody); + HttpEntity requestEntity = new HttpEntity<>(requestBody, httpHeaders); + String res = restTemplate.postForObject(url, requestEntity, String.class); // 这个 res 只要不返回值,就是成功! boolean isSuccess = StrUtil.isBlank(res); if (isSuccess) { @@ -73,4 +99,90 @@ public class MjInteractions { log.error("请求失败! 请求参数:{} 返回结果! {}", requestBody, res); return isSuccess; } + + + public UploadAttachmentsRes uploadAttachments(Attachments attachments) { + // file + JSONObject fileObj = new JSONObject(); + fileObj.put("id", "0"); + fileObj.put("filename", attachments.getFileSystemResource().getFilename()); + try { + fileObj.put("file_size", attachments.getFileSystemResource().contentLength()); + } catch (IOException e) { + throw new RuntimeException(e); + } + // 创建用于存放表单数据的MultiValueMap + MultiValueMap multipartRequest = new LinkedMultiValueMap<>(); + multipartRequest.put("files", Lists.newArrayList(fileObj)); + // 设置header值 + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + httpHeaders.set("Authorization", midjourneyConfig.getToken()); + httpHeaders.set("User-Agent", midjourneyConfig.getUserAage()); + httpHeaders.set("Cookie", MjConstants.HTTP_COOKIE); + httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId())); + // 创建HttpEntity对象,包含表单数据和头部信息 + HttpEntity> multiValueMapHttpEntity = new HttpEntity<>(multipartRequest, httpHeaders); + // 发送POST请求并接收响应 + String uri = String.format(midjourneyConfig.getApiAttachments(), midjourneyConfig.getChannelId()); + String response = restTemplate.postForObject(midjourneyConfig.getServerUrl().concat(uri), multiValueMapHttpEntity, String.class); + UploadAttachmentsRes uploadAttachmentsRes = JSON.parseObject(response, UploadAttachmentsRes.class); + + + // + // 上传文件 + String uploadUrl = uploadAttachmentsRes.getAttachments().getFirst().getUploadUrl(); + String uploadAttachmentsUrl = midjourneyConfig.getApiAttachmentsUpload().concat(uploadUrl); + httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); + HttpEntity fileSystemResourceHttpEntity = new HttpEntity<>(attachments.getFileSystemResource(), httpHeaders); + ResponseEntity exchange = restTemplate.exchange(uploadUrl, HttpMethod.PUT, fileSystemResourceHttpEntity, String.class); + String uploadRes = exchange.getBody(); + + return uploadAttachmentsRes; + } + + public Boolean describe(Describe describe) { + // 获取请求模板 + String requestTemplate = midjourneyConfig.getRequestTemplates().get("describe"); + // 设置参数 + HashMap requestParams = Maps.newHashMap(); + requestParams.put("guild_id", midjourneyConfig.getGuildId()); + requestParams.put("channel_id", midjourneyConfig.getChannelId()); + requestParams.put("session_id", midjourneyConfig.getSessionId()); + requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); + requestParams.put("file_name", describe.getFileName()); + requestParams.put("final_file_name", describe.getFinalFileName()); + // 设置 header + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); // 设置内容类型为JSON + httpHeaders.set("Authorization", midjourneyConfig.getToken()); + httpHeaders.set("User-Agent", midjourneyConfig.getUserAage()); + httpHeaders.set("Cookie", MjConstants.HTTP_COOKIE); + httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId())); + String requestBody = MjUtil.parseTemplate(requestTemplate, requestParams); + // 创建表单数据 + MultiValueMap formData = new LinkedMultiValueMap<>(); + formData.add("payload_json", requestBody); + // 发送请求 + HttpEntity> multiValueMapHttpEntity = new HttpEntity<>(formData, httpHeaders); + String res = restTemplate.postForObject(url, multiValueMapHttpEntity, String.class); + // 这个 res 只要不返回值,就是成功! + boolean isSuccess = StrUtil.isBlank(res); + if (isSuccess) { + return true; + } + log.error("请求失败! 请求参数:{} 返回结果! {}", requestBody, res); + return isSuccess; + } + + @NotNull + private HttpHeaders getHttpHeaders() { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); // 设置内容类型为JSON + httpHeaders.set("Authorization", midjourneyConfig.getToken()); + httpHeaders.set("User-Agent", midjourneyConfig.getUserAage()); + httpHeaders.set("Cookie", MjConstants.HTTP_COOKIE); + httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId())); + return httpHeaders; + } } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/util/MjUtil.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/util/MjUtil.java index 4e04e69dc..751a79b04 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/util/MjUtil.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/util/MjUtil.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.ai.midjourney.util; import cn.hutool.core.text.CharSequenceUtil; import cn.iocoder.yudao.framework.ai.midjourney.MjMessage; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -19,7 +20,12 @@ public class MjUtil { public static final String CONTENT_REGEX = ".*?\\*\\*(.*?)\\*\\*.+<@\\d+> \\((.*?)\\)"; public static final String CONTENT_PROGRESS_REGEX = "\\(([^)]*)\\)"; - + /** + * 解析 content 参数 + * + * @param content + * @return + */ public static MjMessage.Content parseContent(String content) { // 有三种格式。 // 南极应该是什么样子? @@ -61,4 +67,17 @@ public class MjUtil { return mjContent; } + /** + * 设置 params + * + * @param requestTemplate + * @param requestParams + * @return + */ + public static String parseTemplate(String requestTemplate, Map requestParams) { + for (Map.Entry entry : requestParams.entrySet()) { + requestTemplate = requestTemplate.replace("$".concat(entry.getKey()), entry.getValue()); + } + return requestTemplate; + } } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/Attachments.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/Attachments.java new file mode 100644 index 000000000..133a7031f --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/Attachments.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.framework.ai.midjourney.vo; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.core.io.FileSystemResource; + +/** + * 附件 + *

+ * author: fansili + * time: 2024/4/7 17:18 + */ +@Data +@Accessors(chain = true) +public class Attachments { + + /** + * 创建文件系统资源对象 + */ + private FileSystemResource fileSystemResource; + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/Describe.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/Describe.java new file mode 100644 index 000000000..6517f7b86 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/Describe.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.framework.ai.midjourney.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.File; + +/** + * describe + * + * author: fansili + * time: 2024/4/7 12:30 + */ +@Data +@Accessors(chain = true) +public class Describe { + + /** + * 文件名字 + */ + private String fileName; + /** + * UploadAttachmentsRes 里面的 finalFileName + */ + private String finalFileName; +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/ReRoll.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/ReRoll.java index 2d39ba1df..a28517419 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/ReRoll.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/ReRoll.java @@ -11,6 +11,12 @@ import lombok.experimental.Accessors; @Accessors(chain = true) public class ReRoll { + /** + * socket 消息里面收到的 messageId + */ private String messageId; + /** + * socket 消息里面的,操作按钮id(MJ::JOB::upsample::3::2aeefbef-43e2-4057-bcf1-43b5f39ab6f7) + */ private String customId; } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/UploadAttachmentsRes.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/UploadAttachmentsRes.java new file mode 100644 index 000000000..b06c1c318 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/UploadAttachmentsRes.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.framework.ai.midjourney.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * 上传附件 - res + * + * author: fansili + * time: 2024/4/8 13:32 + */ +@Data +@Accessors(chain = true) +public class UploadAttachmentsRes { + + private List attachments; + + @Data + @Accessors(chain = true) + public static class Attachment { + /** + * 附件的ID。 + */ + private int id; + /** + * 附件的上传URL。 + */ + private String uploadUrl; + /** + * 上传到服务器的文件名。 + */ + private String uploadFilename; + } +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/mj/MjInteractionsTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/mj/MjInteractionsTests.java index 3108b31be..636e9d2d4 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/mj/MjInteractionsTests.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/mj/MjInteractionsTests.java @@ -3,9 +3,14 @@ package cn.iocoder.yudao.framework.ai.mj; import cn.hutool.core.io.FileUtil; import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; import cn.iocoder.yudao.framework.ai.midjourney.interactions.MjInteractions; +import cn.iocoder.yudao.framework.ai.midjourney.vo.Attachments; +import cn.iocoder.yudao.framework.ai.midjourney.vo.Describe; import cn.iocoder.yudao.framework.ai.midjourney.vo.ReRoll; +import cn.iocoder.yudao.framework.ai.midjourney.vo.UploadAttachmentsRes; +import com.alibaba.fastjson.JSON; import org.junit.Before; import org.junit.Test; +import org.springframework.core.io.FileSystemResource; import java.io.File; import java.util.HashMap; @@ -46,4 +51,23 @@ public class MjInteractionsTests { .setMessageId("1226165117448753243") .setCustomId("MJ::JOB::upsample::3::2aeefbef-43e2-4057-bcf1-43b5f39ab6f7")); } + + @Test + public void uploadAttachmentsTest() { + MjInteractions mjImagineInteractions = new MjInteractions(midjourneyConfig); + UploadAttachmentsRes res = mjImagineInteractions.uploadAttachments( + new Attachments().setFileSystemResource( + new FileSystemResource(new File("/Users/fansili/Downloads/DSC01402.JPG"))) + ); + System.err.println(JSON.toJSONString(res)); + } + + @Test + public void describeTest() { + MjInteractions mjImagineInteractions = new MjInteractions(midjourneyConfig); + mjImagineInteractions.describe(new Describe() + .setFileName("DSC01402.JPG") + .setFinalFileName("16826931-2873-45ec-8cfb-0ad81f1a075f/DSC01402.JPG") + ); + } }