db399a40fa
- ops_stat: 真实值 offset→保底(max);初始基数过只增不减护栏 - ops_marquee: 脱敏名手机尾号+中文昵称混合;金额长尾;时间随机抖动;真实+种子不足兜底补满;真实记录查询 ~30s 缓存 - comparison_record: 复合索引 (status, created_at) + 迁移(PG CONCURRENTLY);修复 alembic 多 head(merge 改挂 onboarding_completion) - 轮播种子批量删除/启用接口 + ids 上限;docs 同步 - 附带并行会话 WIP:admin users / wallet Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: OuYingJun1024 <1034284404@qq.com> Reviewed-on: #42 Co-authored-by: ouzhou <ouzhou@wonderable.ai> Co-committed-by: ouzhou <ouzhou@wonderable.ai>
44 lines
2.4 KiB
Python
44 lines
2.4 KiB
Python
"""首页轮播「种子」条目(运营可配的兜底假数据 = 假数据生成规则)。
|
|
|
|
客户端首页顶部「用户****xxx 比价后节省 xx 元」滚动条:数据源是全平台真实比价记录,
|
|
但冷启动 / 低谷期真实记录不够 N 条时,用本表的种子条目补齐到 N 条「混播」,保证轮播永不空。
|
|
运营后台可增删改本表。真实够时种子不出现。
|
|
|
|
种子是「规则」而非「死记录」:
|
|
- masked_user 可空——留空则 feed 展示时按脱敏格式随机合成用户名(并避开同屏撞名),
|
|
风格与真实条一致、运营零心智、永不穿帮;填了则固定用该名。
|
|
- 金额是 [min_cents, max_cents] 区间,feed 每次在区间内随机取值(固定金额则 min==max),
|
|
让同一种子每次展示的数字有浮动,更像真的。
|
|
- sort_order 仅供后台列表排序;feed 是公平随机抽取(不看 sort_order),保证所有启用种子都有机会露出。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import Boolean, DateTime, Integer, String, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.db.base import Base
|
|
|
|
|
|
class OpsMarqueeSeed(Base):
|
|
__tablename__ = "ops_marquee_seed"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
# 脱敏用户名(手机尾号 / 中文昵称风格,如「138****5678」「省钱**」);留空(NULL)或旧「用户****xxx」
|
|
# 模板名 → feed 展示时随机合成混合风格名(避开撞名、自愈历史种子)
|
|
masked_user: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
# 节省金额区间(分);feed 每次在 [min,max] 随机取一个值。固定金额则 min==max。客户端 ÷100 显示「x.xx 元」
|
|
min_cents: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
max_cents: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
# 停用的种子不参与混播
|
|
enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
|
# 仅供后台列表排序(小在前);feed 是公平随机抽取,不看此字段
|
|
sort_order: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), server_default=func.now(), nullable=False
|
|
)
|
|
|
|
def __repr__(self) -> str: # pragma: no cover
|
|
return f"<OpsMarqueeSeed id={self.id} user={self.masked_user}>"
|