From 3ca3e8e02302a8bb7aa18c5b320f74ad20dfa054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B9=90=E5=8A=9B=E9=BD=90?= <162269739+lanceyq@users.noreply.github.com> Date: Tue, 10 Feb 2026 13:46:09 +0800 Subject: [PATCH] Fix/bug en zh (#385) * [fix]The log retains genuine alerts and errors, while filtering out unnecessary noise. * [fix]Scenario English and Chinese, emotion specifications * [fix]Change the "no data" scenario from 0.0 to None * [fix]The emotional health indicators, emotional advice, and emotional distribution analysis are all linked together. * [fix]The emotional health indicators, emotional advice, and emotional distribution analysis are all linked together. * [fix]Separate expected errors from unexpected errors --- api/app/controllers/emotion_controller.py | 44 ++++++++++++++++--- .../repositories/neo4j/emotion_repository.py | 11 ++--- api/app/services/emotion_analytics_service.py | 31 +++++++++++++ 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/api/app/controllers/emotion_controller.py b/api/app/controllers/emotion_controller.py index d17b998c..eb2436d2 100644 --- a/api/app/controllers/emotion_controller.py +++ b/api/app/controllers/emotion_controller.py @@ -244,16 +244,46 @@ async def get_emotion_suggestions( ) if data is None: - # 缓存不存在或已过期 + # 缓存不存在或已过期,自动触发生成 api_logger.info( - f"用户 {request.end_user_id} 的建议缓存不存在或已过期", + f"用户 {request.end_user_id} 的建议缓存不存在或已过期,自动生成新建议", extra={"end_user_id": request.end_user_id} ) - return fail( - BizCode.NOT_FOUND, - "建议缓存不存在或已过期,请右上角刷新生成新建议", - "" - ) + try: + data = await emotion_service.generate_emotion_suggestions( + end_user_id=request.end_user_id, + db=db, + language=language + ) + # 保存到缓存 + await emotion_service.save_suggestions_cache( + end_user_id=request.end_user_id, + suggestions_data=data, + db=db, + expires_hours=24 + ) + except (ValueError, KeyError) as gen_e: + # 预期内的业务异常:配置缺失、数据格式问题等 + api_logger.warning( + f"自动生成建议失败(业务异常): {str(gen_e)}", + extra={"end_user_id": request.end_user_id} + ) + return fail( + BizCode.NOT_FOUND, + f"自动生成建议失败: {str(gen_e)}", + "" + ) + except Exception as gen_e: + # 非预期异常:记录完整 traceback 便于排查 + api_logger.error( + f"自动生成建议时发生未预期异常: {str(gen_e)}", + extra={"end_user_id": request.end_user_id}, + exc_info=True + ) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"生成建议时发生内部错误: {str(gen_e)}" + ) api_logger.info( "个性化建议获取成功(缓存)", diff --git a/api/app/repositories/neo4j/emotion_repository.py b/api/app/repositories/neo4j/emotion_repository.py index e39968ac..cc8864a8 100644 --- a/api/app/repositories/neo4j/emotion_repository.py +++ b/api/app/repositories/neo4j/emotion_repository.py @@ -73,11 +73,11 @@ class EmotionRepository: params["emotion_type"] = emotion_type if start_date: - where_clauses.append("s.created_at >= $start_date") + where_clauses.append("s.created_at IS NOT NULL AND datetime(s.created_at) >= datetime($start_date)") params["start_date"] = start_date if end_date: - where_clauses.append("s.created_at <= $end_date") + where_clauses.append("s.created_at IS NOT NULL AND datetime(s.created_at) <= datetime($end_date)") params["end_date"] = end_date where_str = " AND ".join(where_clauses) @@ -211,17 +211,18 @@ class EmotionRepository: # 计算起始日期(使用字符串比较,避免时区问题) start_date = (datetime.now() - timedelta(days=days)).isoformat() - # 优化的 Cypher 查询:使用字符串比较避免时区问题 + # 使用 datetime() 函数进行时间比较,与其他查询保持一致 query = """ MATCH (s:Statement) WHERE s.end_user_id = $end_user_id AND s.emotion_type IS NOT NULL - AND s.created_at >= $start_date + AND s.created_at IS NOT NULL + AND datetime(s.created_at) >= datetime($start_date) RETURN s.id as statement_id, s.emotion_type as emotion_type, s.emotion_intensity as emotion_intensity, s.created_at as created_at - ORDER BY s.created_at ASC + ORDER BY datetime(s.created_at) ASC """ try: diff --git a/api/app/services/emotion_analytics_service.py b/api/app/services/emotion_analytics_service.py index 9d60d6bb..d78dc20c 100644 --- a/api/app/services/emotion_analytics_service.py +++ b/api/app/services/emotion_analytics_service.py @@ -388,6 +388,16 @@ class EmotionAnalyticsService: time_range=time_range ) + # 如果指定时间范围内没有数据,尝试更大的时间范围 + if not emotions and time_range != "90d": + logger.info(f"用户 {end_user_id} 在 {time_range} 内无数据,尝试90天范围") + emotions = await self.emotion_repo.get_emotions_in_range( + end_user_id=end_user_id, + time_range="90d" + ) + if emotions: + time_range = "90d" + # 如果没有数据,返回默认值 if not emotions: logger.warning(f"用户 {end_user_id} 在时间范围 {time_range} 内没有情绪数据") @@ -574,6 +584,27 @@ class EmotionAnalyticsService: time_range="30d" ) + # 3.1 如果30天内没有数据,尝试获取90天的数据 + if not emotions: + logger.info(f"用户 {end_user_id} 30天内无情绪数据,尝试获取90天数据") + emotions = await self.emotion_repo.get_emotions_in_range( + end_user_id=end_user_id, + time_range="90d" + ) + health_data = await self.calculate_emotion_health_index(end_user_id, time_range="90d") + + # 3.2 如果仍然没有时间范围内的数据,从情绪标签统计获取(无时间过滤) + if not emotions: + logger.info(f"用户 {end_user_id} 90天内也无情绪数据,从标签统计获取全量数据") + tags_data = await self.get_emotion_tags(end_user_id=end_user_id) + if tags_data.get("total_count", 0) > 0: + # 用标签统计数据构建简化的 health_data + health_data["emotion_distribution"] = { + tag["emotion_type"]: tag["count"] + for tag in tags_data.get("tags", []) + } + health_data["total_emotion_count"] = tags_data["total_count"] + # 4. 分析情绪模式 patterns = self._analyze_emotion_patterns(emotions)