Commit b4eed07d619ee75d4a4e2e921a386a6a9ba0e869

Authored by YunaiV
1 parent 4c3add50

【代码优化】AI:MJ 配置类的简化

yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/config/YudaoMidjourneyConfiguration.java deleted
1   -package cn.iocoder.yudao.module.ai.config;
2   -
3   -import cn.iocoder.yudao.framework.ai.core.model.midjourney.MidjourneyConfig;
4   -import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
5   -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6   -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
7   -import org.springframework.context.annotation.Bean;
8   -import org.springframework.context.annotation.Configuration;
9   -
10   -/**
11   - * 配置
12   - *
13   - * @author fansili
14   - * @time 2024/6/13 09:50
15   - */
16   -@Configuration
17   -public class YudaoMidjourneyConfiguration {
18   -
19   - @Bean
20   - @ConditionalOnProperty(value = "ai.midjourney-proxy.enable", havingValue = "true")
21   - public MidjourneyApi midjourneyApi(YudaoMidjourneyProperties midjourneyProperties) {
22   - return new MidjourneyApi(BeanUtils.toBean(midjourneyProperties, MidjourneyConfig.class));
23   - }
24   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/config/YudaoMidjourneyProperties.java deleted
1   -package cn.iocoder.yudao.module.ai.config;
2   -
3   -import lombok.Data;
4   -import org.springframework.boot.context.properties.ConfigurationProperties;
5   -import org.springframework.context.annotation.Configuration;
6   -
7   -/**
8   - * Midjourney 属性
9   - *
10   - * @author fansili
11   - * @time 2024/6/5 15:02
12   - * @since 1.0
13   - */
14   -@Configuration
15   -@ConfigurationProperties(prefix = "ai.midjourney-proxy")
16   -@Data
17   -public class YudaoMidjourneyProperties {
18   -
19   - private String enable;
20   - private String key;
21   - private String url;
22   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java
... ... @@ -29,7 +29,6 @@ import org.springframework.ai.image.ImagePrompt;
29 29 import org.springframework.ai.image.ImageResponse;
30 30 import org.springframework.ai.openai.OpenAiImageOptions;
31 31 import org.springframework.ai.stabilityai.api.StabilityAiImageOptions;
32   -import org.springframework.beans.factory.annotation.Value;
33 32 import org.springframework.scheduling.annotation.Async;
34 33 import org.springframework.stereotype.Service;
35 34 import org.springframework.transaction.annotation.Transactional;
... ... @@ -63,9 +62,6 @@ public class AiImageServiceImpl implements AiImageService {
63 62 @Resource
64 63 private MidjourneyApi midjourneyApi;
65 64  
66   - @Value("${ai.midjourney-proxy.notifyUrl:http://127.0.0.1:48080/admin-api/ai/image/midjourney-notify}")
67   - private String midjourneyNotifyUrl;
68   -
69 65 @Override
70 66 public PageResult<AiImageDO> getImagePageMy(Long userId, PageParam pageReqVO) {
71 67 return imageMapper.selectPage(userId, pageReqVO);
... ... @@ -159,7 +155,7 @@ public class AiImageServiceImpl implements AiImageService {
159 155  
160 156 // 2. 调用 Midjourney Proxy 提交任务
161 157 MidjourneyApi.ImagineRequest imagineRequest = new MidjourneyApi.ImagineRequest(
162   - null, midjourneyNotifyUrl, reqVO.getPrompt(),
  158 + null, reqVO.getPrompt(),null,
163 159 MidjourneyApi.ImagineRequest.buildState(reqVO.getWidth(), reqVO.getHeight(), reqVO.getVersion(), reqVO.getModel()));
164 160 MidjourneyApi.SubmitResponse imagineResponse = midjourneyApi.imagine(imagineRequest);
165 161  
... ... @@ -258,7 +254,7 @@ public class AiImageServiceImpl implements AiImageService {
258 254  
259 255 // 2. 调用 Midjourney Proxy 提交任务
260 256 MidjourneyApi.SubmitResponse actionResponse = midjourneyApi.action(
261   - new MidjourneyApi.ActionRequest(button.customId(), image.getTaskId(), midjourneyNotifyUrl));
  257 + new MidjourneyApi.ActionRequest(button.customId(), image.getTaskId(), null));
262 258 if (!MidjourneyApi.SubmitCodeEnum.SUCCESS_CODES.contains(actionResponse.code())) {
263 259 String description = actionResponse.description().contains("quota_not_enough") ?
264 260 "账户余额不足" : actionResponse.description();
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.ai.config;
2 2  
3 3 import cn.iocoder.yudao.framework.ai.core.factory.AiClientFactory;
4 4 import cn.iocoder.yudao.framework.ai.core.factory.AiClientFactoryImpl;
  5 +import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
5 6 import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi;
6 7 import cn.iocoder.yudao.framework.ai.core.model.tongyi.QianWenChatClient;
7 8 import cn.iocoder.yudao.framework.ai.core.model.tongyi.QianWenChatModal;
... ... @@ -97,6 +98,13 @@ public class YudaoAiAutoConfiguration {
97 98 }
98 99  
99 100 @Bean
  101 + @ConditionalOnProperty(value = "yudao.ai.midjourney.enable", havingValue = "true")
  102 + public MidjourneyApi midjourneyApi(YudaoAiProperties yudaoAiProperties) {
  103 + YudaoAiProperties.MidjourneyProperties config = yudaoAiProperties.getMidjourney();
  104 + return new MidjourneyApi(config.getBaseUrl(), config.getApiKey(), config.getNotifyUrl());
  105 + }
  106 +
  107 + @Bean
100 108 @ConditionalOnProperty(value = "yudao.ai.suno.enable", havingValue = "true")
101 109 public SunoApi sunoApi(YudaoAiProperties yudaoAiProperties) {
102 110 return new SunoApi(yudaoAiProperties.getSuno().getBaseUrl());
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiProperties.java
... ... @@ -64,15 +64,18 @@ public class YudaoAiProperties {
64 64 @Data
65 65 @Accessors(chain = true)
66 66 public static class XingHuoProperties extends ChatProperties {
  67 +
67 68 private String appId;
68 69 private String appKey;
69 70 private String secretKey;
70 71 private XingHuoChatModel model;
  72 +
71 73 }
72 74  
73 75 @Data
74 76 @Accessors(chain = true)
75 77 public static class YiYanProperties extends ChatProperties {
  78 +
76 79 /**
77 80 * appKey
78 81 */
... ... @@ -92,26 +95,13 @@ public class YudaoAiProperties {
92 95 }
93 96  
94 97 @Data
95   - @Accessors(chain = true)
96 98 public static class MidjourneyProperties {
97   - private boolean enable = false;
98 99  
99   - /**
100   - * socket 链接地址
101   - */
102   - private String wssUrl = "wss://gateway.discord.gg";
103   - /**
104   - * token
105   - */
106   - private String token;
107   - /**
108   - * 服务id
109   - */
110   - private String guildId;
111   - /**
112   - * 频道id
113   - */
114   - private String channelId;
  100 + private String enable;
  101 + private String apiKey;
  102 + private String baseUrl;
  103 + private String notifyUrl;
  104 +
115 105 }
116 106  
117 107 @Data
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/midjourney/api/MidjourneyApi.java
1 1 package cn.iocoder.yudao.framework.ai.core.model.midjourney.api;
2 2  
3   -import cn.iocoder.yudao.framework.ai.core.model.midjourney.MidjourneyConfig;
  3 +import cn.hutool.core.util.StrUtil;
4 4 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
5 5 import com.google.common.collect.ImmutableMap;
6 6 import com.google.common.collect.Lists;
7 7 import lombok.AllArgsConstructor;
  8 +import lombok.Data;
8 9 import lombok.Getter;
9 10 import lombok.extern.slf4j.Slf4j;
10 11 import org.springframework.ai.openai.api.ApiUtils;
... ... @@ -26,11 +27,17 @@ public class MidjourneyApi {
26 27  
27 28 private final WebClient webClient;
28 29  
29   - public MidjourneyApi(MidjourneyConfig midjourneyConfig) {
  30 + /**
  31 + * 回调地址
  32 + */
  33 + private final String notifyUrl;
  34 +
  35 + public MidjourneyApi(String baseUrl, String apiKey, String notifyUrl) {
30 36 this.webClient = WebClient.builder()
31   - .baseUrl(midjourneyConfig.getUrl())
32   - .defaultHeaders(ApiUtils.getJsonContentHeaders(midjourneyConfig.getKey()))
  37 + .baseUrl(baseUrl)
  38 + .defaultHeaders(ApiUtils.getJsonContentHeaders(apiKey))
33 39 .build();
  40 + this.notifyUrl = notifyUrl;
34 41 }
35 42  
36 43 /**
... ... @@ -40,6 +47,9 @@ public class MidjourneyApi {
40 47 * @return 提交结果
41 48 */
42 49 public SubmitResponse imagine(ImagineRequest request) {
  50 + if (StrUtil.isEmpty(request.getNotifyHook())) {
  51 + request.setNotifyHook(notifyUrl);
  52 + }
43 53 String response = post("/submit/imagine", request);
44 54 return JsonUtils.parseObject(response, SubmitResponse.class);
45 55 }
... ... @@ -51,8 +61,11 @@ public class MidjourneyApi {
51 61 * @return 提交结果
52 62 */
53 63 public SubmitResponse action(ActionRequest request) {
54   - String res = post("/submit/action", request);
55   - return JsonUtils.parseObject(res, SubmitResponse.class);
  64 + if (StrUtil.isEmpty(request.getNotifyHook())) {
  65 + request.setNotifyHook(notifyUrl);
  66 + }
  67 + String response = post("/submit/action", request);
  68 + return JsonUtils.parseObject(response, SubmitResponse.class);
56 69 }
57 70  
58 71 /**
... ... @@ -86,23 +99,40 @@ public class MidjourneyApi {
86 99  
87 100 /**
88 101 * Imagine 请求(生成图片)
89   - *
90   - * @param base64Array 垫图(参考图) base64数 组
91   - * @param notifyHook 通知地址
92   - * @param prompt 提示词
93   - * @param state 自定义参数
94 102 */
95   - public record ImagineRequest(List<String> base64Array,
96   - String notifyHook,
97   - String prompt,
98   - String state) {
  103 + @Data
  104 + public static final class ImagineRequest {
  105 +
  106 + /**
  107 + * 垫图(参考图) base64 数组
  108 + */
  109 + private List<String> base64Array;
  110 + /**
  111 + * 提示词
  112 + */
  113 + private String prompt;
  114 + /**
  115 + * 通知地址
  116 + */
  117 + private String notifyHook;
  118 + /**
  119 + * 自定义参数
  120 + */
  121 + private String state;
  122 +
  123 + public ImagineRequest(List<String> base64Array, String prompt, String notifyHook, String state) {
  124 + this.base64Array = base64Array;
  125 + this.prompt = prompt;
  126 + this.notifyHook = notifyHook;
  127 + this.state = state;
  128 + }
99 129  
100 130 public static String buildState(Integer width, Integer height, String version, String model) {
101 131 StringBuilder params = new StringBuilder();
102 132 // --ar 来设置尺寸
103 133 params.append(String.format(" --ar %s:%s ", width, height));
104 134 // --niji 模型
105   - if (MidjourneyApi.ModelEnum.NIJI.getModel().equals(model)) {
  135 + if (ModelEnum.NIJI.getModel().equals(model)) {
106 136 params.append(String.format(" --niji %s ", version));
107 137 } else {
108 138 params.append(String.format(" --v %s ", version));
... ... @@ -114,15 +144,20 @@ public class MidjourneyApi {
114 144  
115 145 /**
116 146 * Action 请求
117   - *
118   - * @param customId 操作按钮id
119   - * @param taskId 操作按钮id
120   - * @param notifyHook 通知地址
121 147 */
122   - public record ActionRequest(String customId,
123   - String taskId,
124   - String notifyHook
125   - ) {
  148 + @Data
  149 + public static final class ActionRequest {
  150 +
  151 + private String customId;
  152 + private String taskId;
  153 + private String notifyHook;
  154 +
  155 + public ActionRequest(String taskId, String customId, String notifyHook) {
  156 + this.customId = customId;
  157 + this.taskId = taskId;
  158 + this.notifyHook = notifyHook;
  159 + }
  160 +
126 161 }
127 162  
128 163 /**
... ...
yudao-server/src/main/resources/application.yaml
... ... @@ -194,20 +194,14 @@ yudao.ai:
194 194 api-key: sk-Zsd81gZYg7
195 195 midjourney:
196 196 enable: true
197   - token: MTE4MjE3MjY2MjkxNTY3ODIzOA.GEV1SG.c49F8lZoGCUHwsj8O0UdodmM6nyQHvuD2fXflw
198   - guild-id: 1237948819677904956
199   - channel-id: 1237948819677904960
  197 +# base-url: https://api.holdai.top/mj-relax/mj
  198 + base-url: https://api.holdai.top/mj
  199 + api-key: sk-dZEPiVaNcT3FHhef51996bAa0bC74806BeAb620dA5Da10Bf
  200 + notify-url: http://java.nat300.top/admin-api/ai/image/midjourney/notify
200 201 suno:
201 202 enable: true
202 203 base-url: https://suno-imrqwwui8-status2xxs-projects.vercel.app
203 204  
204   -ai:
205   - midjourney-proxy:
206   - enable: true
207   - url: https://api.holdai.top/mj
208   - notifyUrl: http://61d61685.r21.cpolar.top/admin-api/ai/image/midjourney-notify
209   - key: sk-dZEPiVaNcT3FHhef51996bAa0bC74806BeAb620dA5Da10Bf
210   -
211 205 --- #################### 芋道相关配置 ####################
212 206  
213 207 yudao:
... ...