Commit 03f124a82b5e2a083c06b39ea44be9c0373e3d36

Authored by cherishsince
1 parent 0e277b71

1、请求公共部分抽离

2、修改为api和spring ai结构保持一致
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/api/MidjourneyInteractions.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.ai.midjourney.api;
  2 +
  3 +import cn.hutool.core.util.IdUtil;
  4 +import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig;
  5 +import cn.iocoder.yudao.framework.ai.midjourney.constants.MidjourneyConstants;
  6 +import com.google.common.collect.Maps;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.http.HttpHeaders;
  9 +import org.springframework.http.MediaType;
  10 +
  11 +import java.util.HashMap;
  12 +
  13 +// TODO @fansili:按照 spring ai 的封装习惯,这个类是不是 MidjourneyApi
  14 +
  15 +/**
  16 + * 图片生成
  17 + *
  18 + * author: fansili
  19 + * time: 2024/4/3 17:36
  20 + */
  21 +@Slf4j
  22 +public abstract class MidjourneyInteractions {
  23 +
  24 + // TODO done @fansili:静态变量,放在最前面哈;
  25 + /**
  26 + * header - referer 头信息
  27 + */
  28 + private static final String HEADER_REFERER = "https://discord.com/channels/%s/%s";
  29 + /**
  30 + * mj配置文件
  31 + */
  32 + protected final MidjourneyConfig midjourneyConfig;
  33 +
  34 + protected MidjourneyInteractions(MidjourneyConfig midjourneyConfig) {
  35 + this.midjourneyConfig = midjourneyConfig;
  36 + }
  37 +
  38 + /**
  39 + * 获取headers - application json
  40 + *
  41 + * @return
  42 + */
  43 + protected HttpHeaders getHeadersOfAppJson() {
  44 + // 设置header值
  45 + HttpHeaders httpHeaders = new HttpHeaders();
  46 + httpHeaders.setContentType(MediaType.APPLICATION_JSON);
  47 + httpHeaders.set("Authorization", midjourneyConfig.getToken());
  48 + httpHeaders.set("User-Agent", midjourneyConfig.getUserAage());
  49 + httpHeaders.set("Cookie", MidjourneyConstants.HTTP_COOKIE);
  50 + httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId()));
  51 + return httpHeaders;
  52 + }
  53 +
  54 + /**
  55 + * 获取headers - http form data
  56 + *
  57 + * @return
  58 + */
  59 + protected HttpHeaders getHeadersOfFormData() {
  60 + // 设置header值
  61 + HttpHeaders httpHeaders = new HttpHeaders();
  62 + httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
  63 + httpHeaders.set("Authorization", midjourneyConfig.getToken());
  64 + httpHeaders.set("User-Agent", midjourneyConfig.getUserAage());
  65 + httpHeaders.set("Cookie", MidjourneyConstants.HTTP_COOKIE);
  66 + httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId()));
  67 + return httpHeaders;
  68 + }
  69 +
  70 + /**
  71 + * 获取 - 默认参数
  72 + * @return
  73 + */
  74 + protected HashMap<String, String> getDefaultParams() {
  75 + HashMap<String, String> requestParams = Maps.newHashMap();
  76 + // TODO @fansili:感觉参数的组装,可以搞成一个公用的方法;就是 config + 入参的感觉;
  77 + requestParams.put("guild_id", midjourneyConfig.getGuildId());
  78 + requestParams.put("channel_id", midjourneyConfig.getChannelId());
  79 + requestParams.put("session_id", midjourneyConfig.getSessionId());
  80 + requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); // TODO @fansili:建议用 uuid 之类的;nextId 跨进程未必合适哈;
  81 + return requestParams;
  82 + }
  83 +}
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/interactions/MidjourneyInteractions.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/api/MidjourneyInteractionsApi.java
1 -package cn.iocoder.yudao.framework.ai.midjourney.interactions; 1 +package cn.iocoder.yudao.framework.ai.midjourney.api;
2 2
3 -import cn.hutool.core.util.IdUtil;  
4 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; 4 import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig;
6 -import cn.iocoder.yudao.framework.ai.midjourney.constants.MidjourneyConstants;  
7 import cn.iocoder.yudao.framework.ai.midjourney.util.MidjourneyUtil; 5 import cn.iocoder.yudao.framework.ai.midjourney.util.MidjourneyUtil;
8 -import cn.iocoder.yudao.framework.ai.midjourney.vo.Attachments;  
9 -import cn.iocoder.yudao.framework.ai.midjourney.vo.Describe;  
10 -import cn.iocoder.yudao.framework.ai.midjourney.vo.ReRoll;  
11 -import cn.iocoder.yudao.framework.ai.midjourney.vo.UploadAttachmentsRes; 6 +import cn.iocoder.yudao.framework.ai.midjourney.api.req.AttachmentsReq;
  7 +import cn.iocoder.yudao.framework.ai.midjourney.api.req.DescribeReq;
  8 +import cn.iocoder.yudao.framework.ai.midjourney.api.req.ReRollReq;
  9 +import cn.iocoder.yudao.framework.ai.midjourney.api.res.UploadAttachmentsRes;
12 import com.alibaba.fastjson.JSON; 10 import com.alibaba.fastjson.JSON;
13 import com.alibaba.fastjson.JSONObject; 11 import com.alibaba.fastjson.JSONObject;
14 import com.google.common.collect.Lists; 12 import com.google.common.collect.Lists;
15 -import com.google.common.collect.Maps;  
16 import lombok.extern.slf4j.Slf4j; 13 import lombok.extern.slf4j.Slf4j;
17 -import org.jetbrains.annotations.NotNull;  
18 import org.springframework.core.io.FileSystemResource; 14 import org.springframework.core.io.FileSystemResource;
19 import org.springframework.http.*; 15 import org.springframework.http.*;
20 import org.springframework.util.LinkedMultiValueMap; 16 import org.springframework.util.LinkedMultiValueMap;
@@ -32,18 +28,13 @@ import java.util.HashMap; @@ -32,18 +28,13 @@ import java.util.HashMap;
32 * time: 2024/4/3 17:36 28 * time: 2024/4/3 17:36
33 */ 29 */
34 @Slf4j 30 @Slf4j
35 -public class MidjourneyInteractions {  
36 -  
37 - // TODO done @fansili:静态变量,放在最前面哈;  
38 - private static final String HEADER_REFERER = "https://discord.com/channels/%s/%s"; 31 +public class MidjourneyInteractionsApi extends MidjourneyInteractions {
39 32
40 private final String url; 33 private final String url;
41 - private final MidjourneyConfig midjourneyConfig;  
42 private final RestTemplate restTemplate = new RestTemplate(); // TODO @fansili:优先级低:后续搞到统一的管理 34 private final RestTemplate restTemplate = new RestTemplate(); // TODO @fansili:优先级低:后续搞到统一的管理
43 35
44 -  
45 - public MidjourneyInteractions(MidjourneyConfig midjourneyConfig) {  
46 - this.midjourneyConfig = midjourneyConfig; 36 + public MidjourneyInteractionsApi(MidjourneyConfig midjourneyConfig) {
  37 + super(midjourneyConfig);
47 this.url = midjourneyConfig.getServerUrl().concat(midjourneyConfig.getApiInteractions()); 38 this.url = midjourneyConfig.getServerUrl().concat(midjourneyConfig.getApiInteractions());
48 } 39 }
49 40
@@ -51,17 +42,12 @@ public class MidjourneyInteractions { @@ -51,17 +42,12 @@ public class MidjourneyInteractions {
51 // 获取请求模板 42 // 获取请求模板
52 String requestTemplate = midjourneyConfig.getRequestTemplates().get("imagine"); 43 String requestTemplate = midjourneyConfig.getRequestTemplates().get("imagine");
53 // 设置参数 44 // 设置参数
54 - HashMap<String, String> requestParams = Maps.newHashMap();  
55 - // TODO @fansili:感觉参数的组装,可以搞成一个公用的方法;就是 config + 入参的感觉;  
56 - requestParams.put("guild_id", midjourneyConfig.getGuildId());  
57 - requestParams.put("channel_id", midjourneyConfig.getChannelId());  
58 - requestParams.put("session_id", midjourneyConfig.getSessionId());  
59 - requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); // TODO @fansili:建议用 uuid 之类的;nextId 跨进程未必合适哈; 45 + HashMap<String, String> requestParams = getDefaultParams();
60 requestParams.put("prompt", prompt); 46 requestParams.put("prompt", prompt);
61 // 解析 template 参数占位符 47 // 解析 template 参数占位符
62 String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams); 48 String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams);
63 // 获取 header 49 // 获取 header
64 - HttpHeaders httpHeaders = getHttpHeaders(); 50 + HttpHeaders httpHeaders = getHeadersOfAppJson();
65 // 发送请求 51 // 发送请求
66 HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, httpHeaders); 52 HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, httpHeaders);
67 String res = restTemplate.postForObject(url, requestEntity, String.class); 53 String res = restTemplate.postForObject(url, requestEntity, String.class);
@@ -77,19 +63,15 @@ public class MidjourneyInteractions { @@ -77,19 +63,15 @@ public class MidjourneyInteractions {
77 // TODO done @fansili:方法和方法之间,空一行哈; 63 // TODO done @fansili:方法和方法之间,空一行哈;
78 64
79 65
80 - public Boolean reRoll(ReRoll reRoll) { 66 + public Boolean reRoll(ReRollReq reRoll) {
81 // 获取请求模板 67 // 获取请求模板
82 String requestTemplate = midjourneyConfig.getRequestTemplates().get("reroll"); 68 String requestTemplate = midjourneyConfig.getRequestTemplates().get("reroll");
83 // 设置参数 69 // 设置参数
84 - HashMap<String, String> requestParams = Maps.newHashMap();  
85 - requestParams.put("guild_id", midjourneyConfig.getGuildId());  
86 - requestParams.put("channel_id", midjourneyConfig.getChannelId());  
87 - requestParams.put("session_id", midjourneyConfig.getSessionId());  
88 - requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); 70 + HashMap<String, String> requestParams = getDefaultParams();
89 requestParams.put("custom_id", reRoll.getCustomId()); 71 requestParams.put("custom_id", reRoll.getCustomId());
90 requestParams.put("message_id", reRoll.getMessageId()); 72 requestParams.put("message_id", reRoll.getMessageId());
91 // 获取 header 73 // 获取 header
92 - HttpHeaders httpHeaders = getHttpHeaders(); 74 + HttpHeaders httpHeaders = getHeadersOfAppJson();
93 // 设置参数 75 // 设置参数
94 String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams); 76 String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams);
95 // 发送请求 77 // 发送请求
@@ -105,7 +87,7 @@ public class MidjourneyInteractions { @@ -105,7 +87,7 @@ public class MidjourneyInteractions {
105 } 87 }
106 88
107 // TODO @fansili:搞成私有方法,可能会好点; 89 // TODO @fansili:搞成私有方法,可能会好点;
108 - public UploadAttachmentsRes uploadAttachments(Attachments attachments) { 90 + public UploadAttachmentsRes uploadAttachments(AttachmentsReq attachments) {
109 // file 91 // file
110 JSONObject fileObj = new JSONObject(); 92 JSONObject fileObj = new JSONObject();
111 fileObj.put("id", "0"); 93 fileObj.put("id", "0");
@@ -120,13 +102,7 @@ public class MidjourneyInteractions { @@ -120,13 +102,7 @@ public class MidjourneyInteractions {
120 MultiValueMap<String, Object> multipartRequest = new LinkedMultiValueMap<>(); 102 MultiValueMap<String, Object> multipartRequest = new LinkedMultiValueMap<>();
121 multipartRequest.put("files", Lists.newArrayList(fileObj)); 103 multipartRequest.put("files", Lists.newArrayList(fileObj));
122 // 设置header值 104 // 设置header值
123 - HttpHeaders httpHeaders = new HttpHeaders();  
124 - // TODO @fansili:通用的 header 构建,抽一个方法哈;  
125 - httpHeaders.setContentType(MediaType.APPLICATION_JSON);  
126 - httpHeaders.set("Authorization", midjourneyConfig.getToken());  
127 - httpHeaders.set("User-Agent", midjourneyConfig.getUserAage());  
128 - httpHeaders.set("Cookie", MidjourneyConstants.HTTP_COOKIE);  
129 - httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId())); 105 + HttpHeaders httpHeaders = getHeadersOfAppJson();
130 // 创建HttpEntity对象,包含表单数据和头部信息 106 // 创建HttpEntity对象,包含表单数据和头部信息
131 HttpEntity<MultiValueMap<String, Object>> multiValueMapHttpEntity = new HttpEntity<>(multipartRequest, httpHeaders); 107 HttpEntity<MultiValueMap<String, Object>> multiValueMapHttpEntity = new HttpEntity<>(multipartRequest, httpHeaders);
132 // 发送POST请求并接收响应 108 // 发送POST请求并接收响应
@@ -144,24 +120,15 @@ public class MidjourneyInteractions { @@ -144,24 +120,15 @@ public class MidjourneyInteractions {
144 return uploadAttachmentsRes; 120 return uploadAttachmentsRes;
145 } 121 }
146 122
147 - public Boolean describe(Describe describe) { 123 + public Boolean describe(DescribeReq describe) {
148 // 获取请求模板 124 // 获取请求模板
149 String requestTemplate = midjourneyConfig.getRequestTemplates().get("describe"); 125 String requestTemplate = midjourneyConfig.getRequestTemplates().get("describe");
150 // 设置参数 126 // 设置参数
151 - HashMap<String, String> requestParams = Maps.newHashMap();  
152 - requestParams.put("guild_id", midjourneyConfig.getGuildId());  
153 - requestParams.put("channel_id", midjourneyConfig.getChannelId());  
154 - requestParams.put("session_id", midjourneyConfig.getSessionId());  
155 - requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); 127 + HashMap<String, String> requestParams = getDefaultParams();
156 requestParams.put("file_name", describe.getFileName()); 128 requestParams.put("file_name", describe.getFileName());
157 requestParams.put("final_file_name", describe.getFinalFileName()); 129 requestParams.put("final_file_name", describe.getFinalFileName());
158 // 设置 header 130 // 设置 header
159 - HttpHeaders httpHeaders = new HttpHeaders();  
160 - httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); // 设置内容类型为JSON  
161 - httpHeaders.set("Authorization", midjourneyConfig.getToken());  
162 - httpHeaders.set("User-Agent", midjourneyConfig.getUserAage());  
163 - httpHeaders.set("Cookie", MidjourneyConstants.HTTP_COOKIE);  
164 - httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId())); 131 + HttpHeaders httpHeaders = getHeadersOfFormData();
165 String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams); 132 String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams);
166 // 创建表单数据 133 // 创建表单数据
167 MultiValueMap<String, String> formData = new LinkedMultiValueMap<>(); 134 MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
@@ -178,15 +145,4 @@ public class MidjourneyInteractions { @@ -178,15 +145,4 @@ public class MidjourneyInteractions {
178 return isSuccess; 145 return isSuccess;
179 } 146 }
180 147
181 - @NotNull  
182 - private HttpHeaders getHttpHeaders() {  
183 - HttpHeaders httpHeaders = new HttpHeaders();  
184 - httpHeaders.setContentType(MediaType.APPLICATION_JSON); // 设置内容类型为JSON  
185 - httpHeaders.set("Authorization", midjourneyConfig.getToken());  
186 - httpHeaders.set("User-Agent", midjourneyConfig.getUserAage());  
187 - httpHeaders.set("Cookie", MidjourneyConstants.HTTP_COOKIE);  
188 - httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId()));  
189 - return httpHeaders;  
190 - }  
191 -  
192 } 148 }