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 | 33 | import org.springframework.ai.openai.OpenAiImageOptions; |
| 34 | 34 | import org.springframework.ai.qianfan.QianFanImageOptions; |
| 35 | 35 | import org.springframework.ai.stabilityai.api.StabilityAiImageOptions; |
| 36 | +import org.springframework.ai.zhipuai.ZhiPuAiImageOptions; | |
| 36 | 37 | import org.springframework.scheduling.annotation.Async; |
| 37 | 38 | import org.springframework.stereotype.Service; |
| 38 | 39 | import org.springframework.transaction.annotation.Transactional; |
| ... | ... | @@ -104,7 +105,9 @@ public class AiImageServiceImpl implements AiImageService { |
| 104 | 105 | ImageResponse response = imageModel.call(new ImagePrompt(req.getPrompt(), request)); |
| 105 | 106 | |
| 106 | 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 | 111 | String filePath = fileApi.createFile(fileContent); |
| 109 | 112 | |
| 110 | 113 | // 3. 更新数据库 |
| ... | ... | @@ -148,6 +151,10 @@ public class AiImageServiceImpl implements AiImageService { |
| 148 | 151 | .withModel(draw.getModel()).withN(1) |
| 149 | 152 | .withHeight(draw.getHeight()).withWidth(draw.getWidth()) |
| 150 | 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 | 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 | 30 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiAutoConfiguration; |
| 31 | 31 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiChatProperties; |
| 32 | 32 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiConnectionProperties; |
| 33 | +import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiImageProperties; | |
| 33 | 34 | import org.springframework.ai.chat.model.ChatModel; |
| 34 | 35 | import org.springframework.ai.image.ImageModel; |
| 35 | 36 | import org.springframework.ai.model.function.FunctionCallbackContext; |
| ... | ... | @@ -47,7 +48,9 @@ import org.springframework.ai.qianfan.api.QianFanImageApi; |
| 47 | 48 | import org.springframework.ai.stabilityai.StabilityAiImageModel; |
| 48 | 49 | import org.springframework.ai.stabilityai.api.StabilityAiApi; |
| 49 | 50 | import org.springframework.ai.zhipuai.ZhiPuAiChatModel; |
| 51 | +import org.springframework.ai.zhipuai.ZhiPuAiImageModel; | |
| 50 | 52 | import org.springframework.ai.zhipuai.api.ZhiPuAiApi; |
| 53 | +import org.springframework.ai.zhipuai.api.ZhiPuAiImageApi; | |
| 51 | 54 | import org.springframework.retry.support.RetryTemplate; |
| 52 | 55 | import org.springframework.web.client.ResponseErrorHandler; |
| 53 | 56 | import org.springframework.web.client.RestClient; |
| ... | ... | @@ -118,6 +121,8 @@ public class AiModelFactoryImpl implements AiModelFactory { |
| 118 | 121 | return SpringUtil.getBean(TongYiImagesModel.class); |
| 119 | 122 | case YI_YAN: |
| 120 | 123 | return SpringUtil.getBean(QianFanImageModel.class); |
| 124 | + case ZHI_PU: | |
| 125 | + return SpringUtil.getBean(ZhiPuAiImageModel.class); | |
| 121 | 126 | case OPENAI: |
| 122 | 127 | return SpringUtil.getBean(OpenAiImageModel.class); |
| 123 | 128 | case STABLE_DIFFUSION: |
| ... | ... | @@ -135,6 +140,8 @@ public class AiModelFactoryImpl implements AiModelFactory { |
| 135 | 140 | return buildTongYiImagesModel(apiKey); |
| 136 | 141 | case YI_YAN: |
| 137 | 142 | return buildQianFanImageModel(apiKey); |
| 143 | + case ZHI_PU: | |
| 144 | + return buildZhiPuAiImageModel(apiKey, url); | |
| 138 | 145 | case OPENAI: |
| 139 | 146 | return buildOpenAiImageModel(apiKey, url); |
| 140 | 147 | case STABLE_DIFFUSION: |
| ... | ... | @@ -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 | 235 | private ZhiPuAiChatModel buildZhiPuChatModel(String apiKey, String url) { |
| 228 | 236 | url = StrUtil.blankToDefault(url, ZhiPuAiConnectionProperties.DEFAULT_BASE_URL); |
| ... | ... | @@ -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 | 252 | * 可参考 {@link YudaoAiAutoConfiguration#xingHuoChatClient(YudaoAiProperties)} |
| 235 | 253 | */ |
| 236 | 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 | +} | ... | ... |