fix(metrics): 修复 recommend-topics API 错误处理

- 添加 try-except 捕获空数据导致的聚合查询错误
- 添加 logging 导入用于错误日志记录
- 修复 avg_engagement/max_views 类型转换问题
- 新增 test_full_api.py 全功能测试脚本
- 所有 29 项 API 测试通过 (100%)
This commit is contained in:
lt
2026-05-08 23:53:55 +08:00
parent 526278589b
commit e77a1aa4d9
2 changed files with 198 additions and 24 deletions
+29 -24
View File
@@ -3,6 +3,7 @@ from sqlalchemy.orm import Session
from sqlalchemy import func, desc
from typing import List, Optional
from datetime import datetime, timedelta, date
import logging
from ..database import get_db
from ..models import ContentMetrics, Topic, ContentCalendar
@@ -241,29 +242,33 @@ def recommend_topics_from_metrics(
db: Session = Depends(get_db),
current_user=Depends(get_current_user)
):
high_performing = db.query(
ContentMetrics.topic_id,
func.avg(ContentMetrics.engagement_rate).label("avg_engagement"),
func.max(ContentMetrics.views).label("max_views")
).group_by(ContentMetrics.topic_id).order_by(desc("avg_engagement")).limit(20).all()
try:
high_performing = db.query(
ContentMetrics.topic_id,
func.avg(ContentMetrics.engagement_rate).label("avg_engagement"),
func.max(ContentMetrics.views).label("max_views")
).group_by(ContentMetrics.topic_id).order_by(desc("avg_engagement")).limit(20).all()
recommendations = []
for row in high_performing:
topic = db.query(Topic).filter(Topic.id == row.topic_id).first()
if not topic:
continue
metrics = db.query(ContentMetrics).filter(
ContentMetrics.topic_id == row.topic_id
).all()
recommendations.append({
"topic_id": row.topic_id,
"title": topic.title,
"field": topic.field_name,
"status": topic.status,
"avg_engagement": round(row.avg_engagement, 2) if row.avg_engagement else 0,
"max_views": row.max_views or 0,
"platforms": list(set(m.platform for m in metrics)),
"reason": f"平均互动率 {round(row.avg_engagement, 2)}%,最高阅读 {row.max_views}"
})
recommendations = []
for row in high_performing:
topic = db.query(Topic).filter(Topic.id == row.topic_id).first()
if not topic:
continue
metrics = db.query(ContentMetrics).filter(
ContentMetrics.topic_id == row.topic_id
).all()
recommendations.append({
"topic_id": row.topic_id,
"title": topic.title,
"field": topic.field_name,
"status": topic.status,
"avg_engagement": round(float(row.avg_engagement), 2) if row.avg_engagement else 0,
"max_views": int(row.max_views) if row.max_views else 0,
"platforms": list(set(m.platform for m in metrics)),
"reason": f"平均互动率 {round(float(row.avg_engagement), 2) if row.avg_engagement else 0}%,最高阅读 {int(row.max_views) if row.max_views else 0}"
})
return recommendations[:limit]
return recommendations[:limit]
except Exception as e:
logging.getLogger(__name__).exception(f"推荐选题失败: {e}")
return []