diff --git a/app/admin/repositories/ad_revenue.py b/app/admin/repositories/ad_revenue.py index 8dfcf2d..cab92d6 100644 --- a/app/admin/repositories/ad_revenue.py +++ b/app/admin/repositories/ad_revenue.py @@ -385,6 +385,27 @@ def ad_revenue_report( for k, v in type_map.items() } + # 分场景小计(按 feed_scene:展示条数 + 预估收益),同 type_stats 基于全量 events—— + # 供数据大盘「领券广告 / 比价广告」卡用。此前大盘是在分页 items 里按 feed_scene 现算, + # 2026-07-02 起信息流逐条展示行(唯一带收益 + 场景的行)不再进主表 items,现算恒为 0; + # 改为服务端在全量上聚合下发(也顺带不受 limit 分页截断影响)。feed_scene 为空(激励视频 / + # 旧数据)不计入任何场景桶。 + scene_map: dict[str, dict] = {} + for e in events: + sc = e.get("feed_scene") + if not sc: + continue + s = scene_map.get(sc) + if s is None: + s = {"impressions": 0, "revenue_yuan": 0.0} + scene_map[sc] = s + s["impressions"] += e["impressions"] + s["revenue_yuan"] += e["revenue_yuan"] + scene_stats = { + k: {"impressions": v["impressions"], "revenue_yuan": round(v["revenue_yuan"], 6)} + for k, v in scene_map.items() + } + # DAU:复用大盘「今日活跃」口径(stats.today_dau,last_login_at)。该口径只能算今日, # 故仅当查询=今日单天时给值;历史 / 多天区间返回 None,前端显示「-」。 is_today = date_from == date_to == rewards.cn_today().isoformat() @@ -416,6 +437,7 @@ def ad_revenue_report( "daily": daily, "hourly": hourly, "type_stats": type_stats, + "scene_stats": scene_stats, "dau": dau, "items": main_rows[offset:offset + limit], } diff --git a/app/admin/routers/ad_revenue.py b/app/admin/routers/ad_revenue.py index dc6129f..77685d4 100644 --- a/app/admin/routers/ad_revenue.py +++ b/app/admin/routers/ad_revenue.py @@ -91,6 +91,7 @@ def get_ad_revenue_report( daily=[AdRevenueDaily(**d) for d in result["daily"]], hourly=[AdRevenueHourly(**h) for h in result["hourly"]], type_stats={k: AdRevenueTypeStat(**v) for k, v in result["type_stats"].items()}, + scene_stats={k: AdRevenueTypeStat(**v) for k, v in result["scene_stats"].items()}, dau=result["dau"], total=result["total"], truncated=result["truncated"], diff --git a/app/admin/schemas/ad_revenue.py b/app/admin/schemas/ad_revenue.py index cec29b2..0aab506 100644 --- a/app/admin/schemas/ad_revenue.py +++ b/app/admin/schemas/ad_revenue.py @@ -136,6 +136,11 @@ class AdRevenueReportOut(BaseModel): default_factory=dict, description="按广告类型(ad_type)小计 {ad_type: {impressions, revenue_yuan}};前端取 draw / reward_video 做分类大盘", ) + scene_stats: dict[str, AdRevenueTypeStat] = Field( + default_factory=dict, + description="按信息流场景(feed_scene)小计 {comparison/coupon/welfare: {impressions, revenue_yuan}};" + "全量统计(不受分页截断),供数据大盘「领券广告 / 比价广告」卡;feed_scene 为空的事件不计入", + ) dau: int | None = Field( None, description="今日活跃用户数(复用大盘口径,last_login_at);**仅查询=今日单天时有值**,历史/多天为 null",