From dc7ea97a73d8e2f91749f350c1d6a3b92e6e874c Mon Sep 17 00:00:00 2001 From: malog <2153315236@qq.com> Date: Mon, 1 Dec 2025 17:32:54 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DAI=E5=88=86?= =?UTF-8?q?=E6=9E=90=E8=BF=87=E7=A8=8B=E4=B8=AD=E5=AD=A6=E4=B9=A0=E5=BB=BA?= =?UTF-8?q?=E8=AE=AE=E9=87=8D=E5=A4=8D=E6=B7=BB=E5=8A=A0=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/achobeta/config/RagConfig.java | 10 ---------- .../service/impl/LearningDynamicsServiceImpl.java | 13 +++++++++---- .../trigger/http/LearningOverviewController.java | 8 +++++++- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/refine-app/src/main/java/com/achobeta/config/RagConfig.java b/refine-app/src/main/java/com/achobeta/config/RagConfig.java index 6cd9ebf..47ab998 100644 --- a/refine-app/src/main/java/com/achobeta/config/RagConfig.java +++ b/refine-app/src/main/java/com/achobeta/config/RagConfig.java @@ -100,14 +100,4 @@ public List retrieve(Query query) { }; } - // 注释掉PgVector相关的表操作方法 - // private void truncateEmbeddingTable() { - // // TODO: 使用Weaviate实现数据清理 - // log.warn("RagConfig暂未实现Weaviate数据清理"); - // } - - // private void deleteAllEmbeddingData() { - // // TODO: 使用Weaviate实现数据删除 - // log.warn("RagConfig暂未实现Weaviate数据删除"); - // } } \ No newline at end of file diff --git a/refine-domain/src/main/java/com/achobeta/domain/rag/service/impl/LearningDynamicsServiceImpl.java b/refine-domain/src/main/java/com/achobeta/domain/rag/service/impl/LearningDynamicsServiceImpl.java index be3aa72..854853b 100644 --- a/refine-domain/src/main/java/com/achobeta/domain/rag/service/impl/LearningDynamicsServiceImpl.java +++ b/refine-domain/src/main/java/com/achobeta/domain/rag/service/impl/LearningDynamicsServiceImpl.java @@ -50,6 +50,7 @@ public List analyzeUserLearningDynamics(String userId) { // 3. 使用AI分析学习动态 List dynamics = new ArrayList<>(); StringBuilder responseBuilder = new StringBuilder(); + boolean hasProcessedResponse = false; // 防止重复处理 // 异步执行AI分析任务,解析题目并生成学习动态 CompletableFuture aiAnalysis = CompletableFuture.runAsync(() -> { @@ -60,14 +61,18 @@ public List analyzeUserLearningDynamics(String userId) { // 收集所有响应片段 responseBuilder.append(response); - // 检查是否收到完整的JSON响应 + // 检查是否收到完整的JSON响应,并且还没有处理过 String currentResponse = responseBuilder.toString(); - if (isCompleteJsonResponse(currentResponse)) { + if (!hasProcessedResponse && isCompleteJsonResponse(currentResponse)) { log.info("检测到完整JSON响应,开始解析"); // 解析完整的AI返回的JSON格式学习动态 List parsedDynamics = parseAIResponse(currentResponse); - dynamics.addAll(parsedDynamics); - log.info("成功解析AI响应,获得{}条动态", parsedDynamics.size()); + synchronized (dynamics) { + if (dynamics.isEmpty()) { // 确保只添加一次 + dynamics.addAll(parsedDynamics); + log.info("成功解析AI响应,获得{}条动态", parsedDynamics.size()); + } + } } } catch (Exception e) { log.error("解析AI分析结果失败:{}", response, e); diff --git a/refine-trigger/src/main/java/com/achobeta/trigger/http/LearningOverviewController.java b/refine-trigger/src/main/java/com/achobeta/trigger/http/LearningOverviewController.java index 3b48196..b5816cf 100644 --- a/refine-trigger/src/main/java/com/achobeta/trigger/http/LearningOverviewController.java +++ b/refine-trigger/src/main/java/com/achobeta/trigger/http/LearningOverviewController.java @@ -86,15 +86,21 @@ public Response> getStudyDynamic(){ // 提取描述信息 result = dynamics.stream() .map(dynamic -> { - log.debug("处理学习动态: type={}, title={}, description={}", + log.info("处理学习动态: type={}, title={}, description={}", dynamic.getType(), dynamic.getTitle(), dynamic.getDescription()); return dynamic.getDescription(); }) .filter(description -> description != null && !description.trim().isEmpty()) + .distinct() // 去重,防止重复的描述 .collect(java.util.stream.Collectors.toList()); log.info("最终返回描述数量: {}", result.size()); + // 打印每个描述用于调试 + for (int i = 0; i < result.size(); i++) { + log.info("描述[{}]: {}", i, result.get(i)); + } + } catch (Exception e) { log.error("getStudyDynamic error", e); return Response.CUSTOMIZE_ERROR(GET_STUDY_DYNAMIC_FAIL); From c5e4d20711ed713057c1a4e3d03191077448c8f6 Mon Sep 17 00:00:00 2001 From: malog <2153315236@qq.com> Date: Mon, 1 Dec 2025 17:52:40 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E8=BF=BD?= =?UTF-8?q?=E8=B8=AA=E7=94=A8=E6=88=B7=E6=95=B0=E6=8D=AE=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/LearningAnalysisService.java | 27 ++++++-- .../http/LearningOverviewController.java | 68 +++++++++++++++---- 2 files changed, 78 insertions(+), 17 deletions(-) diff --git a/refine-domain/src/main/java/com/achobeta/domain/rag/service/impl/LearningAnalysisService.java b/refine-domain/src/main/java/com/achobeta/domain/rag/service/impl/LearningAnalysisService.java index b697c3e..cb539a2 100644 --- a/refine-domain/src/main/java/com/achobeta/domain/rag/service/impl/LearningAnalysisService.java +++ b/refine-domain/src/main/java/com/achobeta/domain/rag/service/impl/LearningAnalysisService.java @@ -1,5 +1,6 @@ package com.achobeta.domain.rag.service.impl; +import com.achobeta.domain.IRedisService; import com.achobeta.domain.rag.service.IVectorService; import com.achobeta.domain.rag.service.ILearningDynamicsService; import com.achobeta.domain.rag.model.valobj.LearningInsightVO; @@ -27,6 +28,9 @@ public class LearningAnalysisService { @Autowired private ILearningDynamicsService learningDynamicsService; + @Autowired + private IRedisService redisService; + /** * 用户登录时触发的学习动态分析 * @@ -42,10 +46,25 @@ public void onUserLogin(String userId) { if (dynamics != null && !dynamics.isEmpty()) { log.info("用户登录学习动态分析完成,userId:{} 动态数量:{}", userId, dynamics.size()); - - // 可以在这里将分析结果存储到缓存或数据库中,供前端查询使用 - // 例如:存储到Redis中,key为 "user_dynamics:" + userId - + + // 将分析结果存储到Redis缓存中,供前端快速查询使用 + String cacheKey = "user_dynamics:" + userId; + try { + // 提取描述信息并缓存 + List descriptions = dynamics.stream() + .map(LearningDynamicVO::getDescription) + .filter(desc -> desc != null && !desc.trim().isEmpty()) + .distinct() + .collect(Collectors.toList()); + + // 缓存2小时,避免数据过期 (7200秒 = 2小时) + redisService.setValue(cacheKey, descriptions, 7200 * 1000); + log.info("学习动态缓存成功,userId:{} 描述数量:{}", userId, descriptions.size()); + + } catch (Exception e) { + log.error("学习动态缓存失败,userId:{}", userId, e); + } + } else { log.info("用户登录学习动态分析完成,但未生成有效动态,userId:{}", userId); } diff --git a/refine-trigger/src/main/java/com/achobeta/trigger/http/LearningOverviewController.java b/refine-trigger/src/main/java/com/achobeta/trigger/http/LearningOverviewController.java index b5816cf..4bbe0a8 100644 --- a/refine-trigger/src/main/java/com/achobeta/trigger/http/LearningOverviewController.java +++ b/refine-trigger/src/main/java/com/achobeta/trigger/http/LearningOverviewController.java @@ -35,9 +35,11 @@ public class LearningOverviewController { private final ILearningOverviewService service; private final ILearningDynamicsService learningDynamicsService; + private final IRedisService redisService; /** * 获取学习概览 + * * @return 学习概览 */ @GetMapping("/get_overview") @@ -62,49 +64,89 @@ public Response getOverview() { /** * 获取学习动态 + * * @return 学习动态描述列表 */ @GetMapping("/get_study_dynamic") @GlobalInterception - public Response> getStudyDynamic(){ + public Response> getStudyDynamic() { String userId = UserContext.getUserId(); List result = null; try { log.info("用户获取学习动态,userId:{}", userId); + + // 优先从缓存获取数据 + String cacheKey = "user_dynamics:" + userId; + log.info("尝试从缓存获取数据,cacheKey: {}", cacheKey); - // 获取学习动态数据 - List dynamics = + Object cachedData = redisService.getValue(cacheKey); + log.info("缓存查询结果: {}", cachedData != null ? "有数据" : "无数据"); + + if (cachedData != null) { + log.info("从缓存获取学习动态,userId: {}, 数据类型: {}", userId, cachedData.getClass().getSimpleName()); + try { + if (cachedData instanceof List) { + result = (List) cachedData; + log.info("缓存命中,返回{}条学习动态描述", result.size()); + return Response.SYSTEM_SUCCESS(result); + } else if (cachedData instanceof String) { + // 如果是字符串,尝试解析为JSON + String jsonStr = (String) cachedData; + log.info("缓存数据为字符串,尝试解析JSON: {}", jsonStr); + // 这里可以添加JSON解析逻辑 + } else { + log.warn("缓存数据类型不匹配,期望List,实际: {}, 数据内容: {}", + cachedData.getClass().getSimpleName(), cachedData); + } + } catch (Exception e) { + log.error("处理缓存数据失败", e); + } + } + + log.info("缓存未命中,实时分析学习动态,userId: {}", userId); + + // 缓存未命中,实时获取学习动态数据 + List dynamics = learningDynamicsService.analyzeUserLearningDynamics(userId); - + log.info("获取到学习动态数量: {}", dynamics != null ? dynamics.size() : 0); - + if (dynamics == null || dynamics.isEmpty()) { log.warn("未获取到学习动态数据,userId: {}", userId); return Response.SYSTEM_SUCCESS(java.util.Collections.emptyList()); } - + // 提取描述信息 result = dynamics.stream() .map(dynamic -> { - log.info("处理学习动态: type={}, title={}, description={}", + log.debug("处理学习动态: type={}, title={}, description={}", dynamic.getType(), dynamic.getTitle(), dynamic.getDescription()); return dynamic.getDescription(); }) .filter(description -> description != null && !description.trim().isEmpty()) .distinct() // 去重,防止重复的描述 .collect(java.util.stream.Collectors.toList()); - + log.info("最终返回描述数量: {}", result.size()); - - // 打印每个描述用于调试 - for (int i = 0; i < result.size(); i++) { - log.info("描述[{}]: {}", i, result.get(i)); + + // 将结果缓存起来,缓存30分钟 (1800秒 = 30分钟) + try { + log.info("准备缓存学习动态结果,cacheKey: {}, 数据: {}", cacheKey, result); + redisService.setValue(cacheKey, result, 1800 * 1000); + log.info("学习动态结果已缓存,userId: {}, 缓存时间: 30分钟", userId); + + // 验证缓存是否成功 + Object verifyCache = redisService.getValue(cacheKey); + log.info("缓存验证结果: {}", verifyCache != null ? "缓存成功" : "缓存失败"); + } catch (Exception e) { + log.error("缓存学习动态结果失败,userId: {}", userId, e); } - + } catch (Exception e) { log.error("getStudyDynamic error", e); return Response.CUSTOMIZE_ERROR(GET_STUDY_DYNAMIC_FAIL); } return Response.SYSTEM_SUCCESS(result); } + }