Files
cursor/plans/weekly cashback-215d598c.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

7.2 KiB
Raw Permalink Blame History

周返水Weekly Cashback实现方案

已定决策(来自本轮确认)

  • 二、三:按评审意见修订需求文档、计费/配置与每日返水解耦。
  • 四:方案 B —— 周有效投注每日落库,规避 user:profit:Ymd 的 7 天 TTL。
  • 五.1VIP 费率存活动配置 ext_config.vip_ratestype=13不放 VIP 表。
  • 五.2VIP 取「周末最后一刻」(结算下周一读当前 VIP 即可)。
  • 五.3:结算上周的同时把「上上周」未领取的置过期。
  • 五.4VIP0 不进页面,不处理。
  • 五.5/6/7倒计时对齐周界四周记录入库返水 floor 取整到厘。

计费模型(与每日返水的关键差异)

  • 每日返水 = 下注累进分段(tiers);周返水 = 周有效投注 × rate(vip%) 单乘,按 floor 取整。
  • 统计周:周一 00:00:00 ~ 周日 23:59:59服务器时区(统一口径,修订文档里"美国时间"表述)。
  • 周有效投注 = 当周 7 天 rebate_bet 之和(仅充值用户累加,沿用 slot_pwa 现有口径pwa 无需改动)。

数据流

flowchart TD
  pwa["slot_pwa incBet 仅充值用户累加 rebate_bet"] --> redis["redis user:profit:Ymd TTL7天"]
  accrue["weeklyRebateAccrue 每天00:05 处理昨日"] --> redis
  accrue --> rec["weekly_rebate_record 当周Pending bet_amount累加"]
  settle["weeklyRebateSettle 周一00:15"] --> rec
  settle --> vip["读当前VIP rate=vip_rates level"]
  settle --> expirePrev["上上周 Claimable -> Expired"]
  claim["C端 claim 上周"] --> wallet["WalletService gift 类型68 打码Y3"]

落库方案 B幂等

  • 新表 weekly_rebate_record 增加 last_accrued_datedate
  • weeklyRebateAccrue(每天)处理昨日key 仅 1 天,必在 TTL 内):遍历昨日 user:profit: 哈希,充值用户且 rebate_bet>0 → 定位昨日所属周的记录(无则建 Pending→ 若 last_accrued_date < 昨日bet_amount += rebate_bet 且更新 last_accrued_date(重跑不重复累加)。
  • C 端「This Week」展示 = record.bet_amount(昨日及之前)+ 今日 redis 实时 rebate_betrebate = floor(weekBet * rate /100)(镜像每日返水 syncTodayPending 思路)。

结算/过期(周一)

  • weeklyRebateSettle:对上周 week_start 的 Pending 记录,读当前 VIP → rate=vip_rates[level]rebate=floor(bet*rate/100)rebate>0Claimable,写 vip_level/rate_snapshot/claimable_at=本周一/expire_at=下周一;同一次把「上上周」Claimable 且 expire_at<=nowExpired
  • weeklyRebateExpire:兜底,status=Claimable AND expire_at<=now -> Expired(镜像 expireDueRecords)。
  • 顺序accrue 先于 settle。

复用 vs 新建

  • 复用骨架:领取短事务 CAS + 钱包入账失败回滚 + 结算结构化日志(镜像 DailyRebateLogicRechargedUidSetServiceUserProfitEntity、四态 + statusLabel、Controller/Validator 形态。
  • 新建VIP 费率,不复用 tiers 累进):WeeklyRebateCalcService::calcRebateLi(betLi, ratePercent)WeeklyRebateConfigService(解析 vip_ratesmaxRaterateForVipcanonicalExtConfigForStorage)。

文件清单

slot_lib

  • Consts.php 新增 ACTIVITY_TYPE_WEEKLY_REBATE=13TRANSACTION_TYPE_WEEKLY_REBATE=68

slot_console

  • 模型 app/model/common/WeeklyRebateRecordModel.php(四态 + findByUidAndWeek)。
  • RechargeGiftConfigModelTYPE_WEEKLY_REBATE=13getWeeklyRebateActiveInfo/...ByExactSource(镜像每日返水方法)。
  • 服务 app/service/WeeklyRebateCalcService.phpapp/service/WeeklyRebateConfigService.php
  • Logic app/api/logic/WeeklyRebateLogic.phpinfo/claim/accrue/settle/expire
  • Controller app/api/controller/WeeklyRebateController.php、Validator app/api/validator/WeeklyRebateValidator.php
  • 命令 app/command/WeeklyRebateAccrue.phpWeeklyRebateSettle.phpWeeklyRebateExpire.php
  • 路由:在 api 路由注册 weekly-rebate info/claim与每日返水同处
  • SQL db/weekly_rebate.sql(含 last_accrued_date、唯一键 uniq_uid_week)。
  • 活动配置入口 ActivityConfigEntity.php 读写处对 TYPE_WEEKLY_REBATEWeeklyRebateConfigService::canonicalExtConfigForStorage
  • 部署文档 doc/weekly_rebate_deploy.md(镜像 daily_rebate_deploy

backend/slot_admin+ vue

  • 字典 activity_type 增「周返水」value=13菜单「周返水统计」活动 type=13 编辑页 VIP 费率16 档)配置 UI周返水统计页。

slot_wallet

  • 确认 TRANSACTION_TYPE_WEEKLY_REBATE=68 打码归类为 活动赠送 Y3SOURCE_TYPE_ACTIVITY_REWARD=3),与每日返水一致;如有类型白名单需补 68。

需求文档修订(周返水.md

  • 领取按钮「昨天返水金额」→「上一周返水金额」。
  • 规则文案「refreshes daily」改为「本周累计实时刷新、每周一结算」。
  • 时区统一为服务器时区(删「美国时间」歧义)。
  • No BtesNo Bets

ext_config 标准格式type=13

{
  "vip_rates": [
    {"vip_level": 0, "rate_percent": 0},
    {"vip_level": 1, "rate_percent": 0.5},
    {"vip_level": 15, "rate_percent": 2.0}
  ],
  "banner_image": ""
}

cron

  • weeklyRebateAccrue 每天 00:05weeklyRebateSettle 每周一 00:15weeklyRebateExpire 每周一 00:20兜底

收尾门禁

  • app/**/*.php 后按 slot-backend-completion-report Skill 跑 verify-slot-backend.sh + docker php -l,回复附「检测结果」章节。 [ {"id": "doc-fix", "content": "修订 周返水.md 笔误(昨天->上周、daily->weekly、时区统一、No Bets"}, {"id": "consts", "content": "slot_lib Consts 新增 ACTIVITY_TYPE_WEEKLY_REBATE=13、TRANSACTION_TYPE_WEEKLY_REBATE=68"}, {"id": "sql-model", "content": "建 weekly_rebate.sql 与 WeeklyRebateRecordModel含 last_accrued_date、四态、findByUidAndWeek"}, {"id": "config-model-methods", "content": "RechargeGiftConfigModel 加 TYPE_WEEKLY_REBATE 与 getWeeklyRebateActiveInfo 系列方法"}, {"id": "services", "content": "WeeklyRebateCalcService(VIP费率单乘) 与 WeeklyRebateConfigService(解析 vip_rates/maxRate/rateForVip/canonical)"}, {"id": "logic", "content": "WeeklyRebateLogicinfo/claim(短事务CAS+钱包回滚)/accrue/settle(读VIP+过期上上周)/expire"}, {"id": "controller-route", "content": "WeeklyRebateController + WeeklyRebateValidator + 路由注册"}, {"id": "commands", "content": "命令 WeeklyRebateAccrue/Settle/Expire + cron 配置"}, {"id": "activity-entry", "content": "ActivityConfigEntity 读写 type=13 走 canonicalExtConfigForStorage"}, {"id": "admin", "content": "slot_admin 字典/菜单/type=13 VIP费率配置页/周返水统计页"}, {"id": "wallet-verify", "content": "slot_wallet 确认流水类型68 打码归 活动赠送Y3"}, {"id": "deploy-doc", "content": "编写 weekly_rebate_deploy.md 部署文档"}, {"id": "verify-gate", "content": "跑 verify-slot-backend.sh + php -l输出检测结果章节"} ]