7.2 KiB
7.2 KiB
周返水(Weekly Cashback)实现方案
已定决策(来自本轮确认)
- 二、三:按评审意见修订需求文档、计费/配置与每日返水解耦。
- 四:方案 B —— 周有效投注每日落库,规避
user:profit:Ymd的 7 天 TTL。 - 五.1:VIP 费率存活动配置
ext_config.vip_rates(type=13),不放 VIP 表。 - 五.2:VIP 取「周末最后一刻」(结算下周一读当前 VIP 即可)。
- 五.3:结算上周的同时把「上上周」未领取的置过期。
- 五.4:VIP0 不进页面,不处理。
- 五.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_date(date)。 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_bet,rebate = floor(weekBet * rate /100)(镜像每日返水syncTodayPending思路)。
结算/过期(周一)
weeklyRebateSettle:对上周week_start的 Pending 记录,读当前 VIP →rate=vip_rates[level]→rebate=floor(bet*rate/100);rebate>0置Claimable,写vip_level/rate_snapshot/claimable_at=本周一/expire_at=下周一;同一次把「上上周」Claimable 且 expire_at<=now置Expired。weeklyRebateExpire:兜底,status=Claimable AND expire_at<=now -> Expired(镜像expireDueRecords)。- 顺序:accrue 先于 settle。
复用 vs 新建
- 复用骨架:领取短事务 CAS + 钱包入账失败回滚 + 结算结构化日志(镜像 DailyRebateLogic);
RechargedUidSetService、UserProfitEntity、四态 +statusLabel、Controller/Validator 形态。 - 新建(VIP 费率,不复用 tiers 累进):
WeeklyRebateCalcService::calcRebateLi(betLi, ratePercent)、WeeklyRebateConfigService(解析vip_rates、maxRate、rateForVip、canonicalExtConfigForStorage)。
文件清单
slot_lib:
- Consts.php 新增
ACTIVITY_TYPE_WEEKLY_REBATE=13、TRANSACTION_TYPE_WEEKLY_REBATE=68。
slot_console:
- 模型
app/model/common/WeeklyRebateRecordModel.php(四态 +findByUidAndWeek)。 RechargeGiftConfigModel加TYPE_WEEKLY_REBATE=13与getWeeklyRebateActiveInfo/...ByExactSource(镜像每日返水方法)。- 服务
app/service/WeeklyRebateCalcService.php、app/service/WeeklyRebateConfigService.php。 - Logic
app/api/logic/WeeklyRebateLogic.php(info/claim/accrue/settle/expire)。 - Controller
app/api/controller/WeeklyRebateController.php、Validatorapp/api/validator/WeeklyRebateValidator.php。 - 命令
app/command/WeeklyRebateAccrue.php、WeeklyRebateSettle.php、WeeklyRebateExpire.php。 - 路由:在 api 路由注册 weekly-rebate info/claim(与每日返水同处)。
- SQL
db/weekly_rebate.sql(含last_accrued_date、唯一键uniq_uid_week)。 - 活动配置入口 ActivityConfigEntity.php 读写处对
TYPE_WEEKLY_REBATE调WeeklyRebateConfigService::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打码归类为 活动赠送 Y3(SOURCE_TYPE_ACTIVITY_REWARD=3),与每日返水一致;如有类型白名单需补 68。
需求文档修订(周返水.md)
- 领取按钮「昨天返水金额」→「上一周返水金额」。
- 规则文案「refreshes daily」改为「本周累计实时刷新、每周一结算」。
- 时区统一为服务器时区(删「美国时间」歧义)。
No Btes→No 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:05;weeklyRebateSettle每周一 00:15;weeklyRebateExpire每周一 00:20(兜底)。
收尾门禁
- 改
app/**/*.php后按slot-backend-completion-reportSkill 跑verify-slot-backend.sh+ dockerphp -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": "WeeklyRebateLogic:info/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,输出检测结果章节"} ]