""" 一致性指标 API 按达人、规则类型、时间窗口查询 """ from datetime import datetime, timedelta, timezone from fastapi import APIRouter, HTTPException, Query, status from app.schemas.review import ( ConsistencyMetricsResponse, ConsistencyWindow, RuleConsistencyMetric, ViolationType, ) router = APIRouter(prefix="/metrics", tags=["metrics"]) @router.get("/consistency", response_model=ConsistencyMetricsResponse) async def get_consistency_metrics( influencer_id: str = Query(None, description="达人 ID(必填)"), window: ConsistencyWindow = Query(ConsistencyWindow.ROLLING_30D, description="计算周期"), rule_type: ViolationType = Query(None, description="规则类型筛选"), ) -> ConsistencyMetricsResponse: """ 查询一致性指标 - 按达人 ID 查询 - 支持 Rolling 30 天、周度快照、月度快照 - 可按规则类型筛选 """ # 验证必填参数 if not influencer_id: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="缺少必填参数: influencer_id", ) # 计算时间范围 now = datetime.now(timezone.utc) if window == ConsistencyWindow.ROLLING_30D: period_start = now - timedelta(days=30) period_end = now elif window == ConsistencyWindow.SNAPSHOT_WEEK: # 本周一到现在 days_since_monday = now.weekday() period_start = (now - timedelta(days=days_since_monday)).replace( hour=0, minute=0, second=0, microsecond=0 ) period_end = now else: # SNAPSHOT_MONTH # 本月1号到现在 period_start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0) period_end = now # 生成模拟数据(实际应从数据库查询) all_metrics = [ RuleConsistencyMetric( rule_type=ViolationType.FORBIDDEN_WORD, total_reviews=100, violation_count=5, violation_rate=0.05, ), RuleConsistencyMetric( rule_type=ViolationType.COMPETITOR_LOGO, total_reviews=100, violation_count=2, violation_rate=0.02, ), RuleConsistencyMetric( rule_type=ViolationType.DURATION_SHORT, total_reviews=100, violation_count=8, violation_rate=0.08, ), ] # 按规则类型筛选 if rule_type: all_metrics = [m for m in all_metrics if m.rule_type == rule_type] return ConsistencyMetricsResponse( influencer_id=influencer_id, window=window, period_start=period_start, period_end=period_end, metrics=all_metrics, )