浏览代码

Merge remote-tracking branch 'origin/sit-shenzhen' into sit-shenzhen

penghao 5 天之前
父节点
当前提交
a1bc6c866e

+ 7 - 0
alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivityDTO.java

@@ -2,6 +2,7 @@ package shop.alien.entity.storePlatform.vo;
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.JsonNode;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -73,5 +74,11 @@ public class StoreOperationalActivityDTO {
     @ApiModelProperty(value = "页数")
     private Integer pageSize;
 
+    @ApiModelProperty(value = "上传图片的方式: 1-用户本地上传,2-使用用户输入的描述AI生成图片")
+    private Integer uploadImgType;
+
+    @ApiModelProperty(value = "用户输入的AI描述")
+    private JsonNode imgDescribe;
+
 }
 

+ 57 - 0
alien-second/src/main/java/shop/alien/second/util/JsonUtils.java

@@ -31,4 +31,61 @@ public class JsonUtils {
             throw new RuntimeException("解析JSON失败", e);
         }
     }
+
+
+    /**
+     * 从图片对象中获取URL(支持多种可能的字段名)
+     * 例如:从 banner_image 或 vertical_image 对象中获取 url 或 imgUrl
+     *
+     * @param jsonString JSON字符串
+     * @param imageObjectKey 图片对象的key,如 "banner_image" 或 "vertical_image"
+     * @return 图片URL字符串,如果不存在则返回null
+     */
+    public static String getImageUrlFromObject(String jsonString, String imageObjectKey) {
+        try {
+            JsonNode jsonNode = objectMapper.readTree(jsonString);
+            JsonNode dataNode = jsonNode.get("data");
+            if (dataNode == null) {
+                return null;
+            }
+            
+            JsonNode imageNode = dataNode.get(imageObjectKey);
+            if (imageNode == null || !imageNode.isObject()) {
+                return null;
+            }
+            
+            // 尝试常见的URL字段名
+            String[] possibleUrlFields = {"url", "imgUrl", "imageUrl", "img_url", "image_url"};
+            for (String field : possibleUrlFields) {
+                JsonNode urlNode = imageNode.get(field);
+                if (urlNode != null && urlNode.isTextual()) {
+                    return urlNode.asText();
+                }
+            }
+            
+            return null;
+        } catch (Exception e) {
+            throw new RuntimeException("解析图片URL失败,对象key: " + imageObjectKey, e);
+        }
+    }
+
+    /**
+     * 获取banner图片URL
+     *
+     * @param jsonString JSON字符串
+     * @return banner图片URL
+     */
+    public static String getBannerImageUrl(String jsonString) {
+        return getImageUrlFromObject(jsonString, "banner_image");
+    }
+
+    /**
+     * 获取竖版图片URL
+     *
+     * @param jsonString JSON字符串
+     * @return 竖版图片URL
+     */
+    public static String getVerticalImageUrl(String jsonString) {
+        return getImageUrlFromObject(jsonString, "vertical_image");
+    }
 }

+ 2 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/controller/OperationalActivityController.java

@@ -36,6 +36,8 @@ public class OperationalActivityController {
     public R<String> createActivity(@RequestBody StoreOperationalActivityDTO dto) {
         log.info("OperationalActivityController.createActivity: dto={}", dto);
         try {
+            log.warn("用户输入的图片描述{}",dto.getImgDescribe());
+
             int result = activityService.createActivity(dto);
             if (result > 0) {
                 return R.success("活动创建成功");

+ 35 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/feign/AlienAIFeign.java

@@ -0,0 +1,35 @@
+package shop.alien.storeplatform.feign;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.http.MediaType;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.bind.annotation.*;
+
+@FeignClient(url = "${feign.alienAI.url}", name = "alien-AI")
+public interface AlienAIFeign {
+
+    /**
+     * 登录接口 - 获取access_token
+     *
+     * @param username 用户名
+     * @param password 密码
+     * @return JsonNode 响应体,包含access_token
+     */
+    @PostMapping(value = "/ai/user-auth-core/api/v1/auth/login",
+            consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    JsonNode login(@RequestBody MultiValueMap<String, String> formData);
+
+    /**
+     * 使用 JsonNode 灵活调用接口 - 生成促销图片
+     *
+     * @param authorization Bearer token,格式为 "Bearer {access_token}"
+     * @param requestBody JsonNode 请求体,可以灵活构建
+     * @return JsonNode 响应体,可以灵活解析
+     */
+    @PostMapping(value = "/ai/life-manager/api/v1/promotion_image/generate",
+                 consumes = MediaType.APPLICATION_JSON_VALUE,
+                 produces = MediaType.APPLICATION_JSON_VALUE)
+    JsonNode generatePromotionImage(@RequestHeader("Authorization") String authorization, @RequestBody JsonNode requestBody);
+}

+ 68 - 2
alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/OperationalActivityServiceImpl.java

@@ -5,10 +5,16 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
 import shop.alien.entity.store.LifeDiscountCoupon;
 import shop.alien.entity.store.LifeUser;
 import shop.alien.entity.store.StoreImg;
@@ -19,6 +25,7 @@ import shop.alien.entity.storePlatform.vo.StoreOperationalActivityVO;
 import shop.alien.mapper.LifeDiscountCouponMapper;
 import shop.alien.mapper.StoreImgMapper;
 import shop.alien.mapper.storePlantform.StoreOperationalActivityMapper;
+import shop.alien.storeplatform.feign.AlienAIFeign;
 import shop.alien.storeplatform.service.OperationalActivityService;
 
 import java.text.SimpleDateFormat;
@@ -55,13 +62,21 @@ public class OperationalActivityServiceImpl implements OperationalActivityServic
 
     private final LifeDiscountCouponMapper lifeDiscountCouponMapper;
 
+    private final AlienAIFeign alienAIFeign;
+
+    @Value("${ai.aiAccount}")
+    private String aiAccount;
+
+    @Value("${ai.aiPassword}")
+    private String aiPassword;
+
     @Override
     public int createActivity(StoreOperationalActivityDTO dto) {
         log.info("OperationalActivityServiceImpl.createActivity: dto={}", dto);
-        
+
         StoreOperationalActivity activity = new StoreOperationalActivity();
         BeanUtils.copyProperties(dto, activity);
-        
+
         // 设置默认值
         if (activity.getParticipationLimit() == null) {
             activity.setParticipationLimit(0);
@@ -71,6 +86,57 @@ public class OperationalActivityServiceImpl implements OperationalActivityServic
         }
         Integer result = activityMapper.insert(activity);
         if (result > 0) {
+            // 使用用户描述让AI生成图片。
+            if (dto.getUploadImgType()==2) {
+                try {
+                    // 先调用登录接口获取access_token
+                    MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
+                    formData.add("username", aiAccount);
+                    formData.add("password", aiPassword);
+                    JsonNode loginResponse = alienAIFeign.login(formData);
+
+                    String accessToken = null;
+                    if (loginResponse != null && loginResponse.has("data")) {
+                        JsonNode data = loginResponse.get("data");
+                        if (data.has("access_token")) {
+                            accessToken = data.get("access_token").asText();
+                        }
+                    }
+                    
+                    if (accessToken == null || accessToken.isEmpty()) {
+                        log.error("获取AI服务access_token失败,无法生成促销图片");
+                    } else {
+                        ObjectMapper objectMapper = new ObjectMapper();
+                        ObjectNode requestBody = objectMapper.createObjectNode();
+                        requestBody.put("text", dto.getImgDescribe());
+                        // 调用接口,传递Bearer token
+                        String authorization = "Bearer " + accessToken;
+                        JsonNode response = alienAIFeign.generatePromotionImage(authorization, requestBody);
+                        // 解析响应
+                        if (response.has("data")) {
+                            JsonNode data = response.get("data");
+                            // 提取横向图(banner_image)的图片URL
+                            if (data.has("banner_image")) {
+                                JsonNode bannerImage = data.get("banner_image");
+                                if (bannerImage.has("image_url") && !bannerImage.get("image_url").isNull()) {
+                                    String bannerImageUrl = bannerImage.get("image_url").asText();
+                                    dto.getActivityTitleImg().setImgUrl(bannerImageUrl);
+                                }
+                            }
+                            // 提取竖向图(vertical_image)的图片URL
+                            if (data.has("vertical_image")) {
+                                JsonNode verticalImage = data.get("vertical_image");
+                                if (verticalImage.has("image_url") && !verticalImage.get("image_url").isNull()) {
+                                    String verticalImageUrl = verticalImage.get("image_url").asText();
+                                    dto.getActivityDetailImg().setImgUrl(verticalImageUrl);
+                                }
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    log.error("调用AI服务生成促销图片失败", e);
+                }
+            }
             dto.getActivityTitleImg().setBusinessId(activity.getId());
             dto.getActivityTitleImg().setImgType(26);
             imgMapper.insert(dto.getActivityTitleImg());