cfeacb4bab
- 新表 platform_stat_display:每个指标可选 real/manual/random 三种 展示模式,含建表 + anchor_minutes 两个 alembic migration - 公开接口 GET /api/v1/platform/stats(无鉴权门面数字,登录前可读) - 运营后台 GET/PATCH /admin/api/dashboard-display 配置展示模式 - 配套 model/repository/schema,注册 router(app/main+admin/main), 导出 model,补 docs(api/database 索引及 3 篇详情) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
62 lines
3.0 KiB
Python
62 lines
3.0 KiB
Python
"""首页三统计展示配置表(帮助用户 / 完成比价 / 累计节省)。
|
|
|
|
客户端首页顶部三个门面数字,每个指标可独立选 3 种展示模式(运营后台配):
|
|
- real : 实时查真实数据(help_users=去重成功比价用户数 / total_compares=成功比价数 /
|
|
total_saved=成功比价省额求和)。
|
|
- manual : 直接用运营手填的固定值。
|
|
- random : 「只增不减」的伪增长——读取时惰性 tick:距上次 tick 超过 random_tick_seconds
|
|
就把 random_current 乘以一个 [min,max] 内的随机倍率(倍率恒 ≥1.0 → 只增不减)。
|
|
|
|
数值单位约定(三指标都用各自「基础单位」的整数存,避免浮点):
|
|
- help_users / total_compares : 个数(人 / 次)
|
|
- total_saved : 分(cents);客户端 ÷100 显示「元」
|
|
|
|
倍率用千分比整数存:1.000→1000、1.100→1100,读时 factor = randint(min,max)/1000。
|
|
|
|
一行一指标,主键 = metric。初始由 migration 播种 3 行(默认 manual + 当前写死门面值,
|
|
保证上线无视觉变化),运营再按需切模式。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import DateTime, Integer, String, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.db.base import Base
|
|
|
|
|
|
class PlatformStatDisplay(Base):
|
|
__tablename__ = "platform_stat_display"
|
|
|
|
# help_users / total_compares / total_saved
|
|
metric: Mapped[str] = mapped_column(String(32), primary_key=True)
|
|
# real / manual / random(每指标独立)
|
|
mode: Mapped[str] = mapped_column(String(16), nullable=False, default="real")
|
|
|
|
# manual 模式固定值(基础单位整数;total_saved 为分)
|
|
manual_value: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
|
|
# random 模式:倍率区间(千分比,≥1000 保证只增不减)+ tick 周期 + 当前值 + 上次 tick 时刻
|
|
random_mult_min: Mapped[int] = mapped_column(Integer, nullable=False, default=1000)
|
|
random_mult_max: Mapped[int] = mapped_column(Integer, nullable=False, default=1100)
|
|
random_tick_seconds: Mapped[int] = mapped_column(Integer, nullable=False, default=86400)
|
|
# 触发时刻对齐偏移:距北京时间 0 点的分钟数。按单位:天=每日时刻(h*60+m)、小时=每小时第几分、
|
|
# 分钟=0。刷新在北京时间 (anchor + k*interval) 的钟点边界触发(见 repo _refresh)。
|
|
random_anchor_minutes: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
random_current: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
random_last_tick_at: Mapped[datetime | None] = mapped_column(
|
|
DateTime(timezone=True), nullable=True
|
|
)
|
|
|
|
updated_by_admin_id: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
onupdate=func.now(),
|
|
nullable=False,
|
|
)
|
|
|
|
def __repr__(self) -> str: # pragma: no cover
|
|
return f"<PlatformStatDisplay metric={self.metric} mode={self.mode}>"
|