fix(admin): 区分领券广告收益未填充与零收益 (#148)
## 修改内容 - 无 eCPM 填充记录时,领券数据接口返回 null - 已填充但收益为 0 时保留 0.0 - 补充未填充与零收益的回归测试 ## 验证 - 后端定向测试:7 passed - Ruff 检查通过 - 线上近 30 天 740 条领券记录中,647 条无对应 eCPM 填充记录 --------- Co-authored-by: unknown <798648091@qq.com> Reviewed-on: #148 Co-authored-by: linkeyu <linkeyu@wonderable.ai> Co-committed-by: linkeyu <linkeyu@wonderable.ai>
This commit was merged in pull request #148.
This commit is contained in:
@@ -86,7 +86,12 @@ def _success_rates(rows: list) -> dict:
|
||||
}
|
||||
|
||||
|
||||
def _session_to_row(r, phone: str | None = None, nickname: str | None = None, ad_revenue_yuan: float = 0.0) -> dict:
|
||||
def _session_to_row(
|
||||
r,
|
||||
phone: str | None = None,
|
||||
nickname: str | None = None,
|
||||
ad_revenue_yuan: float | None = None,
|
||||
) -> dict:
|
||||
"""CouponSession ORM → 明细行 dict(主表「领券数据」与「用户全部领券」抽屉共用)。"""
|
||||
return {
|
||||
"id": r.id,
|
||||
@@ -252,7 +257,7 @@ def coupon_data_report(
|
||||
items = []
|
||||
for r in page:
|
||||
phone, nickname = user_map.get(r.user_id, (None, None)) if r.user_id is not None else (None, None)
|
||||
items.append(_session_to_row(r, phone, nickname, ad_revenue_yuan=rev_map.get(r.trace_id, 0.0)))
|
||||
items.append(_session_to_row(r, phone, nickname, ad_revenue_yuan=rev_map.get(r.trace_id)))
|
||||
|
||||
return {
|
||||
"summary": summary,
|
||||
@@ -276,7 +281,7 @@ def coupon_user_records(db: Session, *, user_id: int, limit: int = 100) -> dict:
|
||||
).scalar_one()
|
||||
rev_map = crud_ecpm.revenue_yuan_by_trace(db, [r.trace_id for r in rows])
|
||||
return {
|
||||
"items": [_session_to_row(r, ad_revenue_yuan=rev_map.get(r.trace_id, 0.0)) for r in rows],
|
||||
"items": [_session_to_row(r, ad_revenue_yuan=rev_map.get(r.trace_id)) for r in rows],
|
||||
"total": int(total),
|
||||
}
|
||||
|
||||
|
||||
@@ -70,8 +70,9 @@ class CouponDataRow(BaseModel):
|
||||
started_at: datetime = Field(..., description="发起时刻(明细「时间」列)")
|
||||
claimed_count: int | None = None
|
||||
trace_url: str | None = Field(None, description="pricebot 公网 trace 链接(仅 completed 有);admin 渲染可点链接,无则显示可复制 trace_id")
|
||||
ad_revenue_yuan: float = Field(
|
||||
0.0, description="本次领券看的信息流广告预估收益(元);按 trace_id 聚合 ad_ecpm_record"
|
||||
ad_revenue_yuan: float | None = Field(
|
||||
None,
|
||||
description="本次领券看的信息流广告预估收益(元);按 trace_id 聚合 ad_ecpm_record;无填充记录为 null",
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +43,35 @@ def test_coupon_data_report_includes_ad_revenue() -> None:
|
||||
db.close()
|
||||
|
||||
|
||||
def test_coupon_data_report_distinguishes_unfilled_from_zero_revenue() -> None:
|
||||
"""无 eCPM 记录返回 None;已填充但 eCPM=0 返回 0.0。"""
|
||||
db = SessionLocal()
|
||||
try:
|
||||
db.add_all([
|
||||
CouponSession(
|
||||
trace_id="rev-cp-unfilled", device_id="d-unfilled", status="completed", app_env="prod",
|
||||
platforms=["meituan-waimai"], platform_success=["meituan-waimai"],
|
||||
started_at=datetime(2020, 1, 3, tzinfo=UTC), started_date=date(2020, 1, 3),
|
||||
),
|
||||
CouponSession(
|
||||
trace_id="rev-cp-zero", device_id="d-zero", status="completed", app_env="prod",
|
||||
platforms=["meituan-waimai"], platform_success=["meituan-waimai"],
|
||||
started_at=datetime(2020, 1, 3, tzinfo=UTC), started_date=date(2020, 1, 3),
|
||||
),
|
||||
_ecpm("rev-cp-zero", "0", "cp-sess-zero", "coupon"),
|
||||
])
|
||||
db.flush()
|
||||
|
||||
res = coupon_data_report(db, date_from="2020-01-03", date_to="2020-01-03", app_env="prod")
|
||||
rows = {row["trace_id"]: row for row in res["items"]}
|
||||
|
||||
assert rows["rev-cp-unfilled"]["ad_revenue_yuan"] is None
|
||||
assert rows["rev-cp-zero"]["ad_revenue_yuan"] == 0.0
|
||||
finally:
|
||||
db.rollback()
|
||||
db.close()
|
||||
|
||||
|
||||
def test_comparison_list_includes_ad_revenue() -> None:
|
||||
"""比价记录列表项带本次广告收益;200 分 → 0.002 元。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user