Jelajahi Sumber

feat(ai): 添加AI用户会话管理功能

- 新增AiUserSessionController提供获取用户会话列表接口
- 实现用户ID参数验证和类型转换逻辑
- 创建AiUserSessionUtil工具类调用AI服务获取会话数据
- 集成AI认证令牌获取和请求头设置
- 添加HTTP客户端超时配置和错误处理机制
- 实现完整的请求响应日志记录和异常捕获
fcw 2 bulan lalu
induk
melakukan
95331f1dc9

+ 78 - 0
alien-store/src/main/java/shop/alien/store/controller/AiUserSessionController.java

@@ -0,0 +1,78 @@
+package shop.alien.store.controller;
+
+import com.alibaba.fastjson2.JSONObject;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.store.util.ai.AiUserSessionUtil;
+
+import java.util.Map;
+
+/**
+ * AI用户会话管理控制器
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Api(tags = {"AI用户会话管理"})
+@CrossOrigin
+@RestController
+@RequestMapping("/aiUserSession")
+@RequiredArgsConstructor
+public class AiUserSessionController {
+
+    private final AiUserSessionUtil aiUserSessionUtil;
+
+    @ApiOperation("获取用户会话列表")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/getUserSessions")
+    public R<JSONObject> getUserSessions(@RequestBody Map<String, Object> request) {
+        log.info("AiUserSessionController.getUserSessions: request={}", request);
+        try {
+            if (request == null || !request.containsKey("user_id")) {
+                return R.fail("用户ID不能为空");
+            }
+
+            Object userIdObj = request.get("user_id");
+            if (userIdObj == null) {
+                return R.fail("用户ID不能为空");
+            }
+
+            Integer userId;
+            if (userIdObj instanceof Integer) {
+                userId = (Integer) userIdObj;
+            } else if (userIdObj instanceof Number) {
+                userId = ((Number) userIdObj).intValue();
+            } else {
+                try {
+                    userId = Integer.parseInt(userIdObj.toString());
+                } catch (NumberFormatException e) {
+                    return R.fail("用户ID格式错误");
+                }
+            }
+
+            if (userId <= 0) {
+                return R.fail("用户ID必须大于0");
+            }
+
+            JSONObject result = aiUserSessionUtil.getUserSessions(userId);
+            if (result != null) {
+                Boolean success = result.getBoolean("success");
+                if (Boolean.TRUE.equals(success)) {
+                    return R.data(result);
+                } else {
+                    String message = result.getString("message");
+                    return R.fail(message != null ? message : "获取用户会话列表失败");
+                }
+            }
+            return R.fail("获取用户会话列表失败");
+        } catch (Exception e) {
+            log.error("AiUserSessionController.getUserSessions ERROR: {}", e.getMessage(), e);
+            return R.fail("获取用户会话列表异常:" + e.getMessage());
+        }
+    }
+}
+

+ 145 - 0
alien-store/src/main/java/shop/alien/store/util/ai/AiUserSessionUtil.java

@@ -0,0 +1,145 @@
+package shop.alien.store.util.ai;
+
+import com.alibaba.fastjson2.JSONObject;
+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.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * AI用户会话工具类
+ * 调用AI服务获取用户会话列表
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Component
+@RefreshScope
+@RequiredArgsConstructor
+public class AiUserSessionUtil {
+
+    private final AiAuthTokenUtil aiAuthTokenUtil;
+
+    private RestTemplate restTemplate;
+
+    @Value("${ai.service.user-session-url:http://124.93.18.180:9000/ai/smart-customer/api/v1/udian_qa/user-sessions}")
+    private String userSessionUrl;
+
+    /**
+     * 初始化 RestTemplate,设置超时时间
+     */
+    @PostConstruct
+    public void initRestTemplate() {
+        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
+        // 设置连接超时时间为 30 秒
+        factory.setConnectTimeout(30000);
+        // 设置读取超时时间为 30 秒
+        factory.setReadTimeout(30000);
+        this.restTemplate = new RestTemplate(factory);
+    }
+
+    /**
+     * 获取用户会话列表
+     *
+     * @param userId 用户ID
+     * @return 用户会话列表响应,包含 success, user_id, total, limit, offset, sessions
+     */
+    public JSONObject getUserSessions(Integer userId) {
+        if (userId == null || userId <= 0) {
+            log.warn("用户ID为空或无效,无法查询会话列表");
+            return buildErrorResponse("用户ID不能为空");
+        }
+
+        // 获取AI服务访问令牌
+        String accessToken = aiAuthTokenUtil.getAccessToken();
+        if (!StringUtils.hasText(accessToken)) {
+            log.error("获取AI服务访问令牌失败,无法调用用户会话接口");
+            return buildErrorResponse("获取AI服务访问令牌失败");
+        }
+
+        try {
+            // 构建请求体
+            Map<String, Object> requestBody = new HashMap<>();
+            requestBody.put("user_id", userId);
+
+            // 构建请求头,添加Authorization
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            headers.set("Authorization", "Bearer " + accessToken);
+
+            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
+
+            log.info("调用AI用户会话接口,用户ID: {}", userId);
+            ResponseEntity<String> response = restTemplate.postForEntity(userSessionUrl, request, String.class);
+
+            if (response != null && response.getStatusCode() == HttpStatus.OK) {
+                String responseBody = response.getBody();
+                log.info("AI用户会话接口响应: {}", responseBody);
+
+                if (StringUtils.hasText(responseBody)) {
+                    JSONObject jsonObject = JSONObject.parseObject(responseBody);
+                    if (jsonObject != null) {
+                        Boolean success = jsonObject.getBoolean("success");
+                        if (Boolean.TRUE.equals(success)) {
+                            log.info("成功获取用户会话列表,用户ID: {}, 总会话数: {}", 
+                                    userId, jsonObject.getInteger("total"));
+                            return jsonObject;
+                        } else {
+                            String message = jsonObject.getString("message");
+                            log.warn("AI接口返回失败,用户ID: {}, message: {}", userId, message);
+                            return jsonObject;
+                        }
+                    }
+                }
+            } else {
+                log.error("AI用户会话接口调用失败,HTTP状态码: {}", 
+                        response != null ? response.getStatusCode() : "null");
+                return buildErrorResponse("AI用户会话接口调用失败");
+            }
+        } catch (HttpClientErrorException e) {
+            log.error("调用AI用户会话接口失败,HTTP客户端错误,状态码: {}, 响应体: {}, 用户ID: {}", 
+                    e.getStatusCode(), e.getResponseBodyAsString(), userId, e);
+            return buildErrorResponse("调用AI用户会话接口失败: " + e.getMessage());
+        } catch (HttpServerErrorException e) {
+            log.error("调用AI用户会话接口失败,HTTP服务器错误,状态码: {}, 响应体: {}, 用户ID: {}", 
+                    e.getStatusCode(), e.getResponseBodyAsString(), userId, e);
+            return buildErrorResponse("调用AI用户会话接口失败: " + e.getMessage());
+        } catch (Exception e) {
+            log.error("调用AI用户会话接口异常,用户ID: {}", userId, e);
+            return buildErrorResponse("调用AI用户会话接口异常: " + e.getMessage());
+        }
+
+        return buildErrorResponse("获取用户会话列表失败");
+    }
+
+    /**
+     * 构建错误响应
+     *
+     * @param message 错误消息
+     * @return 错误响应JSON对象
+     */
+    private JSONObject buildErrorResponse(String message) {
+        JSONObject response = new JSONObject();
+        response.put("success", false);
+        response.put("message", message);
+        response.put("user_id", null);
+        response.put("total", 0);
+        response.put("limit", 20);
+        response.put("offset", 0);
+        response.put("sessions", new java.util.ArrayList<>());
+        return response;
+    }
+}
+