Commit 3aad33c3cd40c3ff8ca4131cb72bdb63e8791167
Committed by
Gitee
!1013 新增文心一言、智谱 AI 的绘图能力
Merge pull request !1013 from 芋道源码/master-jdk21-ai
Showing
3 changed files
with
62 additions
and
2 deletions
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java
| @@ -33,6 +33,7 @@ import org.springframework.ai.image.ImageResponse; | @@ -33,6 +33,7 @@ import org.springframework.ai.image.ImageResponse; | ||
| 33 | import org.springframework.ai.openai.OpenAiImageOptions; | 33 | import org.springframework.ai.openai.OpenAiImageOptions; |
| 34 | import org.springframework.ai.qianfan.QianFanImageOptions; | 34 | import org.springframework.ai.qianfan.QianFanImageOptions; |
| 35 | import org.springframework.ai.stabilityai.api.StabilityAiImageOptions; | 35 | import org.springframework.ai.stabilityai.api.StabilityAiImageOptions; |
| 36 | +import org.springframework.ai.zhipuai.ZhiPuAiImageOptions; | ||
| 36 | import org.springframework.scheduling.annotation.Async; | 37 | import org.springframework.scheduling.annotation.Async; |
| 37 | import org.springframework.stereotype.Service; | 38 | import org.springframework.stereotype.Service; |
| 38 | import org.springframework.transaction.annotation.Transactional; | 39 | import org.springframework.transaction.annotation.Transactional; |
| @@ -104,7 +105,9 @@ public class AiImageServiceImpl implements AiImageService { | @@ -104,7 +105,9 @@ public class AiImageServiceImpl implements AiImageService { | ||
| 104 | ImageResponse response = imageModel.call(new ImagePrompt(req.getPrompt(), request)); | 105 | ImageResponse response = imageModel.call(new ImagePrompt(req.getPrompt(), request)); |
| 105 | 106 | ||
| 106 | // 2. 上传到文件服务 | 107 | // 2. 上传到文件服务 |
| 107 | - byte[] fileContent = Base64.decode(response.getResult().getOutput().getB64Json()); | 108 | + String b64Json = response.getResult().getOutput().getB64Json(); |
| 109 | + byte[] fileContent = StrUtil.isNotEmpty(b64Json) ? Base64.decode(b64Json) | ||
| 110 | + : HttpUtil.downloadBytes(response.getResult().getOutput().getUrl()); | ||
| 108 | String filePath = fileApi.createFile(fileContent); | 111 | String filePath = fileApi.createFile(fileContent); |
| 109 | 112 | ||
| 110 | // 3. 更新数据库 | 113 | // 3. 更新数据库 |
| @@ -148,6 +151,10 @@ public class AiImageServiceImpl implements AiImageService { | @@ -148,6 +151,10 @@ public class AiImageServiceImpl implements AiImageService { | ||
| 148 | .withModel(draw.getModel()).withN(1) | 151 | .withModel(draw.getModel()).withN(1) |
| 149 | .withHeight(draw.getHeight()).withWidth(draw.getWidth()) | 152 | .withHeight(draw.getHeight()).withWidth(draw.getWidth()) |
| 150 | .build(); | 153 | .build(); |
| 154 | + } else if (ObjUtil.equal(draw.getPlatform(), AiPlatformEnum.ZHI_PU.getPlatform())) { | ||
| 155 | + return ZhiPuAiImageOptions.builder() | ||
| 156 | + .withModel(draw.getModel()) | ||
| 157 | + .build(); | ||
| 151 | } | 158 | } |
| 152 | throw new IllegalArgumentException("不支持的 AI 平台:" + draw.getPlatform()); | 159 | throw new IllegalArgumentException("不支持的 AI 平台:" + draw.getPlatform()); |
| 153 | } | 160 | } |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
| @@ -30,6 +30,7 @@ import org.springframework.ai.autoconfigure.qianfan.QianFanImageProperties; | @@ -30,6 +30,7 @@ import org.springframework.ai.autoconfigure.qianfan.QianFanImageProperties; | ||
| 30 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiAutoConfiguration; | 30 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiAutoConfiguration; |
| 31 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiChatProperties; | 31 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiChatProperties; |
| 32 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiConnectionProperties; | 32 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiConnectionProperties; |
| 33 | +import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiImageProperties; | ||
| 33 | import org.springframework.ai.chat.model.ChatModel; | 34 | import org.springframework.ai.chat.model.ChatModel; |
| 34 | import org.springframework.ai.image.ImageModel; | 35 | import org.springframework.ai.image.ImageModel; |
| 35 | import org.springframework.ai.model.function.FunctionCallbackContext; | 36 | import org.springframework.ai.model.function.FunctionCallbackContext; |
| @@ -47,7 +48,9 @@ import org.springframework.ai.qianfan.api.QianFanImageApi; | @@ -47,7 +48,9 @@ import org.springframework.ai.qianfan.api.QianFanImageApi; | ||
| 47 | import org.springframework.ai.stabilityai.StabilityAiImageModel; | 48 | import org.springframework.ai.stabilityai.StabilityAiImageModel; |
| 48 | import org.springframework.ai.stabilityai.api.StabilityAiApi; | 49 | import org.springframework.ai.stabilityai.api.StabilityAiApi; |
| 49 | import org.springframework.ai.zhipuai.ZhiPuAiChatModel; | 50 | import org.springframework.ai.zhipuai.ZhiPuAiChatModel; |
| 51 | +import org.springframework.ai.zhipuai.ZhiPuAiImageModel; | ||
| 50 | import org.springframework.ai.zhipuai.api.ZhiPuAiApi; | 52 | import org.springframework.ai.zhipuai.api.ZhiPuAiApi; |
| 53 | +import org.springframework.ai.zhipuai.api.ZhiPuAiImageApi; | ||
| 51 | import org.springframework.retry.support.RetryTemplate; | 54 | import org.springframework.retry.support.RetryTemplate; |
| 52 | import org.springframework.web.client.ResponseErrorHandler; | 55 | import org.springframework.web.client.ResponseErrorHandler; |
| 53 | import org.springframework.web.client.RestClient; | 56 | import org.springframework.web.client.RestClient; |
| @@ -118,6 +121,8 @@ public class AiModelFactoryImpl implements AiModelFactory { | @@ -118,6 +121,8 @@ public class AiModelFactoryImpl implements AiModelFactory { | ||
| 118 | return SpringUtil.getBean(TongYiImagesModel.class); | 121 | return SpringUtil.getBean(TongYiImagesModel.class); |
| 119 | case YI_YAN: | 122 | case YI_YAN: |
| 120 | return SpringUtil.getBean(QianFanImageModel.class); | 123 | return SpringUtil.getBean(QianFanImageModel.class); |
| 124 | + case ZHI_PU: | ||
| 125 | + return SpringUtil.getBean(ZhiPuAiImageModel.class); | ||
| 121 | case OPENAI: | 126 | case OPENAI: |
| 122 | return SpringUtil.getBean(OpenAiImageModel.class); | 127 | return SpringUtil.getBean(OpenAiImageModel.class); |
| 123 | case STABLE_DIFFUSION: | 128 | case STABLE_DIFFUSION: |
| @@ -135,6 +140,8 @@ public class AiModelFactoryImpl implements AiModelFactory { | @@ -135,6 +140,8 @@ public class AiModelFactoryImpl implements AiModelFactory { | ||
| 135 | return buildTongYiImagesModel(apiKey); | 140 | return buildTongYiImagesModel(apiKey); |
| 136 | case YI_YAN: | 141 | case YI_YAN: |
| 137 | return buildQianFanImageModel(apiKey); | 142 | return buildQianFanImageModel(apiKey); |
| 143 | + case ZHI_PU: | ||
| 144 | + return buildZhiPuAiImageModel(apiKey, url); | ||
| 138 | case OPENAI: | 145 | case OPENAI: |
| 139 | return buildOpenAiImageModel(apiKey, url); | 146 | return buildOpenAiImageModel(apiKey, url); |
| 140 | case STABLE_DIFFUSION: | 147 | case STABLE_DIFFUSION: |
| @@ -222,7 +229,8 @@ public class AiModelFactoryImpl implements AiModelFactory { | @@ -222,7 +229,8 @@ public class AiModelFactoryImpl implements AiModelFactory { | ||
| 222 | } | 229 | } |
| 223 | 230 | ||
| 224 | /** | 231 | /** |
| 225 | - * 可参考 {@link ZhiPuAiAutoConfiguration#zhiPuAiChatModel(ZhiPuAiConnectionProperties, ZhiPuAiChatProperties, RestClient.Builder, List, FunctionCallbackContext, RetryTemplate, ResponseErrorHandler)} | 232 | + * 可参考 {@link ZhiPuAiAutoConfiguration#zhiPuAiChatModel( |
| 233 | + * ZhiPuAiConnectionProperties, ZhiPuAiChatProperties, RestClient.Builder, List, FunctionCallbackContext, RetryTemplate, ResponseErrorHandler)} | ||
| 226 | */ | 234 | */ |
| 227 | private ZhiPuAiChatModel buildZhiPuChatModel(String apiKey, String url) { | 235 | private ZhiPuAiChatModel buildZhiPuChatModel(String apiKey, String url) { |
| 228 | url = StrUtil.blankToDefault(url, ZhiPuAiConnectionProperties.DEFAULT_BASE_URL); | 236 | url = StrUtil.blankToDefault(url, ZhiPuAiConnectionProperties.DEFAULT_BASE_URL); |
| @@ -231,6 +239,16 @@ public class AiModelFactoryImpl implements AiModelFactory { | @@ -231,6 +239,16 @@ public class AiModelFactoryImpl implements AiModelFactory { | ||
| 231 | } | 239 | } |
| 232 | 240 | ||
| 233 | /** | 241 | /** |
| 242 | + * 可参考 {@link ZhiPuAiAutoConfiguration#zhiPuAiImageModel( | ||
| 243 | + * ZhiPuAiConnectionProperties, ZhiPuAiImageProperties, RestClient.Builder, RetryTemplate, ResponseErrorHandler)} | ||
| 244 | + */ | ||
| 245 | + private ZhiPuAiImageModel buildZhiPuAiImageModel(String apiKey, String url) { | ||
| 246 | + url = StrUtil.blankToDefault(url, ZhiPuAiConnectionProperties.DEFAULT_BASE_URL); | ||
| 247 | + ZhiPuAiImageApi zhiPuAiApi = new ZhiPuAiImageApi(url, apiKey, RestClient.builder()); | ||
| 248 | + return new ZhiPuAiImageModel(zhiPuAiApi); | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | + /** | ||
| 234 | * 可参考 {@link YudaoAiAutoConfiguration#xingHuoChatClient(YudaoAiProperties)} | 252 | * 可参考 {@link YudaoAiAutoConfiguration#xingHuoChatClient(YudaoAiProperties)} |
| 235 | */ | 253 | */ |
| 236 | private static XingHuoChatModel buildXingHuoChatModel(String key) { | 254 | private static XingHuoChatModel buildXingHuoChatModel(String key) { |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/ZhiPuAiImageModelTests.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.image; | ||
| 2 | + | ||
| 3 | +import org.junit.jupiter.api.Disabled; | ||
| 4 | +import org.junit.jupiter.api.Test; | ||
| 5 | +import org.springframework.ai.image.ImagePrompt; | ||
| 6 | +import org.springframework.ai.image.ImageResponse; | ||
| 7 | +import org.springframework.ai.zhipuai.ZhiPuAiImageModel; | ||
| 8 | +import org.springframework.ai.zhipuai.ZhiPuAiImageOptions; | ||
| 9 | +import org.springframework.ai.zhipuai.api.ZhiPuAiImageApi; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * {@link ZhiPuAiImageModel} 集成测试 | ||
| 13 | + */ | ||
| 14 | +public class ZhiPuAiImageModelTests { | ||
| 15 | + | ||
| 16 | + private final ZhiPuAiImageApi imageApi = new ZhiPuAiImageApi( | ||
| 17 | + "78d3228c1d9e5e342a3e1ab349e2dd7b.VXLoq5vrwK2ofboy"); | ||
| 18 | + private final ZhiPuAiImageModel imageModel = new ZhiPuAiImageModel(imageApi); | ||
| 19 | + | ||
| 20 | + @Test | ||
| 21 | + @Disabled | ||
| 22 | + public void testCall() { | ||
| 23 | + // 准备参数 | ||
| 24 | + ZhiPuAiImageOptions imageOptions = ZhiPuAiImageOptions.builder() | ||
| 25 | + .withModel(ZhiPuAiImageApi.ImageModel.CogView_3.getValue()) | ||
| 26 | + .build(); | ||
| 27 | + ImagePrompt prompt = new ImagePrompt("万里长城", imageOptions); | ||
| 28 | + | ||
| 29 | + // 方法调用 | ||
| 30 | + ImageResponse response = imageModel.call(prompt); | ||
| 31 | + // 打印结果 | ||
| 32 | + System.out.println(response); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | +} |