Commit c29430e7542147b46a5c5be6dda050e80e9448ae
Merge branch 'master-jdk21-ai' of https://gitee.com/cherishsince/ruoyi-vue-pro into master-jdk21-ai
Showing
33 changed files
with
290 additions
and
341 deletions
yudao-dependencies/pom.xml
| @@ -628,15 +628,6 @@ | @@ -628,15 +628,6 @@ | ||
| 628 | <artifactId>ureport2-console</artifactId> | 628 | <artifactId>ureport2-console</artifactId> |
| 629 | <version>${ureport2.version}</version> | 629 | <version>${ureport2.version}</version> |
| 630 | </dependency> | 630 | </dependency> |
| 631 | - | ||
| 632 | - <!-- 添加ai模块 --> | ||
| 633 | - <dependency> | ||
| 634 | - <groupId>org.springframework.ai</groupId> | ||
| 635 | - <artifactId>spring-ai-bom</artifactId> | ||
| 636 | - <version>${spring-ai-bom.version}</version> | ||
| 637 | - <type>pom</type> | ||
| 638 | - <scope>import</scope> | ||
| 639 | - </dependency> | ||
| 640 | </dependencies> | 631 | </dependencies> |
| 641 | </dependencyManagement> | 632 | </dependencyManagement> |
| 642 | 633 |
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/ErrorCodeConstants.java
| @@ -11,6 +11,7 @@ public interface ErrorCodeConstants { | @@ -11,6 +11,7 @@ public interface ErrorCodeConstants { | ||
| 11 | 11 | ||
| 12 | // ========== 模块 ai 错误码区间 [1-022-000-000 ~ 1-023-000-000) ========== | 12 | // ========== 模块 ai 错误码区间 [1-022-000-000 ~ 1-023-000-000) ========== |
| 13 | 13 | ||
| 14 | + // TODO @fansili:1)类注释不太对;2)中英文之间,有个空格;例如说 AI 模型 | ||
| 14 | ErrorCode AI_MODULE_NOT_SUPPORTED = new ErrorCode(1_022_000_000, "AI模型暂不支持!"); | 15 | ErrorCode AI_MODULE_NOT_SUPPORTED = new ErrorCode(1_022_000_000, "AI模型暂不支持!"); |
| 15 | 16 | ||
| 16 | } | 17 | } |
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/AiModelEnum.java deleted
| 1 | -package cn.iocoder.yudao.module.ai.enums; | ||
| 2 | - | ||
| 3 | -import lombok.Getter; | ||
| 4 | - | ||
| 5 | -/** | ||
| 6 | - * author: fansili | ||
| 7 | - * time: 2024/3/4 12:36 | ||
| 8 | - */ | ||
| 9 | -@Getter | ||
| 10 | -public enum AiModelEnum { | ||
| 11 | - | ||
| 12 | - OPEN_AI_GPT_3_5("gpt-3.5-turbo", "GPT3.5"), | ||
| 13 | - OPEN_AI_GPT_4("gpt-4-turbo", "GPT4") | ||
| 14 | - | ||
| 15 | - ; | ||
| 16 | - | ||
| 17 | - AiModelEnum(String value, String message) { | ||
| 18 | - this.value = value; | ||
| 19 | - this.message = message; | ||
| 20 | - } | ||
| 21 | - | ||
| 22 | - private String value; | ||
| 23 | - | ||
| 24 | - private String message; | ||
| 25 | -} |
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/OpenAiModelEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.ai.enums; | ||
| 2 | + | ||
| 3 | +import lombok.AllArgsConstructor; | ||
| 4 | +import lombok.Getter; | ||
| 5 | + | ||
| 6 | +// TODO done @fansili:1)类注释要加下;2)author 和 time 用 javadoc,@author 和 @since;3)@AllArgsConstructor 使用这个注解,去掉构造方法;4)value 改成 model 字段,然后注释都写下哈;5)message 改成 name,然后注释都写下哈 | ||
| 7 | +/** | ||
| 8 | + * @author: fansili | ||
| 9 | + * @time: 2024/3/4 12:36 | ||
| 10 | + */ | ||
| 11 | +@Getter | ||
| 12 | +@AllArgsConstructor | ||
| 13 | +public enum OpenAiModelEnum { | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * open ai 3.5模型 | ||
| 17 | + */ | ||
| 18 | + OPEN_AI_GPT_3_5("gpt-3.5-turbo", "GPT3.5"), | ||
| 19 | + /** | ||
| 20 | + * open ai 4.0 收费模型 | ||
| 21 | + */ | ||
| 22 | + OPEN_AI_GPT_4("gpt-4-turbo", "GPT4") | ||
| 23 | + | ||
| 24 | + ; | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 模型 - 用于参数传递 | ||
| 28 | + */ | ||
| 29 | + private String model; | ||
| 30 | + /** | ||
| 31 | + * 模型名字 - 用于展示 | ||
| 32 | + */ | ||
| 33 | + private String name; | ||
| 34 | + | ||
| 35 | +} |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/ChatController.java
| @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | ||
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | import cn.iocoder.yudao.module.ai.ErrorCodeConstants; | 5 | import cn.iocoder.yudao.module.ai.ErrorCodeConstants; |
| 6 | import cn.iocoder.yudao.module.ai.controller.admin.vo.AiChatReqVO; | 6 | import cn.iocoder.yudao.module.ai.controller.admin.vo.AiChatReqVO; |
| 7 | -import cn.iocoder.yudao.module.ai.enums.AiModelEnum; | 7 | +import cn.iocoder.yudao.module.ai.enums.OpenAiModelEnum; |
| 8 | import io.swagger.v3.oas.annotations.Operation; | 8 | import io.swagger.v3.oas.annotations.Operation; |
| 9 | import io.swagger.v3.oas.annotations.tags.Tag; | 9 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 10 | import jakarta.servlet.http.HttpServletResponse; | 10 | import jakarta.servlet.http.HttpServletResponse; |
| @@ -13,7 +13,6 @@ import org.springframework.ai.chat.ChatClient; | @@ -13,7 +13,6 @@ import org.springframework.ai.chat.ChatClient; | ||
| 13 | import org.springframework.ai.chat.ChatResponse; | 13 | import org.springframework.ai.chat.ChatResponse; |
| 14 | import org.springframework.ai.chat.prompt.Prompt; | 14 | import org.springframework.ai.chat.prompt.Prompt; |
| 15 | import org.springframework.ai.openai.OpenAiChatClient; | 15 | import org.springframework.ai.openai.OpenAiChatClient; |
| 16 | -import org.springframework.ai.openai.api.OpenAiApi; | ||
| 17 | import org.springframework.beans.factory.annotation.Autowired; | 16 | import org.springframework.beans.factory.annotation.Autowired; |
| 18 | import org.springframework.context.ApplicationContext; | 17 | import org.springframework.context.ApplicationContext; |
| 19 | import org.springframework.validation.annotation.Validated; | 18 | import org.springframework.validation.annotation.Validated; |
| @@ -23,15 +22,9 @@ import org.springframework.web.bind.annotation.RequestMapping; | @@ -23,15 +22,9 @@ import org.springframework.web.bind.annotation.RequestMapping; | ||
| 23 | import org.springframework.web.bind.annotation.RestController; | 22 | import org.springframework.web.bind.annotation.RestController; |
| 24 | import reactor.core.publisher.Flux; | 23 | import reactor.core.publisher.Flux; |
| 25 | 24 | ||
| 26 | -import java.util.Scanner; | ||
| 27 | import java.util.function.Consumer; | 25 | import java.util.function.Consumer; |
| 28 | 26 | ||
| 29 | -/** | ||
| 30 | - * AI模块 | ||
| 31 | - * | ||
| 32 | - * author: fansili | ||
| 33 | - * time: 2024/3/3 20:28 | ||
| 34 | - */ | 27 | +// TODO done @fansili:有了 swagger 注释,就不用类注释了 |
| 35 | @Tag(name = "AI模块") | 28 | @Tag(name = "AI模块") |
| 36 | @RestController | 29 | @RestController |
| 37 | @RequestMapping("/ai-api") | 30 | @RequestMapping("/ai-api") |
| @@ -47,7 +40,7 @@ public class ChatController { | @@ -47,7 +40,7 @@ public class ChatController { | ||
| 47 | ChatClient chatClient = getChatClient(reqVO.getAiModel()); | 40 | ChatClient chatClient = getChatClient(reqVO.getAiModel()); |
| 48 | String res; | 41 | String res; |
| 49 | try { | 42 | try { |
| 50 | - res = chatClient.call(reqVO.getInputText()); | 43 | + res = chatClient.call(reqVO.getPrompt()); |
| 51 | } catch (Exception e) { | 44 | } catch (Exception e) { |
| 52 | res = e.getMessage(); | 45 | res = e.getMessage(); |
| 53 | } | 46 | } |
| @@ -58,33 +51,14 @@ public class ChatController { | @@ -58,33 +51,14 @@ public class ChatController { | ||
| 58 | @Operation(summary = "对话聊天chatStream", description = "简单的ai聊天") | 51 | @Operation(summary = "对话聊天chatStream", description = "简单的ai聊天") |
| 59 | public CommonResult chatStream(HttpServletResponse response, @RequestBody @Validated AiChatReqVO reqVO) throws InterruptedException { | 52 | public CommonResult chatStream(HttpServletResponse response, @RequestBody @Validated AiChatReqVO reqVO) throws InterruptedException { |
| 60 | OpenAiChatClient chatClient = applicationContext.getBean(OpenAiChatClient.class); | 53 | OpenAiChatClient chatClient = applicationContext.getBean(OpenAiChatClient.class); |
| 61 | - Flux<ChatResponse> chatResponse = chatClient.stream(new Prompt(reqVO.getInputText())); | 54 | + Flux<ChatResponse> chatResponse = chatClient.stream(new Prompt(reqVO.getPrompt())); |
| 62 | chatResponse.subscribe(new Consumer<ChatResponse>() { | 55 | chatResponse.subscribe(new Consumer<ChatResponse>() { |
| 63 | @Override | 56 | @Override |
| 64 | public void accept(ChatResponse chatResponse) { | 57 | public void accept(ChatResponse chatResponse) { |
| 65 | System.err.println(chatResponse.getResults().get(0).getOutput().getContent()); | 58 | System.err.println(chatResponse.getResults().get(0).getOutput().getContent()); |
| 66 | } | 59 | } |
| 67 | }); | 60 | }); |
| 68 | - return CommonResult.success("1"); | ||
| 69 | - } | ||
| 70 | - | ||
| 71 | - public static void main(String[] args) { | ||
| 72 | - OpenAiChatClient openAiChatClient = new OpenAiChatClient(new OpenAiApi("openkey")); | ||
| 73 | - Flux<ChatResponse> responseFlux = openAiChatClient.stream(new Prompt("最好的编程语言!")); | ||
| 74 | - long now = System.currentTimeMillis(); | ||
| 75 | - responseFlux.subscribe(new Consumer<ChatResponse>() { | ||
| 76 | - @Override | ||
| 77 | - public void accept(ChatResponse chatResponse) { | ||
| 78 | - if (chatResponse.getResults().get(0).getOutput() == null) { | ||
| 79 | - return; | ||
| 80 | - } | ||
| 81 | - System.err.println(chatResponse.getResults().get(0).getOutput().getContent()); | ||
| 82 | - } | ||
| 83 | - }); | ||
| 84 | - | ||
| 85 | - // 阻止退出 | ||
| 86 | - Scanner scanner = new Scanner(System.in); | ||
| 87 | - scanner.nextLine(); | 61 | + return CommonResult.success(null); |
| 88 | } | 62 | } |
| 89 | 63 | ||
| 90 | /** | 64 | /** |
| @@ -93,8 +67,8 @@ public class ChatController { | @@ -93,8 +67,8 @@ public class ChatController { | ||
| 93 | * @param aiModelEnum | 67 | * @param aiModelEnum |
| 94 | * @return | 68 | * @return |
| 95 | */ | 69 | */ |
| 96 | - private ChatClient getChatClient(AiModelEnum aiModelEnum) { | ||
| 97 | - if (AiModelEnum.OPEN_AI_GPT_3_5 == aiModelEnum) { | 70 | + private ChatClient getChatClient(OpenAiModelEnum aiModelEnum) { |
| 71 | + if (OpenAiModelEnum.OPEN_AI_GPT_3_5 == aiModelEnum) { | ||
| 98 | return applicationContext.getBean(OpenAiChatClient.class); | 72 | return applicationContext.getBean(OpenAiChatClient.class); |
| 99 | } | 73 | } |
| 100 | // AI模型暂不支持 | 74 | // AI模型暂不支持 |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/vo/AiChatReqVO.java
| 1 | package cn.iocoder.yudao.module.ai.controller.admin.vo; | 1 | package cn.iocoder.yudao.module.ai.controller.admin.vo; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.ai.enums.AiModelEnum; | 3 | +import cn.iocoder.yudao.module.ai.enums.OpenAiModelEnum; |
| 4 | import io.swagger.v3.oas.annotations.media.Schema; | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | import jakarta.validation.constraints.NotNull; | 5 | import jakarta.validation.constraints.NotNull; |
| 6 | import lombok.Data; | 6 | import lombok.Data; |
| 7 | 7 | ||
| 8 | -/** | ||
| 9 | - * ai 聊天 req | ||
| 10 | - * | ||
| 11 | - * author: fansili | ||
| 12 | - * time: 2024/3/4 12:33 | ||
| 13 | - */ | ||
| 14 | -@Schema(description = "用户 App - 上传文件 Request VO") | 8 | +// TODO done @fansili 1)swagger 注释不太对;2)有了 swagger 注释,就不用类注释了 |
| 15 | @Data | 9 | @Data |
| 10 | +@Schema(description = "用户 App - 上传文件 Request VO") | ||
| 16 | public class AiChatReqVO { | 11 | public class AiChatReqVO { |
| 17 | 12 | ||
| 18 | - @Schema(description = "输入内容", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 19 | - @NotNull(message = "输入内容不能为空") | ||
| 20 | - private String inputText; | 13 | + @Schema(description = "提示词", requiredMode = Schema.RequiredMode.REQUIRED) |
| 14 | + @NotNull(message = "提示词不能为空!") | ||
| 15 | + private String prompt; | ||
| 21 | 16 | ||
| 22 | @Schema(description = "AI模型", requiredMode = Schema.RequiredMode.REQUIRED) | 17 | @Schema(description = "AI模型", requiredMode = Schema.RequiredMode.REQUIRED) |
| 23 | @NotNull(message = "AI模型不能为空") | 18 | @NotNull(message = "AI模型不能为空") |
| 24 | - private AiModelEnum aiModel; | 19 | + private OpenAiModelEnum aiModel; |
| 25 | 20 | ||
| 26 | } | 21 | } |
yudao-module-ai/yudao-module-ai-biz/src/main/resources/application.properties
yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml
| @@ -149,6 +149,10 @@ | @@ -149,6 +149,10 @@ | ||
| 149 | <!-- </exclusion>--> | 149 | <!-- </exclusion>--> |
| 150 | <!-- </exclusions>--> | 150 | <!-- </exclusions>--> |
| 151 | </dependency> | 151 | </dependency> |
| 152 | + <dependency> | ||
| 153 | + <groupId>cn.iocoder.boot</groupId> | ||
| 154 | + <artifactId>yudao-common</artifactId> | ||
| 155 | + </dependency> | ||
| 152 | </dependencies> | 156 | </dependencies> |
| 153 | 157 | ||
| 154 | </project> | 158 | </project> |
| 155 | \ No newline at end of file | 159 | \ No newline at end of file |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenChatClient.java
| @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.ai.chat.*; | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.ai.chat.*; | ||
| 6 | import cn.iocoder.yudao.framework.ai.chat.messages.MessageType; | 6 | import cn.iocoder.yudao.framework.ai.chat.messages.MessageType; |
| 7 | import cn.iocoder.yudao.framework.ai.chat.prompt.ChatOptions; | 7 | import cn.iocoder.yudao.framework.ai.chat.prompt.ChatOptions; |
| 8 | import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; | 8 | import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; |
| 9 | +import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenApi; | ||
| 9 | import cn.iocoder.yudao.framework.ai.chatyiyan.exception.YiYanApiException; | 10 | import cn.iocoder.yudao.framework.ai.chatyiyan.exception.YiYanApiException; |
| 10 | import com.aliyun.broadscope.bailian.sdk.models.*; | 11 | import com.aliyun.broadscope.bailian.sdk.models.*; |
| 11 | import lombok.extern.slf4j.Slf4j; | 12 | import lombok.extern.slf4j.Slf4j; |
| @@ -29,7 +30,7 @@ import java.util.stream.Collectors; | @@ -29,7 +30,7 @@ import java.util.stream.Collectors; | ||
| 29 | * time: 2024/3/13 21:06 | 30 | * time: 2024/3/13 21:06 |
| 30 | */ | 31 | */ |
| 31 | @Slf4j | 32 | @Slf4j |
| 32 | -public class QianWenChatClient implements ChatClient, StreamingChatClient { | 33 | +public class QianWenChatClient implements ChatClient, StreamingChatClient { |
| 33 | 34 | ||
| 34 | private QianWenApi qianWenApi; | 35 | private QianWenApi qianWenApi; |
| 35 | 36 | ||
| @@ -44,6 +45,7 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient { | @@ -44,6 +45,7 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient { | ||
| 44 | this.qianWenOptions = qianWenOptions; | 45 | this.qianWenOptions = qianWenOptions; |
| 45 | } | 46 | } |
| 46 | 47 | ||
| 48 | + // TODO @fansili:看看咋公用出来,允许传入类似异常之类的参数; | ||
| 47 | public final RetryTemplate retryTemplate = RetryTemplate.builder() | 49 | public final RetryTemplate retryTemplate = RetryTemplate.builder() |
| 48 | // 最大重试次数 10 | 50 | // 最大重试次数 10 |
| 49 | .maxAttempts(10) | 51 | .maxAttempts(10) |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenApi.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenApi.java
| 1 | -package cn.iocoder.yudao.framework.ai.chatqianwen; | 1 | +package cn.iocoder.yudao.framework.ai.chatqianwen.api; |
| 2 | 2 | ||
| 3 | import com.aliyun.broadscope.bailian.sdk.AccessTokenClient; | 3 | import com.aliyun.broadscope.bailian.sdk.AccessTokenClient; |
| 4 | import com.aliyun.broadscope.bailian.sdk.ApplicationClient; | 4 | import com.aliyun.broadscope.bailian.sdk.ApplicationClient; |
| @@ -9,6 +9,7 @@ import org.springframework.http.HttpStatusCode; | @@ -9,6 +9,7 @@ import org.springframework.http.HttpStatusCode; | ||
| 9 | import org.springframework.http.ResponseEntity; | 9 | import org.springframework.http.ResponseEntity; |
| 10 | import reactor.core.publisher.Flux; | 10 | import reactor.core.publisher.Flux; |
| 11 | 11 | ||
| 12 | +// TODO done @fansili:是不是挪到 api 包里?按照 spring ai 的结构;根目录只放 client 和 options | ||
| 12 | /** | 13 | /** |
| 13 | * 阿里 通义千问 | 14 | * 阿里 通义千问 |
| 14 | * | 15 | * |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/imageopenai/OpenAiImageApi.java
| @@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.ai.imageopenai; | @@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.ai.imageopenai; | ||
| 3 | import cn.hutool.json.JSONUtil; | 3 | import cn.hutool.json.JSONUtil; |
| 4 | import cn.iocoder.yudao.framework.ai.imageopenai.api.OpenAiImageRequest; | 4 | import cn.iocoder.yudao.framework.ai.imageopenai.api.OpenAiImageRequest; |
| 5 | import cn.iocoder.yudao.framework.ai.imageopenai.api.OpenAiImageResponse; | 5 | import cn.iocoder.yudao.framework.ai.imageopenai.api.OpenAiImageResponse; |
| 6 | -import cn.iocoder.yudao.framework.ai.util.JacksonUtil; | 6 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 7 | import io.netty.channel.ChannelOption; | 7 | import io.netty.channel.ChannelOption; |
| 8 | import lombok.extern.slf4j.Slf4j; | 8 | import lombok.extern.slf4j.Slf4j; |
| 9 | import org.apache.http.HttpEntity; | 9 | import org.apache.http.HttpEntity; |
| @@ -14,7 +14,6 @@ import org.apache.http.impl.client.CloseableHttpClient; | @@ -14,7 +14,6 @@ import org.apache.http.impl.client.CloseableHttpClient; | ||
| 14 | import org.apache.http.impl.client.HttpClients; | 14 | import org.apache.http.impl.client.HttpClients; |
| 15 | import org.apache.http.util.EntityUtils; | 15 | import org.apache.http.util.EntityUtils; |
| 16 | import org.springframework.http.client.reactive.ReactorClientHttpConnector; | 16 | import org.springframework.http.client.reactive.ReactorClientHttpConnector; |
| 17 | -import org.springframework.web.reactive.function.BodyInserters; | ||
| 18 | import org.springframework.web.reactive.function.client.WebClient; | 17 | import org.springframework.web.reactive.function.client.WebClient; |
| 19 | import reactor.netty.http.client.HttpClient; | 18 | import reactor.netty.http.client.HttpClient; |
| 20 | 19 | ||
| @@ -55,7 +54,7 @@ public class OpenAiImageApi { | @@ -55,7 +54,7 @@ public class OpenAiImageApi { | ||
| 55 | httpPost.setURI(URI.create(DEFAULT_BASE_URL.concat("/v1/images/generations"))); | 54 | httpPost.setURI(URI.create(DEFAULT_BASE_URL.concat("/v1/images/generations"))); |
| 56 | httpPost.setHeader("Content-Type", "application/json"); | 55 | httpPost.setHeader("Content-Type", "application/json"); |
| 57 | httpPost.setHeader("Authorization", "Bearer " + apiKey); | 56 | httpPost.setHeader("Authorization", "Bearer " + apiKey); |
| 58 | - httpPost.setEntity(new StringEntity(JacksonUtil.toJson(request), "UTF-8")); | 57 | + httpPost.setEntity(new StringEntity(JsonUtils.toJsonString(request), "UTF-8")); |
| 59 | 58 | ||
| 60 | CloseableHttpResponse response= null; | 59 | CloseableHttpResponse response= null; |
| 61 | try { | 60 | try { |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/MjMessage.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/MidjourneyMessage.java
| 1 | package cn.iocoder.yudao.framework.ai.midjourney; | 1 | package cn.iocoder.yudao.framework.ai.midjourney; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.ai.midjourney.constants.MidjourneyGennerateStatusEnum; | ||
| 3 | import lombok.Data; | 4 | import lombok.Data; |
| 4 | import lombok.experimental.Accessors; | 5 | import lombok.experimental.Accessors; |
| 5 | 6 | ||
| @@ -7,7 +8,7 @@ import java.util.List; | @@ -7,7 +8,7 @@ import java.util.List; | ||
| 7 | 8 | ||
| 8 | @Data | 9 | @Data |
| 9 | @Accessors(chain = true) | 10 | @Accessors(chain = true) |
| 10 | -public class MjMessage { | 11 | +public class MidjourneyMessage { |
| 11 | 12 | ||
| 12 | /** | 13 | /** |
| 13 | * id是一个重要的字段,在同时生成多个的时候,可以区分生成信息 | 14 | * id是一个重要的字段,在同时生成多个的时候,可以区分生成信息 |
| @@ -41,7 +42,7 @@ public class MjMessage { | @@ -41,7 +42,7 @@ public class MjMessage { | ||
| 41 | * 1、等待 | 42 | * 1、等待 |
| 42 | * 2、进行中 | 43 | * 2、进行中 |
| 43 | * 3、完成 | 44 | * 3、完成 |
| 44 | - * {@link cn.iocoder.yudao.framework.ai.midjourney.constants.MjGennerateStatusEnum} | 45 | + * {@link MidjourneyGennerateStatusEnum} |
| 45 | */ | 46 | */ |
| 46 | private String generateStatus; | 47 | private String generateStatus; |
| 47 | 48 |
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/MjInteractions.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.MjConstants; | ||
| 7 | -import cn.iocoder.yudao.framework.ai.midjourney.util.MjUtil; | ||
| 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; | 5 | +import cn.iocoder.yudao.framework.ai.midjourney.util.MidjourneyUtil; |
| 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; |
| @@ -24,6 +20,7 @@ import org.springframework.web.client.RestTemplate; | @@ -24,6 +20,7 @@ import org.springframework.web.client.RestTemplate; | ||
| 24 | import java.io.IOException; | 20 | import java.io.IOException; |
| 25 | import java.util.HashMap; | 21 | import java.util.HashMap; |
| 26 | 22 | ||
| 23 | +// TODO @fansili:按照 spring ai 的封装习惯,这个类是不是 MidjourneyApi | ||
| 27 | /** | 24 | /** |
| 28 | * 图片生成 | 25 | * 图片生成 |
| 29 | * | 26 | * |
| @@ -31,17 +28,13 @@ import java.util.HashMap; | @@ -31,17 +28,13 @@ import java.util.HashMap; | ||
| 31 | * time: 2024/4/3 17:36 | 28 | * time: 2024/4/3 17:36 |
| 32 | */ | 29 | */ |
| 33 | @Slf4j | 30 | @Slf4j |
| 34 | -public class MjInteractions { | ||
| 35 | - | 31 | +public class MidjourneyInteractionsApi extends MidjourneyInteractions { |
| 36 | 32 | ||
| 37 | private final String url; | 33 | private final String url; |
| 38 | - private final MidjourneyConfig midjourneyConfig; | ||
| 39 | - private final RestTemplate restTemplate = new RestTemplate(); | ||
| 40 | - private static final String HEADER_REFERER = "https://discord.com/channels/%s/%s"; | ||
| 41 | - | 34 | + private final RestTemplate restTemplate = new RestTemplate(); // TODO @fansili:优先级低:后续搞到统一的管理 |
| 42 | 35 | ||
| 43 | - public MjInteractions(MidjourneyConfig midjourneyConfig) { | ||
| 44 | - this.midjourneyConfig = midjourneyConfig; | 36 | + public MidjourneyInteractionsApi(MidjourneyConfig midjourneyConfig) { |
| 37 | + super(midjourneyConfig); | ||
| 45 | this.url = midjourneyConfig.getServerUrl().concat(midjourneyConfig.getApiInteractions()); | 38 | this.url = midjourneyConfig.getServerUrl().concat(midjourneyConfig.getApiInteractions()); |
| 46 | } | 39 | } |
| 47 | 40 | ||
| @@ -49,45 +42,38 @@ public class MjInteractions { | @@ -49,45 +42,38 @@ public class MjInteractions { | ||
| 49 | // 获取请求模板 | 42 | // 获取请求模板 |
| 50 | String requestTemplate = midjourneyConfig.getRequestTemplates().get("imagine"); | 43 | String requestTemplate = midjourneyConfig.getRequestTemplates().get("imagine"); |
| 51 | // 设置参数 | 44 | // 设置参数 |
| 52 | - HashMap<String, String> requestParams = Maps.newHashMap(); | ||
| 53 | - requestParams.put("guild_id", midjourneyConfig.getGuildId()); | ||
| 54 | - requestParams.put("channel_id", midjourneyConfig.getChannelId()); | ||
| 55 | - requestParams.put("session_id", midjourneyConfig.getSessionId()); | ||
| 56 | - requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); | 45 | + HashMap<String, String> requestParams = getDefaultParams(); |
| 57 | requestParams.put("prompt", prompt); | 46 | requestParams.put("prompt", prompt); |
| 58 | // 解析 template 参数占位符 | 47 | // 解析 template 参数占位符 |
| 59 | - String requestBody = MjUtil.parseTemplate(requestTemplate, requestParams); | 48 | + String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams); |
| 60 | // 获取 header | 49 | // 获取 header |
| 61 | - HttpHeaders httpHeaders = getHttpHeaders(); | 50 | + HttpHeaders httpHeaders = getHeadersOfAppJson(); |
| 62 | // 发送请求 | 51 | // 发送请求 |
| 63 | HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, httpHeaders); | 52 | HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, httpHeaders); |
| 64 | String res = restTemplate.postForObject(url, requestEntity, String.class); | 53 | String res = restTemplate.postForObject(url, requestEntity, String.class); |
| 65 | // 这个 res 只要不返回值,就是成功! | 54 | // 这个 res 只要不返回值,就是成功! |
| 66 | - boolean isSuccess = StrUtil.isBlank(res); | ||
| 67 | - if (isSuccess) { | 55 | + // TODO @fansili:可以直接 if (StrUtil.isBlank(res)) |
| 56 | + if (StrUtil.isBlank(res)) { | ||
| 68 | return true; | 57 | return true; |
| 58 | + } else { | ||
| 59 | + log.error("请求失败! 请求参数:{} 返回结果! {}", requestBody, res); | ||
| 60 | + return false; | ||
| 69 | } | 61 | } |
| 70 | - log.error("请求失败! 请求参数:{} 返回结果! {}", requestBody, res); | ||
| 71 | - return isSuccess; | ||
| 72 | } | 62 | } |
| 63 | + // TODO done @fansili:方法和方法之间,空一行哈; | ||
| 73 | 64 | ||
| 74 | 65 | ||
| 75 | - | ||
| 76 | - public Boolean reRoll(ReRoll reRoll) { | 66 | + public Boolean reRoll(ReRollReq reRoll) { |
| 77 | // 获取请求模板 | 67 | // 获取请求模板 |
| 78 | String requestTemplate = midjourneyConfig.getRequestTemplates().get("reroll"); | 68 | String requestTemplate = midjourneyConfig.getRequestTemplates().get("reroll"); |
| 79 | // 设置参数 | 69 | // 设置参数 |
| 80 | - HashMap<String, String> requestParams = Maps.newHashMap(); | ||
| 81 | - requestParams.put("guild_id", midjourneyConfig.getGuildId()); | ||
| 82 | - requestParams.put("channel_id", midjourneyConfig.getChannelId()); | ||
| 83 | - requestParams.put("session_id", midjourneyConfig.getSessionId()); | ||
| 84 | - requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); | 70 | + HashMap<String, String> requestParams = getDefaultParams(); |
| 85 | requestParams.put("custom_id", reRoll.getCustomId()); | 71 | requestParams.put("custom_id", reRoll.getCustomId()); |
| 86 | requestParams.put("message_id", reRoll.getMessageId()); | 72 | requestParams.put("message_id", reRoll.getMessageId()); |
| 87 | // 获取 header | 73 | // 获取 header |
| 88 | - HttpHeaders httpHeaders = getHttpHeaders(); | 74 | + HttpHeaders httpHeaders = getHeadersOfAppJson(); |
| 89 | // 设置参数 | 75 | // 设置参数 |
| 90 | - String requestBody = MjUtil.parseTemplate(requestTemplate, requestParams); | 76 | + String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams); |
| 91 | // 发送请求 | 77 | // 发送请求 |
| 92 | HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, httpHeaders); | 78 | HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, httpHeaders); |
| 93 | String res = restTemplate.postForObject(url, requestEntity, String.class); | 79 | String res = restTemplate.postForObject(url, requestEntity, String.class); |
| @@ -100,12 +86,13 @@ public class MjInteractions { | @@ -100,12 +86,13 @@ public class MjInteractions { | ||
| 100 | return isSuccess; | 86 | return isSuccess; |
| 101 | } | 87 | } |
| 102 | 88 | ||
| 103 | - | ||
| 104 | - public UploadAttachmentsRes uploadAttachments(Attachments attachments) { | 89 | + // TODO @fansili:搞成私有方法,可能会好点; |
| 90 | + public UploadAttachmentsRes uploadAttachments(AttachmentsReq attachments) { | ||
| 105 | // file | 91 | // file |
| 106 | JSONObject fileObj = new JSONObject(); | 92 | JSONObject fileObj = new JSONObject(); |
| 107 | fileObj.put("id", "0"); | 93 | fileObj.put("id", "0"); |
| 108 | fileObj.put("filename", attachments.getFileSystemResource().getFilename()); | 94 | fileObj.put("filename", attachments.getFileSystemResource().getFilename()); |
| 95 | + // TODO @fansili:这块用 lombok 哪个异常处理,简化下代码; | ||
| 109 | try { | 96 | try { |
| 110 | fileObj.put("file_size", attachments.getFileSystemResource().contentLength()); | 97 | fileObj.put("file_size", attachments.getFileSystemResource().contentLength()); |
| 111 | } catch (IOException e) { | 98 | } catch (IOException e) { |
| @@ -115,12 +102,7 @@ public class MjInteractions { | @@ -115,12 +102,7 @@ public class MjInteractions { | ||
| 115 | MultiValueMap<String, Object> multipartRequest = new LinkedMultiValueMap<>(); | 102 | MultiValueMap<String, Object> multipartRequest = new LinkedMultiValueMap<>(); |
| 116 | multipartRequest.put("files", Lists.newArrayList(fileObj)); | 103 | multipartRequest.put("files", Lists.newArrayList(fileObj)); |
| 117 | // 设置header值 | 104 | // 设置header值 |
| 118 | - HttpHeaders httpHeaders = new HttpHeaders(); | ||
| 119 | - httpHeaders.setContentType(MediaType.APPLICATION_JSON); | ||
| 120 | - httpHeaders.set("Authorization", midjourneyConfig.getToken()); | ||
| 121 | - httpHeaders.set("User-Agent", midjourneyConfig.getUserAage()); | ||
| 122 | - httpHeaders.set("Cookie", MjConstants.HTTP_COOKIE); | ||
| 123 | - httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId())); | 105 | + HttpHeaders httpHeaders = getHeadersOfAppJson(); |
| 124 | // 创建HttpEntity对象,包含表单数据和头部信息 | 106 | // 创建HttpEntity对象,包含表单数据和头部信息 |
| 125 | HttpEntity<MultiValueMap<String, Object>> multiValueMapHttpEntity = new HttpEntity<>(multipartRequest, httpHeaders); | 107 | HttpEntity<MultiValueMap<String, Object>> multiValueMapHttpEntity = new HttpEntity<>(multipartRequest, httpHeaders); |
| 126 | // 发送POST请求并接收响应 | 108 | // 发送POST请求并接收响应 |
| @@ -128,38 +110,26 @@ public class MjInteractions { | @@ -128,38 +110,26 @@ public class MjInteractions { | ||
| 128 | String response = restTemplate.postForObject(midjourneyConfig.getServerUrl().concat(uri), multiValueMapHttpEntity, String.class); | 110 | String response = restTemplate.postForObject(midjourneyConfig.getServerUrl().concat(uri), multiValueMapHttpEntity, String.class); |
| 129 | UploadAttachmentsRes uploadAttachmentsRes = JSON.parseObject(response, UploadAttachmentsRes.class); | 111 | UploadAttachmentsRes uploadAttachmentsRes = JSON.parseObject(response, UploadAttachmentsRes.class); |
| 130 | 112 | ||
| 131 | - | ||
| 132 | // | 113 | // |
| 133 | // 上传文件 | 114 | // 上传文件 |
| 134 | String uploadUrl = uploadAttachmentsRes.getAttachments().getFirst().getUploadUrl(); | 115 | String uploadUrl = uploadAttachmentsRes.getAttachments().getFirst().getUploadUrl(); |
| 135 | - String uploadAttachmentsUrl = midjourneyConfig.getApiAttachmentsUpload().concat(uploadUrl); | ||
| 136 | httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); | 116 | httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); |
| 137 | HttpEntity<FileSystemResource> fileSystemResourceHttpEntity = new HttpEntity<>(attachments.getFileSystemResource(), httpHeaders); | 117 | HttpEntity<FileSystemResource> fileSystemResourceHttpEntity = new HttpEntity<>(attachments.getFileSystemResource(), httpHeaders); |
| 138 | ResponseEntity<String> exchange = restTemplate.exchange(uploadUrl, HttpMethod.PUT, fileSystemResourceHttpEntity, String.class); | 118 | ResponseEntity<String> exchange = restTemplate.exchange(uploadUrl, HttpMethod.PUT, fileSystemResourceHttpEntity, String.class); |
| 139 | String uploadRes = exchange.getBody(); | 119 | String uploadRes = exchange.getBody(); |
| 140 | - | ||
| 141 | return uploadAttachmentsRes; | 120 | return uploadAttachmentsRes; |
| 142 | } | 121 | } |
| 143 | 122 | ||
| 144 | - public Boolean describe(Describe describe) { | 123 | + public Boolean describe(DescribeReq describe) { |
| 145 | // 获取请求模板 | 124 | // 获取请求模板 |
| 146 | String requestTemplate = midjourneyConfig.getRequestTemplates().get("describe"); | 125 | String requestTemplate = midjourneyConfig.getRequestTemplates().get("describe"); |
| 147 | // 设置参数 | 126 | // 设置参数 |
| 148 | - HashMap<String, String> requestParams = Maps.newHashMap(); | ||
| 149 | - requestParams.put("guild_id", midjourneyConfig.getGuildId()); | ||
| 150 | - requestParams.put("channel_id", midjourneyConfig.getChannelId()); | ||
| 151 | - requestParams.put("session_id", midjourneyConfig.getSessionId()); | ||
| 152 | - requestParams.put("nonce", String.valueOf(IdUtil.getSnowflakeNextId())); | 127 | + HashMap<String, String> requestParams = getDefaultParams(); |
| 153 | requestParams.put("file_name", describe.getFileName()); | 128 | requestParams.put("file_name", describe.getFileName()); |
| 154 | requestParams.put("final_file_name", describe.getFinalFileName()); | 129 | requestParams.put("final_file_name", describe.getFinalFileName()); |
| 155 | // 设置 header | 130 | // 设置 header |
| 156 | - HttpHeaders httpHeaders = new HttpHeaders(); | ||
| 157 | - httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); // 设置内容类型为JSON | ||
| 158 | - httpHeaders.set("Authorization", midjourneyConfig.getToken()); | ||
| 159 | - httpHeaders.set("User-Agent", midjourneyConfig.getUserAage()); | ||
| 160 | - httpHeaders.set("Cookie", MjConstants.HTTP_COOKIE); | ||
| 161 | - httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId())); | ||
| 162 | - String requestBody = MjUtil.parseTemplate(requestTemplate, requestParams); | 131 | + HttpHeaders httpHeaders = getHeadersOfFormData(); |
| 132 | + String requestBody = MidjourneyUtil.parseTemplate(requestTemplate, requestParams); | ||
| 163 | // 创建表单数据 | 133 | // 创建表单数据 |
| 164 | MultiValueMap<String, String> formData = new LinkedMultiValueMap<>(); | 134 | MultiValueMap<String, String> formData = new LinkedMultiValueMap<>(); |
| 165 | formData.add("payload_json", requestBody); | 135 | formData.add("payload_json", requestBody); |
| @@ -175,14 +145,4 @@ public class MjInteractions { | @@ -175,14 +145,4 @@ public class MjInteractions { | ||
| 175 | return isSuccess; | 145 | return isSuccess; |
| 176 | } | 146 | } |
| 177 | 147 | ||
| 178 | - @NotNull | ||
| 179 | - private HttpHeaders getHttpHeaders() { | ||
| 180 | - HttpHeaders httpHeaders = new HttpHeaders(); | ||
| 181 | - httpHeaders.setContentType(MediaType.APPLICATION_JSON); // 设置内容类型为JSON | ||
| 182 | - httpHeaders.set("Authorization", midjourneyConfig.getToken()); | ||
| 183 | - httpHeaders.set("User-Agent", midjourneyConfig.getUserAage()); | ||
| 184 | - httpHeaders.set("Cookie", MjConstants.HTTP_COOKIE); | ||
| 185 | - httpHeaders.set("Referer", String.format(HEADER_REFERER, midjourneyConfig.getGuildId(), midjourneyConfig.getChannelId())); | ||
| 186 | - return httpHeaders; | ||
| 187 | - } | ||
| 188 | } | 148 | } |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/Attachments.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/api/req/AttachmentsReq.java
| 1 | -package cn.iocoder.yudao.framework.ai.midjourney.vo; | 1 | +package cn.iocoder.yudao.framework.ai.midjourney.api.req; |
| 2 | 2 | ||
| 3 | import lombok.Data; | 3 | import lombok.Data; |
| 4 | import lombok.experimental.Accessors; | 4 | import lombok.experimental.Accessors; |
| @@ -12,7 +12,7 @@ import org.springframework.core.io.FileSystemResource; | @@ -12,7 +12,7 @@ import org.springframework.core.io.FileSystemResource; | ||
| 12 | */ | 12 | */ |
| 13 | @Data | 13 | @Data |
| 14 | @Accessors(chain = true) | 14 | @Accessors(chain = true) |
| 15 | -public class Attachments { | 15 | +public class AttachmentsReq { |
| 16 | 16 | ||
| 17 | /** | 17 | /** |
| 18 | * 创建文件系统资源对象 | 18 | * 创建文件系统资源对象 |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/Describe.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/api/req/DescribeReq.java
| 1 | -package cn.iocoder.yudao.framework.ai.midjourney.vo; | 1 | +package cn.iocoder.yudao.framework.ai.midjourney.api.req; |
| 2 | 2 | ||
| 3 | import lombok.Data; | 3 | import lombok.Data; |
| 4 | import lombok.experimental.Accessors; | 4 | import lombok.experimental.Accessors; |
| 5 | 5 | ||
| 6 | -import java.io.File; | ||
| 7 | - | ||
| 8 | /** | 6 | /** |
| 9 | * describe | 7 | * describe |
| 10 | * | 8 | * |
| @@ -13,7 +11,7 @@ import java.io.File; | @@ -13,7 +11,7 @@ import java.io.File; | ||
| 13 | */ | 11 | */ |
| 14 | @Data | 12 | @Data |
| 15 | @Accessors(chain = true) | 13 | @Accessors(chain = true) |
| 16 | -public class Describe { | 14 | +public class DescribeReq { |
| 17 | 15 | ||
| 18 | /** | 16 | /** |
| 19 | * 文件名字 | 17 | * 文件名字 |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/ReRoll.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/api/req/ReRollReq.java
| 1 | -package cn.iocoder.yudao.framework.ai.midjourney.vo; | 1 | +package cn.iocoder.yudao.framework.ai.midjourney.api.req; |
| 2 | 2 | ||
| 3 | import lombok.Data; | 3 | import lombok.Data; |
| 4 | import lombok.experimental.Accessors; | 4 | import lombok.experimental.Accessors; |
| @@ -9,7 +9,7 @@ import lombok.experimental.Accessors; | @@ -9,7 +9,7 @@ import lombok.experimental.Accessors; | ||
| 9 | */ | 9 | */ |
| 10 | @Data | 10 | @Data |
| 11 | @Accessors(chain = true) | 11 | @Accessors(chain = true) |
| 12 | -public class ReRoll { | 12 | +public class ReRollReq { |
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| 15 | * socket 消息里面收到的 messageId | 15 | * socket 消息里面收到的 messageId |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/vo/UploadAttachmentsRes.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/api/res/UploadAttachmentsRes.java
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MjConstants.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MidjourneyConstants.java
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MjGennerateStatusEnum.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MidjourneyGennerateStatusEnum.java
| 1 | package cn.iocoder.yudao.framework.ai.midjourney.constants; | 1 | package cn.iocoder.yudao.framework.ai.midjourney.constants; |
| 2 | 2 | ||
| 3 | +import lombok.AllArgsConstructor; | ||
| 3 | import lombok.Getter; | 4 | import lombok.Getter; |
| 4 | 5 | ||
| 6 | +// TODO done @fansili:1)Mj 缩写,还是搞成全称。。虽然长一点,但是感觉会相对清晰一些哈;2)lombok 相关的注解,可以用用哈;3)value 改 status; | ||
| 5 | /** | 7 | /** |
| 6 | * mj 生成状态 | 8 | * mj 生成状态 |
| 7 | * | 9 | * |
| @@ -9,8 +11,8 @@ import lombok.Getter; | @@ -9,8 +11,8 @@ import lombok.Getter; | ||
| 9 | * time: 2024/4/6 21:07 | 11 | * time: 2024/4/6 21:07 |
| 10 | */ | 12 | */ |
| 11 | @Getter | 13 | @Getter |
| 12 | -public enum MjGennerateStatusEnum { | ||
| 13 | - | 14 | +@AllArgsConstructor |
| 15 | +public enum MidjourneyGennerateStatusEnum { | ||
| 14 | 16 | ||
| 15 | WAITING("waiting", "等待..."), | 17 | WAITING("waiting", "等待..."), |
| 16 | IN_PROGRESS("in_progress", "进行中"), | 18 | IN_PROGRESS("in_progress", "进行中"), |
| @@ -18,12 +20,12 @@ public enum MjGennerateStatusEnum { | @@ -18,12 +20,12 @@ public enum MjGennerateStatusEnum { | ||
| 18 | 20 | ||
| 19 | ; | 21 | ; |
| 20 | 22 | ||
| 21 | - MjGennerateStatusEnum(String value, String message) { | ||
| 22 | - this.value = value; | ||
| 23 | - this.message = message; | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - private String value; | ||
| 27 | - | 23 | + /** |
| 24 | + * 状态 | ||
| 25 | + */ | ||
| 26 | + private String status; | ||
| 27 | + /** | ||
| 28 | + * 状态信息 | ||
| 29 | + */ | ||
| 28 | private String message; | 30 | private String message; |
| 29 | } | 31 | } |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MjInteractionsEnum.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MidjourneyInteractionsEnum.java
| @@ -6,7 +6,7 @@ import lombok.Getter; | @@ -6,7 +6,7 @@ import lombok.Getter; | ||
| 6 | * MJ 命令 | 6 | * MJ 命令 |
| 7 | */ | 7 | */ |
| 8 | @Getter | 8 | @Getter |
| 9 | -public enum MjInteractionsEnum { | 9 | +public enum MidjourneyInteractionsEnum { |
| 10 | 10 | ||
| 11 | IMAGINE("imagine", "生成图片"), | 11 | IMAGINE("imagine", "生成图片"), |
| 12 | DESCRIBE("describe", "生成描述"), | 12 | DESCRIBE("describe", "生成描述"), |
| @@ -17,7 +17,7 @@ public enum MjInteractionsEnum { | @@ -17,7 +17,7 @@ public enum MjInteractionsEnum { | ||
| 17 | 17 | ||
| 18 | ; | 18 | ; |
| 19 | 19 | ||
| 20 | - MjInteractionsEnum(String value, String message) { | 20 | + MidjourneyInteractionsEnum(String value, String message) { |
| 21 | this.value =value; | 21 | this.value =value; |
| 22 | this.message =message; | 22 | this.message =message; |
| 23 | } | 23 | } |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MjMessageTypeEnum.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MidjourneyMessageTypeEnum.java
| 1 | package cn.iocoder.yudao.framework.ai.midjourney.constants; | 1 | package cn.iocoder.yudao.framework.ai.midjourney.constants; |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | -public enum MjMessageTypeEnum { | 4 | +public enum MidjourneyMessageTypeEnum { |
| 5 | /** | 5 | /** |
| 6 | * 创建. | 6 | * 创建. |
| 7 | */ | 7 | */ |
| @@ -15,7 +15,7 @@ public enum MjMessageTypeEnum { | @@ -15,7 +15,7 @@ public enum MjMessageTypeEnum { | ||
| 15 | */ | 15 | */ |
| 16 | DELETE; | 16 | DELETE; |
| 17 | 17 | ||
| 18 | - public static MjMessageTypeEnum of(String type) { | 18 | + public static MidjourneyMessageTypeEnum of(String type) { |
| 19 | return switch (type) { | 19 | return switch (type) { |
| 20 | case "MESSAGE_CREATE" -> CREATE; | 20 | case "MESSAGE_CREATE" -> CREATE; |
| 21 | case "MESSAGE_UPDATE" -> UPDATE; | 21 | case "MESSAGE_UPDATE" -> UPDATE; |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MjNotifyCode.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/constants/MidjourneyNotifyCode.java
| @@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.ai.midjourney.constants; | @@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.ai.midjourney.constants; | ||
| 3 | import lombok.experimental.UtilityClass; | 3 | import lombok.experimental.UtilityClass; |
| 4 | 4 | ||
| 5 | @UtilityClass | 5 | @UtilityClass |
| 6 | -public final class MjNotifyCode { | 6 | +public final class MidjourneyNotifyCode { |
| 7 | /** | 7 | /** |
| 8 | * 成功. | 8 | * 成功. |
| 9 | */ | 9 | */ |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/util/MjUtil.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/util/MidjourneyUtil.java
| 1 | package cn.iocoder.yudao.framework.ai.midjourney.util; | 1 | package cn.iocoder.yudao.framework.ai.midjourney.util; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.text.CharSequenceUtil; | 3 | import cn.hutool.core.text.CharSequenceUtil; |
| 4 | -import cn.iocoder.yudao.framework.ai.midjourney.MjMessage; | 4 | +import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyMessage; |
| 5 | 5 | ||
| 6 | import java.util.Map; | 6 | import java.util.Map; |
| 7 | import java.util.regex.Matcher; | 7 | import java.util.regex.Matcher; |
| @@ -13,7 +13,7 @@ import java.util.regex.Pattern; | @@ -13,7 +13,7 @@ import java.util.regex.Pattern; | ||
| 13 | * author: fansili | 13 | * author: fansili |
| 14 | * time: 2024/4/6 19:00 | 14 | * time: 2024/4/6 19:00 |
| 15 | */ | 15 | */ |
| 16 | -public class MjUtil { | 16 | +public class MidjourneyUtil { |
| 17 | /** | 17 | /** |
| 18 | * content正则匹配prompt和进度. | 18 | * content正则匹配prompt和进度. |
| 19 | */ | 19 | */ |
| @@ -26,12 +26,12 @@ public class MjUtil { | @@ -26,12 +26,12 @@ public class MjUtil { | ||
| 26 | * @param content | 26 | * @param content |
| 27 | * @return | 27 | * @return |
| 28 | */ | 28 | */ |
| 29 | - public static MjMessage.Content parseContent(String content) { | 29 | + public static MidjourneyMessage.Content parseContent(String content) { |
| 30 | // 有三种格式。 | 30 | // 有三种格式。 |
| 31 | // 南极应该是什么样子? | 31 | // 南极应该是什么样子? |
| 32 | // "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (32%) (fast, stealth)", | 32 | // "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (32%) (fast, stealth)", |
| 33 | // "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (fast, stealth)" | 33 | // "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (fast, stealth)" |
| 34 | - MjMessage.Content mjContent = new MjMessage.Content(); | 34 | + MidjourneyMessage.Content mjContent = new MidjourneyMessage.Content(); |
| 35 | if (CharSequenceUtil.isBlank(content)) { | 35 | if (CharSequenceUtil.isBlank(content)) { |
| 36 | return null; | 36 | return null; |
| 37 | } | 37 | } |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/webSocket/MjWebSocketStarter.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/webSocket/MidjourneyWebSocketStarter.java
| @@ -4,9 +4,9 @@ package cn.iocoder.yudao.framework.ai.midjourney.webSocket; | @@ -4,9 +4,9 @@ package cn.iocoder.yudao.framework.ai.midjourney.webSocket; | ||
| 4 | import cn.hutool.core.text.CharSequenceUtil; | 4 | import cn.hutool.core.text.CharSequenceUtil; |
| 5 | import cn.hutool.core.thread.ThreadUtil; | 5 | import cn.hutool.core.thread.ThreadUtil; |
| 6 | import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; | 6 | import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; |
| 7 | -import cn.iocoder.yudao.framework.ai.midjourney.constants.MjNotifyCode; | ||
| 8 | -import cn.iocoder.yudao.framework.ai.midjourney.webSocket.handler.MjWebSocketHandler; | ||
| 9 | -import cn.iocoder.yudao.framework.ai.midjourney.webSocket.listener.MjMessageListener; | 7 | +import cn.iocoder.yudao.framework.ai.midjourney.constants.MidjourneyNotifyCode; |
| 8 | +import cn.iocoder.yudao.framework.ai.midjourney.webSocket.handler.MidjourneyWebSocketHandler; | ||
| 9 | +import cn.iocoder.yudao.framework.ai.midjourney.webSocket.listener.MidjourneyMessageListener; | ||
| 10 | import lombok.Getter; | 10 | import lombok.Getter; |
| 11 | import lombok.extern.slf4j.Slf4j; | 11 | import lombok.extern.slf4j.Slf4j; |
| 12 | import org.apache.tomcat.websocket.Constants; | 12 | import org.apache.tomcat.websocket.Constants; |
| @@ -20,10 +20,10 @@ import org.springframework.web.socket.client.standard.StandardWebSocketClient; | @@ -20,10 +20,10 @@ import org.springframework.web.socket.client.standard.StandardWebSocketClient; | ||
| 20 | 20 | ||
| 21 | import java.io.IOException; | 21 | import java.io.IOException; |
| 22 | import java.net.URI; | 22 | import java.net.URI; |
| 23 | -import java.util.concurrent.TimeoutException; | ||
| 24 | 23 | ||
| 24 | +// TODO @fansili:mj 这块 websocket 有点小复杂,虽然代码量 400 多行;感觉可以考虑,有没第三方 sdk,通过它透明接入 mj | ||
| 25 | @Slf4j | 25 | @Slf4j |
| 26 | -public class MjWebSocketStarter implements WebSocketStarter { | 26 | +public class MidjourneyWebSocketStarter implements WebSocketStarter { |
| 27 | /** | 27 | /** |
| 28 | * 链接重试次数 | 28 | * 链接重试次数 |
| 29 | */ | 29 | */ |
| @@ -35,7 +35,7 @@ public class MjWebSocketStarter implements WebSocketStarter { | @@ -35,7 +35,7 @@ public class MjWebSocketStarter implements WebSocketStarter { | ||
| 35 | /** | 35 | /** |
| 36 | * mj 监听(所有message 都会 callback到这里) | 36 | * mj 监听(所有message 都会 callback到这里) |
| 37 | */ | 37 | */ |
| 38 | - private final MjMessageListener userMessageListener; | 38 | + private final MidjourneyMessageListener userMessageListener; |
| 39 | /** | 39 | /** |
| 40 | * wss 服务器 | 40 | * wss 服务器 |
| 41 | */ | 41 | */ |
| @@ -57,10 +57,10 @@ public class MjWebSocketStarter implements WebSocketStarter { | @@ -57,10 +57,10 @@ public class MjWebSocketStarter implements WebSocketStarter { | ||
| 57 | */ | 57 | */ |
| 58 | private WebSocketSession webSocketSession = null; | 58 | private WebSocketSession webSocketSession = null; |
| 59 | 59 | ||
| 60 | - public MjWebSocketStarter(String wssServer, | ||
| 61 | - String resumeWss, | ||
| 62 | - MidjourneyConfig midjourneyConfig, | ||
| 63 | - MjMessageListener userMessageListener) { | 60 | + public MidjourneyWebSocketStarter(String wssServer, |
| 61 | + String resumeWss, | ||
| 62 | + MidjourneyConfig midjourneyConfig, | ||
| 63 | + MidjourneyMessageListener userMessageListener) { | ||
| 64 | this.wssServer = wssServer; | 64 | this.wssServer = wssServer; |
| 65 | this.resumeWss = resumeWss; | 65 | this.resumeWss = resumeWss; |
| 66 | this.midjourneyConfig = midjourneyConfig; | 66 | this.midjourneyConfig = midjourneyConfig; |
| @@ -82,7 +82,7 @@ public class MjWebSocketStarter implements WebSocketStarter { | @@ -82,7 +82,7 @@ public class MjWebSocketStarter implements WebSocketStarter { | ||
| 82 | headers.add("Sec-Websocket-Extensions", "permessage-deflate; client_max_window_bits"); | 82 | headers.add("Sec-Websocket-Extensions", "permessage-deflate; client_max_window_bits"); |
| 83 | headers.add("User-Agent", this.midjourneyConfig.getUserAage()); | 83 | headers.add("User-Agent", this.midjourneyConfig.getUserAage()); |
| 84 | // 创建 mjHeader | 84 | // 创建 mjHeader |
| 85 | - MjWebSocketHandler mjWebSocketHandler = new MjWebSocketHandler( | 85 | + MidjourneyWebSocketHandler mjWebSocketHandler = new MidjourneyWebSocketHandler( |
| 86 | this.midjourneyConfig, this.userMessageListener, this::onSocketSuccess, this::onSocketFailure); | 86 | this.midjourneyConfig, this.userMessageListener, this::onSocketSuccess, this::onSocketFailure); |
| 87 | // | 87 | // |
| 88 | String gatewayUrl; | 88 | String gatewayUrl; |
| @@ -104,12 +104,12 @@ public class MjWebSocketStarter implements WebSocketStarter { | @@ -104,12 +104,12 @@ public class MjWebSocketStarter implements WebSocketStarter { | ||
| 104 | socketSessionFuture.addCallback(new ListenableFutureCallback<>() { | 104 | socketSessionFuture.addCallback(new ListenableFutureCallback<>() { |
| 105 | @Override | 105 | @Override |
| 106 | public void onFailure(@NotNull Throwable e) { | 106 | public void onFailure(@NotNull Throwable e) { |
| 107 | - onSocketFailure(MjWebSocketHandler.CLOSE_CODE_EXCEPTION, e.getMessage()); | 107 | + onSocketFailure(MidjourneyWebSocketHandler.CLOSE_CODE_EXCEPTION, e.getMessage()); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | @Override | 110 | @Override |
| 111 | public void onSuccess(WebSocketSession session) { | 111 | public void onSuccess(WebSocketSession session) { |
| 112 | - MjWebSocketStarter.this.webSocketSession = session; | 112 | + MidjourneyWebSocketStarter.this.webSocketSession = session; |
| 113 | } | 113 | } |
| 114 | }); | 114 | }); |
| 115 | } | 115 | } |
| @@ -117,7 +117,7 @@ public class MjWebSocketStarter implements WebSocketStarter { | @@ -117,7 +117,7 @@ public class MjWebSocketStarter implements WebSocketStarter { | ||
| 117 | private void onSocketSuccess(String sessionId, Object sequence, String resumeGatewayUrl) { | 117 | private void onSocketSuccess(String sessionId, Object sequence, String resumeGatewayUrl) { |
| 118 | this.resumeData = new ResumeData(sessionId, sequence, resumeGatewayUrl); | 118 | this.resumeData = new ResumeData(sessionId, sequence, resumeGatewayUrl); |
| 119 | this.running = true; | 119 | this.running = true; |
| 120 | - notifyWssLock(MjNotifyCode.SUCCESS, ""); | 120 | + notifyWssLock(MidjourneyNotifyCode.SUCCESS, ""); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | private void onSocketFailure(int code, String reason) { | 123 | private void onSocketFailure(int code, String reason) { |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/webSocket/handler/MjWebSocketHandler.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/webSocket/handler/MidjourneyWebSocketHandler.java
| @@ -8,7 +8,7 @@ import cn.hutool.http.useragent.UserAgentUtil; | @@ -8,7 +8,7 @@ import cn.hutool.http.useragent.UserAgentUtil; | ||
| 8 | import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; | 8 | import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; |
| 9 | import cn.iocoder.yudao.framework.ai.midjourney.webSocket.FailureCallback; | 9 | import cn.iocoder.yudao.framework.ai.midjourney.webSocket.FailureCallback; |
| 10 | import cn.iocoder.yudao.framework.ai.midjourney.webSocket.SuccessCallback; | 10 | import cn.iocoder.yudao.framework.ai.midjourney.webSocket.SuccessCallback; |
| 11 | -import cn.iocoder.yudao.framework.ai.midjourney.webSocket.listener.MjMessageListener; | 11 | +import cn.iocoder.yudao.framework.ai.midjourney.webSocket.listener.MidjourneyMessageListener; |
| 12 | import lombok.Setter; | 12 | import lombok.Setter; |
| 13 | import lombok.extern.slf4j.Slf4j; | 13 | import lombok.extern.slf4j.Slf4j; |
| 14 | import net.dv8tion.jda.api.utils.data.DataArray; | 14 | import net.dv8tion.jda.api.utils.data.DataArray; |
| @@ -29,7 +29,7 @@ import java.util.concurrent.ScheduledExecutorService; | @@ -29,7 +29,7 @@ import java.util.concurrent.ScheduledExecutorService; | ||
| 29 | import java.util.concurrent.TimeUnit; | 29 | import java.util.concurrent.TimeUnit; |
| 30 | 30 | ||
| 31 | @Slf4j | 31 | @Slf4j |
| 32 | -public class MjWebSocketHandler implements WebSocketHandler { | 32 | +public class MidjourneyWebSocketHandler implements WebSocketHandler { |
| 33 | /** | 33 | /** |
| 34 | * close 错误码:重连 | 34 | * close 错误码:重连 |
| 35 | */ | 35 | */ |
| @@ -49,7 +49,7 @@ public class MjWebSocketHandler implements WebSocketHandler { | @@ -49,7 +49,7 @@ public class MjWebSocketHandler implements WebSocketHandler { | ||
| 49 | /** | 49 | /** |
| 50 | * mj 消息监听 | 50 | * mj 消息监听 |
| 51 | */ | 51 | */ |
| 52 | - private final MjMessageListener userMessageListener; | 52 | + private final MidjourneyMessageListener userMessageListener; |
| 53 | /** | 53 | /** |
| 54 | * 成功回调 | 54 | * 成功回调 |
| 55 | */ | 55 | */ |
| @@ -85,10 +85,10 @@ public class MjWebSocketHandler implements WebSocketHandler { | @@ -85,10 +85,10 @@ public class MjWebSocketHandler implements WebSocketHandler { | ||
| 85 | */ | 85 | */ |
| 86 | private final Decompressor decompressor = new ZlibDecompressor(2048); | 86 | private final Decompressor decompressor = new ZlibDecompressor(2048); |
| 87 | 87 | ||
| 88 | - public MjWebSocketHandler(MidjourneyConfig account, | ||
| 89 | - MjMessageListener userMessageListener, | ||
| 90 | - SuccessCallback successCallback, | ||
| 91 | - FailureCallback failureCallback) { | 88 | + public MidjourneyWebSocketHandler(MidjourneyConfig account, |
| 89 | + MidjourneyMessageListener userMessageListener, | ||
| 90 | + SuccessCallback successCallback, | ||
| 91 | + FailureCallback failureCallback) { | ||
| 92 | this.midjourneyConfig = account; | 92 | this.midjourneyConfig = account; |
| 93 | this.userMessageListener = userMessageListener; | 93 | this.userMessageListener = userMessageListener; |
| 94 | this.successCallback = successCallback; | 94 | this.successCallback = successCallback; |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/webSocket/listener/MjMessageListener.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/webSocket/listener/MidjourneyMessageListener.java
| @@ -6,11 +6,11 @@ import cn.hutool.core.text.CharSequenceUtil; | @@ -6,11 +6,11 @@ import cn.hutool.core.text.CharSequenceUtil; | ||
| 6 | import cn.hutool.core.util.StrUtil; | 6 | import cn.hutool.core.util.StrUtil; |
| 7 | import cn.hutool.json.JSONUtil; | 7 | import cn.hutool.json.JSONUtil; |
| 8 | import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; | 8 | import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; |
| 9 | -import cn.iocoder.yudao.framework.ai.midjourney.MjMessage; | ||
| 10 | -import cn.iocoder.yudao.framework.ai.midjourney.constants.MjConstants; | ||
| 11 | -import cn.iocoder.yudao.framework.ai.midjourney.constants.MjGennerateStatusEnum; | ||
| 12 | -import cn.iocoder.yudao.framework.ai.midjourney.constants.MjMessageTypeEnum; | ||
| 13 | -import cn.iocoder.yudao.framework.ai.midjourney.util.MjUtil; | 9 | +import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyMessage; |
| 10 | +import cn.iocoder.yudao.framework.ai.midjourney.constants.MidjourneyConstants; | ||
| 11 | +import cn.iocoder.yudao.framework.ai.midjourney.constants.MidjourneyGennerateStatusEnum; | ||
| 12 | +import cn.iocoder.yudao.framework.ai.midjourney.constants.MidjourneyMessageTypeEnum; | ||
| 13 | +import cn.iocoder.yudao.framework.ai.midjourney.util.MidjourneyUtil; | ||
| 14 | import com.alibaba.fastjson.JSON; | 14 | import com.alibaba.fastjson.JSON; |
| 15 | import lombok.extern.slf4j.Slf4j; | 15 | import lombok.extern.slf4j.Slf4j; |
| 16 | import net.dv8tion.jda.api.utils.data.DataObject; | 16 | import net.dv8tion.jda.api.utils.data.DataObject; |
| @@ -18,17 +18,17 @@ import net.dv8tion.jda.api.utils.data.DataObject; | @@ -18,17 +18,17 @@ import net.dv8tion.jda.api.utils.data.DataObject; | ||
| 18 | import java.util.List; | 18 | import java.util.List; |
| 19 | 19 | ||
| 20 | @Slf4j | 20 | @Slf4j |
| 21 | -public class MjMessageListener { | 21 | +public class MidjourneyMessageListener { |
| 22 | 22 | ||
| 23 | private MidjourneyConfig midjourneyConfig; | 23 | private MidjourneyConfig midjourneyConfig; |
| 24 | 24 | ||
| 25 | - public MjMessageListener(MidjourneyConfig midjourneyConfig) { | 25 | + public MidjourneyMessageListener(MidjourneyConfig midjourneyConfig) { |
| 26 | this.midjourneyConfig = midjourneyConfig; | 26 | this.midjourneyConfig = midjourneyConfig; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | public void onMessage(DataObject raw) { | 29 | public void onMessage(DataObject raw) { |
| 30 | - MjMessageTypeEnum messageType = MjMessageTypeEnum.of(raw.getString("t")); | ||
| 31 | - if (messageType == null || MjMessageTypeEnum.DELETE == messageType) { | 30 | + MidjourneyMessageTypeEnum messageType = MidjourneyMessageTypeEnum.of(raw.getString("t")); |
| 31 | + if (messageType == null || MidjourneyMessageTypeEnum.DELETE == messageType) { | ||
| 32 | return; | 32 | return; |
| 33 | } | 33 | } |
| 34 | DataObject data = raw.getObject("d"); | 34 | DataObject data = raw.getObject("d"); |
| @@ -37,21 +37,21 @@ public class MjMessageListener { | @@ -37,21 +37,21 @@ public class MjMessageListener { | ||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | // 转换几个重要的信息 | 39 | // 转换几个重要的信息 |
| 40 | - MjMessage mjMessage = new MjMessage(); | ||
| 41 | - mjMessage.setId(data.getString(MjConstants.MSG_ID)); | ||
| 42 | - mjMessage.setType(data.getInt(MjConstants.MSG_TYPE)); | 40 | + MidjourneyMessage mjMessage = new MidjourneyMessage(); |
| 41 | + mjMessage.setId(data.getString(MidjourneyConstants.MSG_ID)); | ||
| 42 | + mjMessage.setType(data.getInt(MidjourneyConstants.MSG_TYPE)); | ||
| 43 | mjMessage.setRawData(StrUtil.str(raw.toJson(), "UTF-8")); | 43 | mjMessage.setRawData(StrUtil.str(raw.toJson(), "UTF-8")); |
| 44 | - mjMessage.setContent(MjUtil.parseContent(data.getString(MjConstants.MSG_CONTENT))); | 44 | + mjMessage.setContent(MidjourneyUtil.parseContent(data.getString(MidjourneyConstants.MSG_CONTENT))); |
| 45 | // 转换 components | 45 | // 转换 components |
| 46 | - if (!data.getArray(MjConstants.MSG_COMPONENTS).isEmpty()) { | ||
| 47 | - String componentsJson = StrUtil.str(data.getArray(MjConstants.MSG_COMPONENTS).toJson(), "UTF-8"); | ||
| 48 | - List<MjMessage.ComponentType> components = JSON.parseArray(componentsJson, MjMessage.ComponentType.class); | 46 | + if (!data.getArray(MidjourneyConstants.MSG_COMPONENTS).isEmpty()) { |
| 47 | + String componentsJson = StrUtil.str(data.getArray(MidjourneyConstants.MSG_COMPONENTS).toJson(), "UTF-8"); | ||
| 48 | + List<MidjourneyMessage.ComponentType> components = JSON.parseArray(componentsJson, MidjourneyMessage.ComponentType.class); | ||
| 49 | mjMessage.setComponents(components); | 49 | mjMessage.setComponents(components); |
| 50 | } | 50 | } |
| 51 | // 转换附件 | 51 | // 转换附件 |
| 52 | - if (!data.getArray(MjConstants.MSG_ATTACHMENTS).isEmpty()) { | ||
| 53 | - String attachmentsJson = StrUtil.str(data.getArray(MjConstants.MSG_ATTACHMENTS).toJson(), "UTF-8"); | ||
| 54 | - List<MjMessage.Attachment> attachments = JSON.parseArray(attachmentsJson, MjMessage.Attachment.class); | 52 | + if (!data.getArray(MidjourneyConstants.MSG_ATTACHMENTS).isEmpty()) { |
| 53 | + String attachmentsJson = StrUtil.str(data.getArray(MidjourneyConstants.MSG_ATTACHMENTS).toJson(), "UTF-8"); | ||
| 54 | + List<MidjourneyMessage.Attachment> attachments = JSON.parseArray(attachmentsJson, MidjourneyMessage.Attachment.class); | ||
| 55 | mjMessage.setAttachments(attachments); | 55 | mjMessage.setAttachments(attachments); |
| 56 | } | 56 | } |
| 57 | // 转换状态 | 57 | // 转换状态 |
| @@ -61,18 +61,18 @@ public class MjMessageListener { | @@ -61,18 +61,18 @@ public class MjMessageListener { | ||
| 61 | System.err.println(JSONUtil.toJsonPrettyStr(mjMessage)); | 61 | System.err.println(JSONUtil.toJsonPrettyStr(mjMessage)); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | - private void convertGenerateStatus(MjMessage mjMessage) { | 64 | + private void convertGenerateStatus(MidjourneyMessage mjMessage) { |
| 65 | if (mjMessage.getType() == 20 && mjMessage.getContent().getStatus().contains("Waiting")) { | 65 | if (mjMessage.getType() == 20 && mjMessage.getContent().getStatus().contains("Waiting")) { |
| 66 | - mjMessage.setGenerateStatus(MjGennerateStatusEnum.WAITING.getValue()); | 66 | + mjMessage.setGenerateStatus(MidjourneyGennerateStatusEnum.WAITING.getStatus()); |
| 67 | } else if (mjMessage.getType() == 20 && !StrUtil.isBlank(mjMessage.getContent().getProgress())) { | 67 | } else if (mjMessage.getType() == 20 && !StrUtil.isBlank(mjMessage.getContent().getProgress())) { |
| 68 | - mjMessage.setGenerateStatus(MjGennerateStatusEnum.IN_PROGRESS.getValue()); | 68 | + mjMessage.setGenerateStatus(MidjourneyGennerateStatusEnum.IN_PROGRESS.getStatus()); |
| 69 | } else if (mjMessage.getType() == 0 && !CollUtil.isEmpty(mjMessage.getComponents())) { | 69 | } else if (mjMessage.getType() == 0 && !CollUtil.isEmpty(mjMessage.getComponents())) { |
| 70 | - mjMessage.setGenerateStatus(MjGennerateStatusEnum.COMPLETED.getValue()); | 70 | + mjMessage.setGenerateStatus(MidjourneyGennerateStatusEnum.COMPLETED.getStatus()); |
| 71 | } | 71 | } |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | - private boolean ignoreAndLogMessage(DataObject data, MjMessageTypeEnum messageType) { | ||
| 75 | - String channelId = data.getString(MjConstants.MSG_CHANNEL_ID); | 74 | + private boolean ignoreAndLogMessage(DataObject data, MidjourneyMessageTypeEnum messageType) { |
| 75 | + String channelId = data.getString(MidjourneyConstants.MSG_CHANNEL_ID); | ||
| 76 | if (!CharSequenceUtil.equals(channelId, midjourneyConfig.getChannelId())) { | 76 | if (!CharSequenceUtil.equals(channelId, midjourneyConfig.getChannelId())) { |
| 77 | return true; | 77 | return true; |
| 78 | } | 78 | } |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/package-info.java
| 1 | /** | 1 | /** |
| 2 | * author: fansili | 2 | * author: fansili |
| 3 | * time: 2024/3/12 20:29 | 3 | * time: 2024/3/12 20:29 |
| 4 | + * | ||
| 5 | + * TODO @fansili:包的想法,需要重点看看 | ||
| 6 | + * | ||
| 7 | + * 1. org.springframework.ai:包括 chat、image、model、parser、util 部分 | ||
| 8 | + * | ||
| 9 | + * 2. yudao.framework.models | ||
| 10 | + * \qianwen 通义千问 | ||
| 11 | + * \yiyan 文心一言 | ||
| 12 | + * \xinghuo 星火 | ||
| 13 | + * \midjourney | ||
| 4 | */ | 14 | */ |
| 5 | package cn.iocoder.yudao.framework.ai; | 15 | package cn.iocoder.yudao.framework.ai; |
| 6 | \ No newline at end of file | 16 | \ No newline at end of file |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/util/JacksonUtil.java deleted
| 1 | -package cn.iocoder.yudao.framework.ai.util; | ||
| 2 | - | ||
| 3 | -import com.fasterxml.jackson.annotation.JsonInclude; | ||
| 4 | -import com.fasterxml.jackson.core.JsonProcessingException; | ||
| 5 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
| 6 | -import com.fasterxml.jackson.databind.SerializationFeature; | ||
| 7 | -import com.fasterxml.jackson.databind.module.SimpleModule; | ||
| 8 | -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; | ||
| 9 | - | ||
| 10 | -import java.io.IOException; | ||
| 11 | - | ||
| 12 | -/** | ||
| 13 | - * Jackson工具类 | ||
| 14 | - * | ||
| 15 | - * author: fansili | ||
| 16 | - * time: 2024/3/17 10:13 | ||
| 17 | - */ | ||
| 18 | -public class JacksonUtil { | ||
| 19 | - | ||
| 20 | - private static final ObjectMapper objectMapper = new ObjectMapper(); | ||
| 21 | - | ||
| 22 | - /** | ||
| 23 | - * 初始化 ObjectMapper 以美化输出(即格式化JSON内容) | ||
| 24 | - */ | ||
| 25 | - static { | ||
| 26 | - // 美化输出(缩进) | ||
| 27 | - objectMapper.enable(SerializationFeature.INDENT_OUTPUT); | ||
| 28 | - // 忽略值为 null 的属性 | ||
| 29 | - objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); | ||
| 30 | - // 配置一个模块来将 Long 类型转换为 String 类型 | ||
| 31 | - SimpleModule module = new SimpleModule(); | ||
| 32 | - module.addSerializer(Long.class, ToStringSerializer.instance); | ||
| 33 | - objectMapper.registerModule(module); | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | - /** | ||
| 37 | - * 将对象转换为 JSON 字符串 | ||
| 38 | - * | ||
| 39 | - * @param obj 需要序列化的Java对象 | ||
| 40 | - * @return 序列化后的 JSON 字符串 | ||
| 41 | - * @throws JsonProcessingException 当 JSON 序列化过程中出现错误时抛出异常 | ||
| 42 | - */ | ||
| 43 | - public static String toJson(Object obj) { | ||
| 44 | - try { | ||
| 45 | - return objectMapper.writeValueAsString(obj); | ||
| 46 | - } catch (JsonProcessingException e) { | ||
| 47 | - throw new RuntimeException(e); | ||
| 48 | - } | ||
| 49 | - } | ||
| 50 | - | ||
| 51 | - /** | ||
| 52 | - * 将 JSON 字符串反序列化为指定类型的对象 | ||
| 53 | - * | ||
| 54 | - * @param json JSON 字符串 | ||
| 55 | - * @param clazz 目标类型 Class 对象 | ||
| 56 | - * @param <T> 泛型类型参数 | ||
| 57 | - * @return 反序列化后的 Java 对象 | ||
| 58 | - * @throws IOException 当 JSON 解析过程中出现错误时抛出异常 | ||
| 59 | - */ | ||
| 60 | - public static <T> T fromJson(String json, Class<T> clazz) { | ||
| 61 | - try { | ||
| 62 | - return objectMapper.readValue(json, clazz); | ||
| 63 | - } catch (JsonProcessingException e) { | ||
| 64 | - throw new RuntimeException(e); | ||
| 65 | - } | ||
| 66 | - } | ||
| 67 | - | ||
| 68 | - /** | ||
| 69 | - * 将对象转换为格式化的 JSON 字符串(已启用 INDENT_OUTPUT 功能,所以所有方法都会返回格式化后的 JSON) | ||
| 70 | - * | ||
| 71 | - * @param obj 需要序列化的Java对象 | ||
| 72 | - * @return 格式化后的 JSON 字符串 | ||
| 73 | - * @throws JsonProcessingException 当 JSON 序列化过程中出现错误时抛出异常 | ||
| 74 | - */ | ||
| 75 | - public static String toFormattedJson(Object obj) { | ||
| 76 | - // 已在类初始化时设置了 SerializationFeature.INDENT_OUTPUT,此处无需额外操作 | ||
| 77 | - return toJson(obj); | ||
| 78 | - } | ||
| 79 | -} |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java
| 1 | package cn.iocoder.yudao.framework.ai.chat; | 1 | package cn.iocoder.yudao.framework.ai.chat; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; | 3 | import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; |
| 4 | -import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenApi; | 4 | +import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenApi; |
| 5 | import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatClient; | 5 | import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatClient; |
| 6 | import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenOptions; | 6 | import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenOptions; |
| 7 | -import com.aliyun.broadscope.bailian.sdk.models.CompletionsRequest; | ||
| 8 | import org.junit.Before; | 7 | import org.junit.Before; |
| 9 | import org.junit.Test; | 8 | import org.junit.Test; |
| 10 | import reactor.core.publisher.Flux; | 9 | import reactor.core.publisher.Flux; |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/mj/MjInteractionsTests.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/midjourney/MidjourneyInteractionsTests.java
| 1 | -package cn.iocoder.yudao.framework.ai.mj; | 1 | +package cn.iocoder.yudao.framework.ai.midjourney; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.io.FileUtil; | 3 | import cn.hutool.core.io.FileUtil; |
| 4 | -import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; | ||
| 5 | -import cn.iocoder.yudao.framework.ai.midjourney.interactions.MjInteractions; | ||
| 6 | -import cn.iocoder.yudao.framework.ai.midjourney.vo.Attachments; | ||
| 7 | -import cn.iocoder.yudao.framework.ai.midjourney.vo.Describe; | ||
| 8 | -import cn.iocoder.yudao.framework.ai.midjourney.vo.ReRoll; | ||
| 9 | -import cn.iocoder.yudao.framework.ai.midjourney.vo.UploadAttachmentsRes; | 4 | +import cn.iocoder.yudao.framework.ai.midjourney.api.MidjourneyInteractionsApi; |
| 5 | +import cn.iocoder.yudao.framework.ai.midjourney.api.req.AttachmentsReq; | ||
| 6 | +import cn.iocoder.yudao.framework.ai.midjourney.api.req.DescribeReq; | ||
| 7 | +import cn.iocoder.yudao.framework.ai.midjourney.api.req.ReRollReq; | ||
| 8 | +import cn.iocoder.yudao.framework.ai.midjourney.api.res.UploadAttachmentsRes; | ||
| 10 | import com.alibaba.fastjson.JSON; | 9 | import com.alibaba.fastjson.JSON; |
| 11 | import org.junit.Before; | 10 | import org.junit.Before; |
| 12 | import org.junit.Test; | 11 | import org.junit.Test; |
| @@ -23,7 +22,7 @@ import java.util.Map; | @@ -23,7 +22,7 @@ import java.util.Map; | ||
| 23 | * author: fansili | 22 | * author: fansili |
| 24 | * time: 2024/4/4 18:59 | 23 | * time: 2024/4/4 18:59 |
| 25 | */ | 24 | */ |
| 26 | -public class MjInteractionsTests { | 25 | +public class MidjourneyInteractionsTests { |
| 27 | 26 | ||
| 28 | private MidjourneyConfig midjourneyConfig; | 27 | private MidjourneyConfig midjourneyConfig; |
| 29 | @Before | 28 | @Before |
| @@ -39,24 +38,24 @@ public class MjInteractionsTests { | @@ -39,24 +38,24 @@ public class MjInteractionsTests { | ||
| 39 | 38 | ||
| 40 | @Test | 39 | @Test |
| 41 | public void mjImageTest() { | 40 | public void mjImageTest() { |
| 42 | - MjInteractions mjImagineInteractions = new MjInteractions(midjourneyConfig); | 41 | + MidjourneyInteractionsApi mjImagineInteractions = new MidjourneyInteractionsApi(midjourneyConfig); |
| 43 | mjImagineInteractions.imagine("童话里应该是什么样子?"); | 42 | mjImagineInteractions.imagine("童话里应该是什么样子?"); |
| 44 | } | 43 | } |
| 45 | 44 | ||
| 46 | 45 | ||
| 47 | @Test | 46 | @Test |
| 48 | public void reRollTest() { | 47 | public void reRollTest() { |
| 49 | - MjInteractions mjImagineInteractions = new MjInteractions(midjourneyConfig); | ||
| 50 | - mjImagineInteractions.reRoll(new ReRoll() | 48 | + MidjourneyInteractionsApi mjImagineInteractions = new MidjourneyInteractionsApi(midjourneyConfig); |
| 49 | + mjImagineInteractions.reRoll(new ReRollReq() | ||
| 51 | .setMessageId("1226165117448753243") | 50 | .setMessageId("1226165117448753243") |
| 52 | .setCustomId("MJ::JOB::upsample::3::2aeefbef-43e2-4057-bcf1-43b5f39ab6f7")); | 51 | .setCustomId("MJ::JOB::upsample::3::2aeefbef-43e2-4057-bcf1-43b5f39ab6f7")); |
| 53 | } | 52 | } |
| 54 | 53 | ||
| 55 | @Test | 54 | @Test |
| 56 | public void uploadAttachmentsTest() { | 55 | public void uploadAttachmentsTest() { |
| 57 | - MjInteractions mjImagineInteractions = new MjInteractions(midjourneyConfig); | 56 | + MidjourneyInteractionsApi mjImagineInteractions = new MidjourneyInteractionsApi(midjourneyConfig); |
| 58 | UploadAttachmentsRes res = mjImagineInteractions.uploadAttachments( | 57 | UploadAttachmentsRes res = mjImagineInteractions.uploadAttachments( |
| 59 | - new Attachments().setFileSystemResource( | 58 | + new AttachmentsReq().setFileSystemResource( |
| 60 | new FileSystemResource(new File("/Users/fansili/Downloads/DSC01402.JPG"))) | 59 | new FileSystemResource(new File("/Users/fansili/Downloads/DSC01402.JPG"))) |
| 61 | ); | 60 | ); |
| 62 | System.err.println(JSON.toJSONString(res)); | 61 | System.err.println(JSON.toJSONString(res)); |
| @@ -64,8 +63,8 @@ public class MjInteractionsTests { | @@ -64,8 +63,8 @@ public class MjInteractionsTests { | ||
| 64 | 63 | ||
| 65 | @Test | 64 | @Test |
| 66 | public void describeTest() { | 65 | public void describeTest() { |
| 67 | - MjInteractions mjImagineInteractions = new MjInteractions(midjourneyConfig); | ||
| 68 | - mjImagineInteractions.describe(new Describe() | 66 | + MidjourneyInteractionsApi mjImagineInteractions = new MidjourneyInteractionsApi(midjourneyConfig); |
| 67 | + mjImagineInteractions.describe(new DescribeReq() | ||
| 69 | .setFileName("DSC01402.JPG") | 68 | .setFileName("DSC01402.JPG") |
| 70 | .setFinalFileName("16826931-2873-45ec-8cfb-0ad81f1a075f/DSC01402.JPG") | 69 | .setFinalFileName("16826931-2873-45ec-8cfb-0ad81f1a075f/DSC01402.JPG") |
| 71 | ); | 70 | ); |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/mj/MjUtilTests.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/midjourney/MidjourneyUtilTests.java
| 1 | -package cn.iocoder.yudao.framework.ai.mj; | 1 | +package cn.iocoder.yudao.framework.ai.midjourney; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.ai.midjourney.util.MjUtil; | 3 | +import cn.iocoder.yudao.framework.ai.midjourney.util.MidjourneyUtil; |
| 4 | import org.junit.Test; | 4 | import org.junit.Test; |
| 5 | 5 | ||
| 6 | /** | 6 | /** |
| @@ -9,14 +9,14 @@ import org.junit.Test; | @@ -9,14 +9,14 @@ import org.junit.Test; | ||
| 9 | * author: fansili | 9 | * author: fansili |
| 10 | * time: 2024/4/6 21:57 | 10 | * time: 2024/4/6 21:57 |
| 11 | */ | 11 | */ |
| 12 | -public class MjUtilTests { | 12 | +public class MidjourneyUtilTests { |
| 13 | 13 | ||
| 14 | @Test | 14 | @Test |
| 15 | public void parseContentTest() { | 15 | public void parseContentTest() { |
| 16 | String content1 = "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (32%) (fast, stealth)"; | 16 | String content1 = "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (32%) (fast, stealth)"; |
| 17 | String content2 = "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (fast, stealth)"; | 17 | String content2 = "**南极应该是什么样子? --v 6.0 --style raw** - <@972721304891453450> (fast, stealth)"; |
| 18 | 18 | ||
| 19 | - System.err.println(MjUtil.parseContent(content1)); | ||
| 20 | - System.err.println(MjUtil.parseContent(content2)); | 19 | + System.err.println(MidjourneyUtil.parseContent(content1)); |
| 20 | + System.err.println(MidjourneyUtil.parseContent(content2)); | ||
| 21 | } | 21 | } |
| 22 | } | 22 | } |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/mj/MjWebSocketTests.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/midjourney/MidjourneyWebSocketTests.java
| 1 | -package cn.iocoder.yudao.framework.ai.mj; | 1 | +package cn.iocoder.yudao.framework.ai.midjourney; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.io.FileUtil; | 3 | import cn.hutool.core.io.FileUtil; |
| 4 | -import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; | ||
| 5 | -import cn.iocoder.yudao.framework.ai.midjourney.webSocket.listener.MjMessageListener; | ||
| 6 | -import cn.iocoder.yudao.framework.ai.midjourney.webSocket.MjWebSocketStarter; | 4 | +import cn.iocoder.yudao.framework.ai.midjourney.webSocket.listener.MidjourneyMessageListener; |
| 5 | +import cn.iocoder.yudao.framework.ai.midjourney.webSocket.MidjourneyWebSocketStarter; | ||
| 7 | import org.junit.Before; | 6 | import org.junit.Before; |
| 8 | import org.junit.Test; | 7 | import org.junit.Test; |
| 9 | 8 | ||
| @@ -17,7 +16,7 @@ import java.util.Scanner; | @@ -17,7 +16,7 @@ import java.util.Scanner; | ||
| 17 | * author: fansili | 16 | * author: fansili |
| 18 | * time: 2024/4/3 16:40 | 17 | * time: 2024/4/3 16:40 |
| 19 | */ | 18 | */ |
| 20 | -public class MjWebSocketTests { | 19 | +public class MidjourneyWebSocketTests { |
| 21 | 20 | ||
| 22 | private MidjourneyConfig midjourneyConfig; | 21 | private MidjourneyConfig midjourneyConfig; |
| 23 | 22 | ||
| @@ -35,8 +34,8 @@ public class MjWebSocketTests { | @@ -35,8 +34,8 @@ public class MjWebSocketTests { | ||
| 35 | @Test | 34 | @Test |
| 36 | public void startSocketTest() { | 35 | public void startSocketTest() { |
| 37 | String wssUrl = "wss://gateway.discord.gg"; | 36 | String wssUrl = "wss://gateway.discord.gg"; |
| 38 | - var messageListener = new MjMessageListener(midjourneyConfig); | ||
| 39 | - var webSocketStarter = new MjWebSocketStarter(wssUrl, null, midjourneyConfig, messageListener); | 37 | + var messageListener = new MidjourneyMessageListener(midjourneyConfig); |
| 38 | + var webSocketStarter = new MidjourneyWebSocketStarter(wssUrl, null, midjourneyConfig, messageListener); | ||
| 40 | 39 | ||
| 41 | try { | 40 | try { |
| 42 | webSocketStarter.start(); | 41 | webSocketStarter.start(); |