Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 836cbe3c85 |
@@ -57,9 +57,15 @@ def list_seeds(db: AdminDb) -> list[OpsMarqueeSeedOut]:
|
||||
def preview_feed(
|
||||
db: AdminDb,
|
||||
limit: Annotated[int, Query(ge=1, le=30)] = 8,
|
||||
mode: Annotated[str | None, Query(description="mixed/real/seed;不传=当前持久化模式")] = None,
|
||||
) -> OpsSavingsFeedPreviewOut:
|
||||
"""返回客户端实际会看到的 feed(真实记录会插队、种子随机抽取/金额随机/名字合成),供运营对效果。"""
|
||||
return OpsSavingsFeedPreviewOut(items=ops_marquee.get_feed(db, limit=limit))
|
||||
"""返回客户端实际会看到的 feed(真实记录会插队、种子随机抽取/金额随机/名字合成),供运营对效果。
|
||||
|
||||
mode 显式指定则预览该模式(**不改持久化配置**,供前端切换开关时实时预览);不传则用当前持久化模式。
|
||||
"""
|
||||
if mode is not None and mode not in ops_marquee.FEED_MODES:
|
||||
raise HTTPException(status_code=400, detail="mode 需为 mixed / real / seed")
|
||||
return OpsSavingsFeedPreviewOut(items=ops_marquee.get_feed(db, limit=limit, mode=mode))
|
||||
|
||||
|
||||
# 注:/mode 两个端点须在 /{seed_id} 之前注册,否则 PATCH /mode 会被 /{seed_id} 抢先按 id 解析。
|
||||
|
||||
@@ -30,6 +30,7 @@ from app.models.comparison import ComparisonRecord
|
||||
from app.models.ops_marquee_seed import OpsMarqueeSeed
|
||||
from app.models.user import User
|
||||
from app.repositories import app_config
|
||||
from app.repositories.user import is_default_nickname
|
||||
|
||||
# 首页轮播数据源模式(存 app_config.marquee_feed_mode):
|
||||
# mixed=真实优先+种子补位+合成兜底(默认,原行为);real=只真实(不足则少/空);seed=只种子+合成兜底。
|
||||
@@ -140,9 +141,12 @@ def _synth_masked_name(rng: random.Random) -> str:
|
||||
|
||||
def _mask_real(nickname: str | None, user_id: int) -> str:
|
||||
"""真实用户脱敏(对齐 PRD「用户标识打码规则」):设过昵称→昵称脱敏(中英文皆可);
|
||||
没昵称→「用户」+5星+id 后 2 位(用户*****08),按 user_id 稳定、刷新不变脸。"""
|
||||
没昵称→「用户」+5星+id 后 2 位(用户*****08),按 user_id 稳定、刷新不变脸。
|
||||
|
||||
创建时自动分配的默认昵称(「用户」+9 位随机,见 user.is_default_nickname)不算用户主动设的昵称,
|
||||
按「无昵称」处理走 id 规则(产品决策 2026-07:默认昵称归入「没昵称」档)。"""
|
||||
nick = (nickname or "").strip()
|
||||
if nick:
|
||||
if nick and not is_default_nickname(nick):
|
||||
return _mask_nickname(nick)
|
||||
return _mask_anon(user_id)
|
||||
|
||||
@@ -213,9 +217,11 @@ def _recent_real_rows(db: Session) -> list[tuple[int, int, str | None]]:
|
||||
return out
|
||||
|
||||
|
||||
def get_feed(db: Session, limit: int = 8) -> list[dict]:
|
||||
def get_feed(db: Session, limit: int = 8, mode: str | None = None) -> list[dict]:
|
||||
"""返回最多 limit 条 {masked_user, saved_amount_cents, time(HH:MM:SS 北京)}。
|
||||
|
||||
mode:显式传入(admin 预览指定模式)则用它、**不改持久化配置**;不传(客户端 /savings-feed)读
|
||||
持久化的 marquee_feed_mode;非法值一律回退到持久化模式。
|
||||
真实条:success 且 0 < saved ≤ 上限,按 user 去重(同一用户只取最新一条,避免单人刷屏)。
|
||||
不足用启用的种子补齐——**公平随机抽取** need 个(而非固定取前 N),让所有种子都有机会露出;
|
||||
种子用户名留空则随机合成(避开撞名),金额取**长尾随机**(小额居多、偶尔大额,更像真实分布)。
|
||||
@@ -223,7 +229,8 @@ def get_feed(db: Session, limit: int = 8) -> list[dict]:
|
||||
展示时间统一「刷新」成相对现在的最近时刻(从 now 往前**随机抖动**递减),保证轮播永远像刚发生、
|
||||
节奏自然不机械(真实用户/金额不变,只换展示时间——避免旧测试数据 / 低谷期记录显示成过时时间)。
|
||||
"""
|
||||
mode = get_feed_mode(db) # mixed / real / seed(运营可在「首页轮播种子」页切换)
|
||||
# 预览可显式指定模式(所见=选中模式,不依赖 PATCH 落库时序);None/非法 → 读持久化配置。
|
||||
mode = mode if mode in FEED_MODES else get_feed_mode(db) # mixed / real / seed
|
||||
|
||||
items: list[dict] = []
|
||||
used_names: set[str] = set()
|
||||
|
||||
@@ -42,6 +42,22 @@ def _gen_nickname() -> str:
|
||||
)
|
||||
|
||||
|
||||
def is_default_nickname(nickname: str | None) -> bool:
|
||||
"""是否为创建时自动分配的默认昵称(= "用户" + 9 位字母数字,见 [_gen_nickname])。
|
||||
|
||||
这类不是用户主动设置的昵称,展示脱敏时按「无昵称」处理(走 id 规则,见 ops_marquee._mask_real)。
|
||||
精确匹配生成格式(前缀 + 定长字母数字集),不误伤真人以「用户」开头的昵称(如「用户体验师」含汉字、
|
||||
长度也不符)。用户改过昵称即不再匹配。"""
|
||||
if not nickname:
|
||||
return False
|
||||
s = nickname.strip()
|
||||
return (
|
||||
len(s) == len(_NICKNAME_PREFIX) + _NICKNAME_LEN
|
||||
and s.startswith(_NICKNAME_PREFIX)
|
||||
and all(c in _NICKNAME_ALPHABET for c in s[len(_NICKNAME_PREFIX):])
|
||||
)
|
||||
|
||||
|
||||
def get_user_by_username(db: Session, username: str) -> User | None:
|
||||
return db.execute(
|
||||
select(User).where(User.username == username)
|
||||
|
||||
Reference in New Issue
Block a user