fix: 点赞/收藏/转发同一篇文章每日只触发一次

问题:同一用户对同一篇文章重复点赞、收藏、转发
原因:去重逻辑只针对评论,未覆盖其他互动类型

修复:
- 查询今日所有互动类型的已完成记录(不只是评论)
- 点赞/收藏/转发执行前检查 today_done,已做过则跳过
- 概率控制依然有效(未做过的文章才进入随机概率判断)
- 评论去重逻辑保持不变
This commit is contained in:
stefanfeng
2026-04-03 10:47:34 +08:00
parent 4ab8f94663
commit f52bc7d147

View File

@@ -243,19 +243,25 @@ class SchedulerService:
return return
# ── 文章去重 + 热度加权选取 ───────────────────────────────── # ── 文章去重 + 热度加权选取 ─────────────────────────────────
# 查询今日已评论过的文章ID(避免重复评论同一篇 # 查询今日已互动过的文章(所有类型),避免重复互动同一篇
from sqlalchemy import func as _func from sqlalchemy import func as _func
from datetime import date as _date from datetime import date as _date
today_str = datetime.now().date() today_str = datetime.now().date()
dup_result = await db.execute( dup_result = await db.execute(
select(InteractionRecord.article_id).where( select(
InteractionRecord.article_id,
InteractionRecord.interact_type,
).where(
InteractionRecord.user_id == user_id, InteractionRecord.user_id == user_id,
InteractionRecord.interact_type == "comment",
InteractionRecord.status == 1, InteractionRecord.status == 1,
_func.date(InteractionRecord.executed_at) == today_str, _func.date(InteractionRecord.executed_at) == today_str,
) )
) )
already_commented = {r[0] for r in dup_result.all()} # {article_id: set of interact_types already done today}
today_done: dict = {}
for r in dup_result.all():
today_done.setdefault(r[0], set()).add(r[1])
already_commented = {aid for aid, types in today_done.items() if "comment" in types}
# 按热度加权commentNum + praiseNum + readNum 越高权重越大 # 按热度加权commentNum + praiseNum + readNum 越高权重越大
# 同时优先未评论过的文章 # 同时优先未评论过的文章
@@ -275,7 +281,7 @@ class SchedulerService:
# 判断是否已评论此文章(用于后续逻辑) # 判断是否已评论此文章(用于后续逻辑)
news_id = str(article.get("recordId") or article.get("id", "")) news_id = str(article.get("recordId") or article.get("id", ""))
already_commented_this = news_id in already_commented already_commented_this = "comment" in today_done.get(news_id, set())
# 接口返回字段: id/newsTitle/content/digest/createUser # 接口返回字段: id/newsTitle/content/digest/createUser
# 广场接口字段recordId=新闻实际ID, id=广场记录ID, title=标题 # 广场接口字段recordId=新闻实际ID, id=广场记录ID, title=标题
@@ -300,23 +306,26 @@ class SchedulerService:
# ① 先记录阅读(每次必做,模拟真实用户打开文章) # ① 先记录阅读(每次必做,模拟真实用户打开文章)
await news_service.read_news(db, user, news_id) await news_service.read_news(db, user, news_id)
# ② 点赞 # 今日已对此文章做过的互动类型
if random.random() < like_prob: done_on_this = today_done.get(news_id, set())
# ② 点赞(每篇文章每用户每天只点赞一次)
if "like" not in done_on_this and random.random() < like_prob:
success, err = await news_service.like_news(db, user, news_id, org_id=article_org_id, to_user_id=news_author, title=news_title) success, err = await news_service.like_news(db, user, news_id, org_id=article_org_id, to_user_id=news_author, title=news_title)
await self._save_record(db, user, news_id, news_title, "like", None, 0, success, err) await self._save_record(db, user, news_id, news_title, "like", None, 0, success, err)
if success: if success:
interactions_done.append("like") interactions_done.append("like")
await self._incr_total(db, user_id) await self._incr_total(db, user_id)
# ③ 收藏(阅读+点赞组合模拟 # ③ 收藏(每篇文章每用户每天只收藏一次
if random.random() < collect_prob: if "collect" not in done_on_this and random.random() < collect_prob:
success, err = await news_service.collect_news(db, user, news_id, org_id=article_org_id, to_user_id=news_author, title=news_title) success, err = await news_service.collect_news(db, user, news_id, org_id=article_org_id, to_user_id=news_author, title=news_title)
await self._save_record(db, user, news_id, news_title, "collect", None, 0, success, err) await self._save_record(db, user, news_id, news_title, "collect", None, 0, success, err)
if success: if success:
interactions_done.append("collect") interactions_done.append("collect")
# ④ 转发(调用 /points/forward/news/{orgId} # ④ 转发(每篇文章每用户每天只转发一次
if random.random() < forward_prob: if "forward" not in done_on_this and random.random() < forward_prob:
success, err = await news_service.forward_news(db, user, news_id) success, err = await news_service.forward_news(db, user, news_id)
await self._save_record(db, user, news_id, news_title, "forward", None, 0, success, err) await self._save_record(db, user, news_id, news_title, "forward", None, 0, success, err)
if success: if success: