feat: 评论去重 + 热度/新鲜度加权选文

评论去重逻辑:
- 查询今日已评论的文章ID,选文时已评论的文章权重降为10%
- 若选中已评论文章:改为回复其他用户的评论(虚拟用户互动链)
- 若选中未评论文章:正常发新评论,评论成功后随机回复他人评论

热度+新鲜度加权选文规则:
- 热度分 = commentNum×3 + praiseNum×2 + readNum×1
- 新鲜度 = 72小时内的新文章获得最高3倍加成,随时间线性衰减
- 综合权重 = (热度分+1) × 新鲜度,确保真实用户互动多的新文章优先被虚拟用户关注
This commit is contained in:
stefanfeng
2026-04-02 17:33:07 +08:00
parent 958eaeda8a
commit 7203f04be6
2 changed files with 157 additions and 34 deletions

View File

@@ -407,7 +407,54 @@ class NewsPlatformService:
if (x.get("recordId") or x.get("id")) not in INVALID_IDS]
logger.info(f"[广场新闻] {user.account} 获取到 {len(items)} 条(已过滤本人+无效文章)")
import random as _rand
return _rand.sample(items, min(count, len(items))) if items else []
from datetime import datetime as _dt
import math as _math
# ── 热度 + 新鲜度加权选取 ─────────────────────────────────
# 规则:真实用户互动量越大 + 发布时间越新 → 虚拟用户越倾向互动
def _hot_weight(a):
comment_n = int(a.get("commentNum") or 0)
praise_n = int(a.get("praiseNum") or 0)
read_n = int(a.get("readNum") or 0)
# 热度分评论权重3倍点赞2倍阅读1倍
hot_score = comment_n * 3 + praise_n * 2 + read_n
# 新鲜度衰减发布时间越近权重越高72小时内为新鲜文章
freshness = 1.0
pub_time_str = a.get("publishTime") or a.get("createTime") or ""
if pub_time_str:
try:
for fmt in ["%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%S"]:
try:
pub_dt = _dt.strptime(pub_time_str[:19], fmt)
hours_old = (_dt.now() - pub_dt).total_seconds() / 3600
# 72小时内新鲜文章新鲜度加成最高3倍
freshness = max(1.0, 3.0 - hours_old / 36.0)
break
except Exception:
continue
except Exception:
pass
# 综合权重:热度 * 新鲜度基础权重最少为1
return max(1.0, (hot_score + 1) * freshness)
if len(items) <= count:
return items
# 加权随机采样
weights = [_hot_weight(a) for a in items]
selected = []
pool = list(range(len(items)))
w_pool = list(weights)
for _ in range(min(count, len(items))):
if not pool:
break
chosen_idx = _rand.choices(pool, weights=w_pool, k=1)[0]
selected.append(items[chosen_idx])
i = pool.index(chosen_idx)
pool.pop(i)
w_pool.pop(i)
return selected
logger.warning(f"[广场新闻] {user.account} code={d.get('code')} msg={d.get('message')}")
except Exception as e:
logger.error(f"[广场新闻] {user.account}: {e}")