From f52bc7d14712b6dab5cba07d16e0f297e22dd6b3 Mon Sep 17 00:00:00 2001 From: stefanfeng Date: Fri, 3 Apr 2026 10:47:34 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=82=B9=E8=B5=9E/=E6=94=B6=E8=97=8F/?= =?UTF-8?q?=E8=BD=AC=E5=8F=91=E5=90=8C=E4=B8=80=E7=AF=87=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E6=AF=8F=E6=97=A5=E5=8F=AA=E8=A7=A6=E5=8F=91=E4=B8=80=E6=AC=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:同一用户对同一篇文章重复点赞、收藏、转发 原因:去重逻辑只针对评论,未覆盖其他互动类型 修复: - 查询今日所有互动类型的已完成记录(不只是评论) - 点赞/收藏/转发执行前检查 today_done,已做过则跳过 - 概率控制依然有效(未做过的文章才进入随机概率判断) - 评论去重逻辑保持不变 --- backend/app/services/scheduler.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/backend/app/services/scheduler.py b/backend/app/services/scheduler.py index ab6d4b8..d083a45 100755 --- a/backend/app/services/scheduler.py +++ b/backend/app/services/scheduler.py @@ -243,19 +243,25 @@ class SchedulerService: return # ── 文章去重 + 热度加权选取 ───────────────────────────────── - # 查询今日已评论过的文章ID(避免重复评论同一篇) + # 查询今日已互动过的文章(所有类型),避免重复互动同一篇 from sqlalchemy import func as _func from datetime import date as _date today_str = datetime.now().date() dup_result = await db.execute( - select(InteractionRecord.article_id).where( + select( + InteractionRecord.article_id, + InteractionRecord.interact_type, + ).where( InteractionRecord.user_id == user_id, - InteractionRecord.interact_type == "comment", InteractionRecord.status == 1, _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 越高权重越大 # 同时优先未评论过的文章 @@ -275,7 +281,7 @@ class SchedulerService: # 判断是否已评论此文章(用于后续逻辑) 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 # 广场接口字段:recordId=新闻实际ID, id=广场记录ID, title=标题 @@ -300,23 +306,26 @@ class SchedulerService: # ① 先记录阅读(每次必做,模拟真实用户打开文章) 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) await self._save_record(db, user, news_id, news_title, "like", None, 0, success, err) if success: interactions_done.append("like") 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) await self._save_record(db, user, news_id, news_title, "collect", None, 0, success, err) if success: 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) await self._save_record(db, user, news_id, news_title, "forward", None, 0, success, err) if success: