Explorar o código

fix: ImageServiceImpl 下载 Qwen AI 图片到本地目录

- 修复 imageUrl 判空逻辑反转的 bug
- 新增图片下载功能:从临时 URL 下载保存到 fileDirectory/yyyyMM/uuid.png
- 返回本地 baseUrl 访问地址,下载失败降级返回原始 URL

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
tanlie hai 2 semanas
pai
achega
ade8288036

+ 7 - 0
wishing-platform/platform-service/platform-service-mobile/pom.xml

@@ -66,6 +66,13 @@
             <groupId>org.springframework.ai</groupId>
             <artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
         </dependency>
+        <!-- Source: https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dashscope-sdk-java</artifactId>
+            <version>2.22.22</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
     <build>
         <finalName>wishing-mobile</finalName>

+ 13 - 0
wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/service/ImageService.java

@@ -0,0 +1,13 @@
+package cn.qinys.platform.mobile.service;
+
+/**
+* @author lie tan
+* @description 
+* @date 2026-06-13 23:46
+**/
+public interface ImageService {
+
+
+    public String getImageUrl(String msg);
+
+}

+ 61 - 0
wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/service/impl/ImageServiceImpl.java

@@ -0,0 +1,61 @@
+package cn.qinys.platform.mobile.service.impl;
+
+import cn.qinys.platform.mobile.service.ImageService;
+import cn.qinys.platform.mobile.util.QwenImage;
+import cn.qinys.platform.properties.SystemProperties;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.UUID;
+
+/**
+ * @author lie tan
+ * @description 图片服务:调用 AI 生成图片,下载到本地目录,返回本地访问 URL
+ * @date 2026-06-13 23:46
+ **/
+@Slf4j
+@Service
+public class ImageServiceImpl implements ImageService {
+
+    @Resource
+    private SystemProperties systemProperties;
+
+    @Override
+    public String getImageUrl(String msg) {
+        // 调用 Qwen 生成图片
+        String imageUrl = QwenImage.call(msg);
+        if (imageUrl == null) {
+            log.error("QwenImage.call returned null");
+            return null;
+        }
+        log.info("Qwen generated image url: {}", imageUrl);
+
+        // 下载图片到本地目录
+        try {
+            String ym = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
+            String fileName = UUID.randomUUID().toString().replace("-", "") + ".png";
+            Path targetDir = Path.of(systemProperties.getFileDirectory(), ym);
+            Files.createDirectories(targetDir);
+            Path targetFile = targetDir.resolve(fileName);
+
+            try (InputStream in = URI.create(imageUrl).toURL().openStream()) {
+                Files.copy(in, targetFile, StandardCopyOption.REPLACE_EXISTING);
+            }
+
+            String localUrl = systemProperties.getBaseUrl() + ym + "/" + fileName;
+            log.info("Image saved to: {}", localUrl);
+            return localUrl;
+        } catch (Exception e) {
+            log.error("Failed to download image from: {}", imageUrl, e);
+            return imageUrl;
+        }
+    }
+}

+ 62 - 0
wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/util/QwenImage.java

@@ -0,0 +1,62 @@
+package cn.qinys.platform.mobile.util;
+
+import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
+import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
+import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
+import com.alibaba.dashscope.common.MultiModalMessage;
+import com.alibaba.dashscope.common.Role;
+import com.alibaba.dashscope.utils.Constants;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+public class QwenImage {
+
+    static {
+        // 以下为华北2(北京)地域的URL,各地域的URL不同。
+        Constants.baseHttpApiUrl = "https://dashscope.aliyuncs.com/api/v1";
+    }
+
+    // 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
+    static String apiKey = "sk-a52acbfc944e495ead45b1c54b5659fb";
+
+    /**
+     * String msg = """
+     * 我的名字叫400块,是一只5岁的英短小猫,我喜欢吃鸡肉冻干
+     * 我现在在一个许愿树下许愿,希望我身体健康,天天都有冻干吃,吃多了也不长胖
+     * """;
+     *
+     * @param msg
+     * @return
+     */
+    public static String call(String msg) {
+        MultiModalConversation conv = new MultiModalConversation();
+        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
+                .content(List.of(Collections.singletonMap("text", msg))).build();
+        Map<String, Object> parameters = new HashMap<>();
+        parameters.put("watermark", false);
+        parameters.put("prompt_extend", true);
+        parameters.put("negative_prompt", "低分辨率,低画质,肢体畸形,手指畸形,画面过饱和,蜡像感,人脸无细节,过度光滑,画面具有AI感。构图混乱。文字模糊,扭曲。");
+        parameters.put("size", "1024*1024");
+
+        MultiModalConversationParam param = MultiModalConversationParam.builder()
+                .apiKey(apiKey)
+                .model("qwen-image-2.0-pro")
+                .messages(Collections.singletonList(userMessage))
+                .parameters(parameters)
+                .build();
+        try {
+            MultiModalConversationResult result = conv.call(param);
+            return result.getOutput().getChoices().getFirst().getMessage().getContent().getFirst().get("image").toString();
+        } catch (Exception e) {
+            log.error("get QwenImage error", e);
+        }
+        return null;
+    }
+
+
+}