From 25b2b6850b2d0a4dbec264662654a6f81dd6e528 Mon Sep 17 00:00:00 2001 From: marco Date: Tue, 9 Jun 2026 11:18:07 +0800 Subject: [PATCH] =?UTF-8?q?feat(coupon):=20=E9=A2=86=E5=88=B8=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E9=A2=91=E6=8E=A7=E5=8A=A0=E9=87=8D=E7=BD=AE=E7=AB=AF?= =?UTF-8?q?=E7=82=B9=20+=20reset=5Ftoday=5Fengagement=20(#29)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 加 POST /api/v1/coupon/prompt/reset:删该设备今日 engagement → has_engaged_today 变 false、 今天又能弹。开发设置「重置今日领券弹窗状态」按钮调它(客户端改纯后台频控后前台清缓存已失效) - coupon_state 加 reset_today_engagement(按 device_id + 今天删);should-show 文档改为"纯后台判据" Co-Authored-By: Claude Opus 4.8 Reviewed-on: https://gitea.shaguabijia.com/WonderableAI/shaguabijia-app-server/pulls/29 --- app/api/v1/coupon.py | 10 +++++++++- app/repositories/coupon_state.py | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/app/api/v1/coupon.py b/app/api/v1/coupon.py index 4de69eb..9051f92 100644 --- a/app/api/v1/coupon.py +++ b/app/api/v1/coupon.py @@ -183,7 +183,15 @@ def coupon_prompt_should_show( device_id: str, db: DbSession ) -> CouponPromptShouldShowOut: """今天这台设备已 engage(领或拒)过 → should_show=false。客户端据此决定弹不弹 - (前台 SP 缓存做快速路径,这里是权威)。""" + (纯后台判据,客户端不再做前台 SP 缓存判断)。""" return CouponPromptShouldShowOut( should_show=not coupon_repo.has_engaged_today(db, device_id) ) + + +@router.post("/prompt/reset", summary="重置今日领券引导窗 engagement(开发测频控用)") +def coupon_prompt_reset(payload: CouponPromptDismissIn, db: DbSession) -> dict[str, bool]: + """删这台设备今天的 engagement → has_engaged_today 变 false,今天又能弹。 + 开发设置「重置今日领券弹窗状态」按钮调。MVP 不鉴权,按 device_id。""" + coupon_repo.reset_today_engagement(db, payload.device_id) + return {"ok": True} diff --git a/app/repositories/coupon_state.py b/app/repositories/coupon_state.py index d36be0a..e255e9f 100644 --- a/app/repositories/coupon_state.py +++ b/app/repositories/coupon_state.py @@ -9,7 +9,7 @@ import logging from datetime import date, datetime from zoneinfo import ZoneInfo -from sqlalchemy import select +from sqlalchemy import delete, select from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import Session @@ -65,6 +65,19 @@ def mark_engagement( db.rollback() +def reset_today_engagement(db: Session, device_id: str) -> int: + """删这台设备今天的 engagement(开发设置「重置今日领券弹窗状态」调,测频控用)。 + 删后 has_engaged_today → false,今天又能弹。返回删除行数。""" + result = db.execute( + delete(CouponPromptEngagement).where( + CouponPromptEngagement.device_id == device_id, + CouponPromptEngagement.engage_date == today_cn(), + ) + ) + db.commit() + return result.rowcount or 0 + + # ===== 领券记录(coupon_claim_record)===== def record_claims(