Files
marco 4ee6de2548 feat(cps): 活动支持编辑(PATCH /activities/{id})
- CpsActivityUpdate schema + repo update_activity(部分更新,非 None 覆盖)
- router 按「合并后最终值」校验平台必填项(同新建口径),写审计 cps.activity.update
- 可改名/平台/对应字段/落地页图/备注/状态

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:13:35 +08:00

2.5 KiB

signin_record — 签到记录(7 天循环)

模型 app/models/signin.py · 仓库 app/repositories/signin.py · 接口 signin-status / signin-do · ← 索引 · 总览

App「每日签到」每签一次写一行,(user_id, signin_date) 唯一,天然防一天签两次。cycle_day(1..7)决定发多少金币(档位 rewards.SIGNIN_REWARDS,默认 (200,200,300,200,400,400,800),一轮 7 天累计 2500 金币,运营后台 app_config.signin_rewards 可改),断签重置回 1;第 8 天回到第 1 天;streak 是连续天数(不封顶),给"已连续签到 N 天"展示。

用在哪 / 增删改查

  • C(插入):POST /signin/do(do_signin)。今天未签且校验通过 → 算出 cycle_day/streak(昨天签过则在上次基础上 +1、否则重置 1)→ 写一行 + grant_coins(biz_type='signin', ref_id=今天日期) 加币,同事务 commit。今天已签再调 → 抛 AlreadySignedError(409),不重复写。
  • U / D:无。每天一行,历史不改。
  • R:GET /signin/status(签到页:今天签没签、连续天数、7 档状态/金币、能否签),内部 get_status 读最近一条 + 推算今天档位。

字段

类型 约束 / 默认 说明(取值 / join)
id Integer PK, autoincrement
user_id Integer FK→user.id, index, NOT NULL 归属用户
signin_date Date NOT NULL 签到日期(北京时间 cn_today() 的 date)。其 ISO 串被 coin_transaction.ref_id 引用(biz_type=signin)
cycle_day Integer NOT NULL 取值 1..7:7 天循环里今天第几档,决定发币额;断签重置回 1
streak Integer NOT NULL 连续签到天数(≥1,不封顶);断签重置回 1
coin_awarded Integer NOT NULL 本次实发金币(= 当时档位金额)
created_at DateTime(tz) server_default now() 时间

关系 / Join Key

  • user_iduser.id(多对一)。
  • 配套写 coin_account(U,加币)+ coin_transaction(C,biz_type='signin'ref_id=signin_date.isoformat())。coin_transaction.ref_id 反查即对应本表当天那条。

索引与约束

  • PK id;index user_id;UNIQUE(user_id, signin_date) = uq_signin_user_date(防一天签两次)。

注意

  • "今天/昨天"全按北京时间(CN_TZ=UTC+8),不用 UTC(否则 0~8 点会算成前一天)。
  • 连续判定:last.signin_date == today - 1天 才算连续,否则首签/断签重置。