Kaynağa Gözat

feat:ai标签

刘云鑫 2 ay önce
ebeveyn
işleme
5b57d0da50

+ 200 - 0
alien-store/src/main/java/shop/alien/store/controller/AiTagsController.java

@@ -0,0 +1,200 @@
+package shop.alien.store.controller;
+
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.http.*;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+import shop.alien.entity.result.R;
+import shop.alien.store.util.ai.AiAuthTokenUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Slf4j
+@Api(tags = {"ai搜索标签"})
+@CrossOrigin
+@RestController
+@RequestMapping("/aiTags")
+@RequiredArgsConstructor
+@RefreshScope
+public class AiTagsController {
+
+    @Value("${third-part-ai-tags.tags-url:http://124.93.18.180:9000/ai/intelligent-analysis/api/v1/tag/get_store_level_tag}")
+    private String aiTagsUrl;
+
+    @Value("${third-part-ai-tags.tags-rating-url:http://124.93.18.180:9000/ai/intelligent-analysis/api/v1/tag/get_ratings_by_tag}")
+    private String tagsRatingUrl;
+
+    private static final Pattern PATTERN = Pattern.compile("([^()]+)\\((\\d+)\\)");
+
+    private final RestTemplate restTemplate;
+    private final AiAuthTokenUtil aiAuthTokenUtil;
+    /**
+     * 获取店铺标签
+     *
+     * @param storeId 店铺ID
+     * @param page    页码
+     * @param pageNum 每页数量
+     * @return 店铺标签列表
+     */
+    @ApiOperation("获取店铺标签")
+    @RequestMapping("/storeTags")
+    public R storeTags(@RequestParam("store_id") Long storeId,
+                       @RequestParam(value = "page", defaultValue = "1") Integer page,
+                       @RequestParam(value = "pageNum", defaultValue = "10") Integer pageNum) {
+        try {
+            // 1. 获取访问令牌(如果外部接口需要,可添加到请求头)
+            String accessToken = aiAuthTokenUtil.getAccessToken();
+
+            // 2. 构建请求头
+            HttpHeaders aiHeaders = new HttpHeaders();
+            aiHeaders.setContentType(MediaType.APPLICATION_JSON);
+            // 如果外部接口需要 token 认证,添加到请求头(根据实际需求调整)
+            if (accessToken != null && !accessToken.isEmpty()) {
+                aiHeaders.set("Authorization", "Bearer " + accessToken);
+            }
+
+            // 3. 拼接请求 URL 和参数(重点:按外部接口格式拼接)
+            // 使用 String.format 拼接参数,注意参数名对应:page_size 而非 pageNum
+            String requestUrl = String.format("%s?store_id=%d&page=%d&page_size=%d",
+                    aiTagsUrl, storeId, page, pageNum);
+
+            HttpEntity<Void> requestEntity = new HttpEntity<>(aiHeaders);
+            ResponseEntity<String> exchange = restTemplate.exchange(requestUrl, HttpMethod.GET, requestEntity, String.class);
+//            ResponseEntity<String> responseEntity = restTemplate.exchange(requestUrl,"GET",requestEntity,String.class);
+            if(exchange.getStatusCode().is2xxSuccessful()){
+                // 4. 解析响应体(根据外部接口返回格式调整)
+                String responseBody = exchange.getBody();
+                JSONObject jsonObject = JSONObject.parseObject(responseBody);
+                JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("list");
+                if(jsonArray.isEmpty()){
+                    throw new Exception("ai接口失败");
+                }
+                String negativeComment = jsonArray.getJSONObject(0).getString("negative_comment");
+                // 这里简单返回原始字符串(根据实际情况调整)
+                return R.data(parseComment(negativeComment));
+            } else {
+                return R.fail("获取店铺标签失败:" + exchange.getStatusCode());
+            }
+        } catch (Exception e) {
+            // 补充异常处理:捕获调用外部接口的异常,返回友好提示
+            e.printStackTrace(); // 生产环境建议用日志框架记录
+            return R.fail("获取店铺标签失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 根据标签获取店铺评分
+     *
+     * @param storeId 店铺ID
+     * @param tag     标签(如:商品质量差)
+     * @param page    页码
+     * @param pageNum 每页数量(对应外部接口的page_size)
+     * @return 店铺评分列表
+     */
+    @ApiOperation("根据标签获取店铺评价")
+    @RequestMapping("/storeRatingsByTag")
+    public R storeRatingsByTag(@RequestParam("store_id") Long storeId,
+                               @RequestParam("tag") String tag,  // 新增标签参数,必填
+                               @RequestParam(value = "page", defaultValue = "1") Integer page,
+                               @RequestParam(value = "pageNum", defaultValue = "10") Integer pageNum) {
+        try {
+            // 1. 获取访问令牌(复用原有逻辑)
+            String accessToken = aiAuthTokenUtil.getAccessToken();
+
+            // 2. 构建请求头
+            HttpHeaders aiHeaders = new HttpHeaders();
+            aiHeaders.setContentType(MediaType.APPLICATION_JSON);
+            // 添加token认证(如有需要)
+            if (accessToken != null && !accessToken.isEmpty()) {
+                aiHeaders.set("Authorization", "Bearer " + accessToken);
+            }
+
+            // 3. 拼接请求URL和参数(核心调整:新增tag参数,匹配外部接口参数名)
+            String requestUrl = String.format("%s?store_id=%d&tag=%s&page=%d&page_size=%d",
+                    tagsRatingUrl, storeId, tag, page, pageNum);
+
+            // 4. 发送GET请求
+            HttpEntity<Void> requestEntity = new HttpEntity<>(aiHeaders);
+            ResponseEntity<String> exchange = restTemplate.exchange(requestUrl, HttpMethod.GET, requestEntity, String.class);
+
+            // 5. 处理响应结果
+            if (exchange.getStatusCode().is2xxSuccessful()) {
+                String responseBody = exchange.getBody();
+                JSONObject jsonObject = JSONObject.parseObject(responseBody);
+                JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("list");
+                if(jsonArray.isEmpty()){
+                    throw new Exception("ai接口失败");
+                }
+
+                // 保持和原有接口一致的返回格式:将data节点重新封装(可根据实际需求调整)
+                return R.data(jsonArray);
+            } else {
+                return R.fail("获取店铺评价失败:" + exchange.getStatusCode());
+            }
+        } catch (Exception e) {
+            // 异常日志记录(生产环境建议替换为日志框架,如logback/log4j2)
+            e.printStackTrace();
+            return R.fail("获取店铺评分失败:" + e.getMessage());
+        }
+    }
+
+    public static List<JSONObject> parseComment(String negativeComment) {
+        // 最终返回的结果列表
+        List<JSONObject> resultList = new ArrayList<>();
+        // 临时存储标签-数值的映射,用于累加相同标签的数值
+        Map<String, Integer> tagCountMap = new HashMap<>();
+
+        // 1. 空值校验:避免空字符串/Null导致后续处理异常
+        if (negativeComment == null || negativeComment.trim().isEmpty()) {
+            return resultList;
+        }
+
+        // 2. 按分号;分割成多个片段(如:["差评(1)", "商品质量差(1),商品质量差(1)"])
+        String[] semicolonParts = negativeComment.split(";");
+        String trimPart = semicolonParts[1].trim();
+
+            // 3. 按逗号,分割当前片段内的多个标签(如:["商品质量差(1)", "商品质量差(1)"])
+            String[] commaParts = trimPart.split(",");
+            for (String tagWithNum : commaParts) {
+                String trimTag = tagWithNum.trim();
+                if (trimTag.isEmpty()) {
+                    continue;
+                }
+
+                // 4. 正则匹配标签和数值(如:"差评(1)" → 标签=差评,数值=1)
+                Matcher matcher = PATTERN.matcher(trimTag);
+                if (matcher.find()) {
+                    String label = matcher.group(1).trim(); // 标签(如:差评)
+                    int value = Integer.parseInt(matcher.group(2)); // 数值(如:1)
+
+                    // 5. 累加相同标签的数值
+                    tagCountMap.put(label, tagCountMap.getOrDefault(label, 0) + value);
+                }
+            }
+
+        // 6. 将Map转换为指定的List<JSONObject>格式
+        for (Map.Entry<String, Integer> entry : tagCountMap.entrySet()) {
+            JSONObject jsonObj = new JSONObject();
+            jsonObj.put("label", entry.getKey());
+            jsonObj.put("value", String.valueOf(entry.getValue())); // value转为字符串,匹配示例格式
+            resultList.add(jsonObj);
+        }
+
+        return resultList;
+    }
+}