diff --git a/app/admin/repositories/stats.py b/app/admin/repositories/stats.py index 260c159..42e7998 100644 --- a/app/admin/repositories/stats.py +++ b/app/admin/repositories/stats.py @@ -30,17 +30,11 @@ from app.models.user import User from app.models.wallet import CoinTransaction, WithdrawOrder _BEIJING = timezone(timedelta(hours=8)) -REWARD_VIDEO_BIZ_TYPES = ("reward_video", "ad_reward") -# 领券/比价奖励金币的真实来源是信息流广告发奖(ad_feed_reward_record,按 feed_scene 分场景); -# coin_transaction 里只有扁平的 feed_ad_reward、biz_type 不分 coupon/comparison,故这俩桶历史从未 -# 被写入,仅留作未来兜底,实际金额在下方按 feed_scene 汇总 ad_feed_reward_record 得出。reward_video/ -# ad_reward 是激励视频,单独成桶、不再混进领券奖励(历史误并会把激励视频金币双计进领券)。 -COUPON_REWARD_BIZ_TYPES = ("coupon", "coupon_reward") +COUPON_REWARD_BIZ_TYPES = ("reward_video", "ad_reward", "coupon", "coupon_reward") COMPARISON_REWARD_BIZ_TYPES = ("comparison", "compare_reward", "comparison_reward") EXCLUDED_REWARD_BIZ_TYPES = ("invite_inviter", "invite_invitee", "admin_grant") UNCLASSIFIED_FEED_BIZ_TYPES = ("feed_ad_reward",) REGULAR_TASK_EXCLUDED_BIZ_TYPES = ( - *REWARD_VIDEO_BIZ_TYPES, *COUPON_REWARD_BIZ_TYPES, *COMPARISON_REWARD_BIZ_TYPES, *EXCLUDED_REWARD_BIZ_TYPES, @@ -368,7 +362,7 @@ def dashboard_overview( period_reward_video_coin_total = _sum( CoinTransaction.amount, *period_coin_conds, - CoinTransaction.biz_type.in_(REWARD_VIDEO_BIZ_TYPES), + CoinTransaction.biz_type.in_(("reward_video", "ad_reward")), ) period_feed_ad_coin_total = _sum( CoinTransaction.amount, @@ -390,29 +384,15 @@ def dashboard_overview( *period_coin_conds, CoinTransaction.biz_type.like("task_%"), ) - # 领券/比价奖励金币 = biz_type 桶(历史空,兜底)+ 该场景信息流广告实发金币 - # (ad_feed_reward_record.feed_scene,granted;reward_date 是北京日期串,与 period 同自然日窗口)。 period_coupon_reward_coin_total = _sum( CoinTransaction.amount, *period_coin_conds, CoinTransaction.biz_type.in_(COUPON_REWARD_BIZ_TYPES), - ) + _sum( - AdFeedRewardRecord.coin, - AdFeedRewardRecord.status == "granted", - AdFeedRewardRecord.feed_scene == "coupon", - AdFeedRewardRecord.reward_date >= period_from.isoformat(), - AdFeedRewardRecord.reward_date <= period_to.isoformat(), ) period_comparison_reward_coin_total = _sum( CoinTransaction.amount, *period_coin_conds, CoinTransaction.biz_type.in_(COMPARISON_REWARD_BIZ_TYPES), - ) + _sum( - AdFeedRewardRecord.coin, - AdFeedRewardRecord.status == "granted", - AdFeedRewardRecord.feed_scene == "comparison", - AdFeedRewardRecord.reward_date >= period_from.isoformat(), - AdFeedRewardRecord.reward_date <= period_to.isoformat(), ) period_regular_task_coin_total = _sum( CoinTransaction.amount, @@ -563,7 +543,7 @@ def dashboard_overview( "reward_video_coin_total": _sum( CoinTransaction.amount, CoinTransaction.amount > 0, - CoinTransaction.biz_type.in_(REWARD_VIDEO_BIZ_TYPES), + CoinTransaction.biz_type.in_(("reward_video", "ad_reward")), ), "reward_video_watch_count": _count( AdRewardRecord, diff --git a/tests/test_admin_read.py b/tests/test_admin_read.py index 5f5313f..1babd3c 100644 --- a/tests/test_admin_read.py +++ b/tests/test_admin_read.py @@ -320,92 +320,3 @@ def test_read_apis_require_auth(admin_client: TestClient) -> None: "/admin/api/feedbacks", ]: assert admin_client.get(path).status_code == 401, path - - -def test_period_comparison_reward_coin_from_feed_scene( - admin_client: TestClient, admin_token: str -) -> None: - """比价奖励金币口径:按 ad_feed_reward_record.feed_scene='comparison' 的实发金币 - (status=granted)汇总,而非查从不写入的 biz_type 桶(修复大盘该卡恒 0)。 - too_short(未发奖)不计。""" - from app.models.ad_feed_reward import AdFeedRewardRecord - - d = "2021-06-15" # 独立历史日,隔离其它用例数据 - db = SessionLocal() - try: - uid = user_repo.upsert_user_for_login(db, phone="13800008801", register_channel="sms").id - db.add(AdFeedRewardRecord( - client_event_id="cmp-fs-granted", user_id=uid, reward_date=d, - ecpm_raw="0", coin=123, feed_scene="comparison", status="granted", - )) - db.add(AdFeedRewardRecord( - client_event_id="cmp-fs-tooshort", user_id=uid, reward_date=d, - ecpm_raw="0", coin=99, feed_scene="comparison", status="too_short", - )) - db.commit() - finally: - db.close() - - r = admin_client.get( - "/admin/api/stats/overview", params={"date_from": d, "date_to": d}, - headers=_auth(admin_token), - ) - assert r.status_code == 200, r.text - assert r.json()["period"]["coins"]["comparison_reward_coin_total"] == 123 - - -def test_period_coupon_reward_coin_from_feed_scene( - admin_client: TestClient, admin_token: str -) -> None: - """领券奖励金币口径:按 ad_feed_reward_record.feed_scene='coupon' 的实发金币汇总。""" - from app.models.ad_feed_reward import AdFeedRewardRecord - - d = "2021-06-16" - db = SessionLocal() - try: - uid = user_repo.upsert_user_for_login(db, phone="13800008802", register_channel="sms").id - db.add(AdFeedRewardRecord( - client_event_id="cpn-fs-granted", user_id=uid, reward_date=d, - ecpm_raw="0", coin=456, feed_scene="coupon", status="granted", - )) - db.commit() - finally: - db.close() - - r = admin_client.get( - "/admin/api/stats/overview", params={"date_from": d, "date_to": d}, - headers=_auth(admin_token), - ) - assert r.status_code == 200, r.text - assert r.json()["period"]["coins"]["coupon_reward_coin_total"] == 456 - - -def test_period_coupon_reward_excludes_reward_video( - admin_client: TestClient, admin_token: str -) -> None: - """领券奖励金币不再把激励视频金币算进来(reward_video/ad_reward 从领券桶拆出); - 激励视频仍单独计入 reward_video_coin_total。""" - from datetime import datetime - - from app.models.wallet import CoinTransaction - - d = "2021-06-17" - db = SessionLocal() - try: - uid = user_repo.upsert_user_for_login(db, phone="13800008803", register_channel="sms").id - db.add(CoinTransaction( - user_id=uid, amount=50, balance_after=50, biz_type="reward_video", - ref_id="rv-split-1", created_at=datetime(2021, 6, 17, 12, 0, 0), - )) - db.commit() - finally: - db.close() - - r = admin_client.get( - "/admin/api/stats/overview", params={"date_from": d, "date_to": d}, - headers=_auth(admin_token), - ) - assert r.status_code == 200, r.text - coins = r.json()["period"]["coins"] - assert coins["coupon_reward_coin_total"] == 0 # 激励视频不计入领券奖励 - assert coins["reward_video_coin_total"] == 50 # 仍计入激励视频卡