fix(comments): 评论栏所有博主都显示成「未知博主」
现象:小红书的和抖音的评论栏,最外层分组全是「未知博主」,分不出谁是谁。 根因是分组接口漏了两个字段。api/routers/monitor.py 里按作品构造桶时只放了 note_id/note_title/note_cover/note_url/comments,而前端 groupByCreator 是用 bucket.creator_hash / bucket.creator_name 分组的 —— 两个都是 undefined,于是所有 博主塌成同一个 key,标签取空串回退成「未知博主」。 数据一直都在:每条评论上都带着 note_creator_hash / note_creator_name (service.py:540-541),只是没往桶上搬。TS 的 CommentBucket 里也声明了这两个字段, 所以是后端没兑现自己的契约,不是前端写错。 修:构造桶时把作品的创作者一并放上去(同一个桶里的评论必然同属一个作品,取哪条都一样)。 测试:种子数据改成「两个作品属于不同博主」(原来是同一个 hash,测不出这个 bug), 新增一条断言每个桶带上自己那个博主、且两个博主的 hash 确实不同。
This commit is contained in:
@@ -172,6 +172,12 @@ async def list_comments(
|
|||||||
"note_title": comment["note_title"],
|
"note_title": comment["note_title"],
|
||||||
"note_cover": comment["note_cover"],
|
"note_cover": comment["note_cover"],
|
||||||
"note_url": comment["note_url"],
|
"note_url": comment["note_url"],
|
||||||
|
# 作品所属的创作者。评论流按 博主 → 作品 → 评论 三级展开时,最外层
|
||||||
|
# 就是按这两个字段分组的 —— 少了它们,前端拿到的是 undefined,
|
||||||
|
# 于是所有博主塌成同一个分组、标签回退成「未知博主」。
|
||||||
|
# 同一个桶里的评论必然同属一个作品,所以取哪一条都一样。
|
||||||
|
"creator_hash": comment["note_creator_hash"],
|
||||||
|
"creator_name": comment["note_creator_name"],
|
||||||
"comments": [],
|
"comments": [],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -49,12 +49,17 @@ async def _seed():
|
|||||||
session.add(task)
|
session.add(task)
|
||||||
await session.flush()
|
await session.flush()
|
||||||
|
|
||||||
for note_id, title in (("note-a", "作品甲"), ("note-b", "作品乙")):
|
# 两个作品**属于不同的博主** —— 评论流最外层按创作者分组,同一个人就没得测了。
|
||||||
|
for note_id, title, creator_hash, creator_name in (
|
||||||
|
("note-a", "作品甲", "hash-a", "博主甲"),
|
||||||
|
("note-b", "作品乙", "hash-b", "博主乙"),
|
||||||
|
):
|
||||||
session.add(
|
session.add(
|
||||||
MonitorNote(
|
MonitorNote(
|
||||||
task_id=task.id, note_id=note_id, title=title,
|
task_id=task.id, note_id=note_id, title=title,
|
||||||
note_url=f"https://www.xiaohongshu.com/explore/{note_id}",
|
note_url=f"https://www.xiaohongshu.com/explore/{note_id}",
|
||||||
cover=f"https://img/{note_id}.jpg", creator_hash="h",
|
cover=f"https://img/{note_id}.jpg", creator_hash=creator_hash,
|
||||||
|
creator_name=creator_name,
|
||||||
source_kind="video", published_at=None,
|
source_kind="video", published_at=None,
|
||||||
first_seen_run_id=1, first_seen_at=1_700_000_000_000,
|
first_seen_run_id=1, first_seen_at=1_700_000_000_000,
|
||||||
last_seen_run_id=1, last_seen_at=1_700_000_000_000,
|
last_seen_run_id=1, last_seen_at=1_700_000_000_000,
|
||||||
@@ -139,6 +144,27 @@ class TestGroupByNote:
|
|||||||
# note-b's only comment is the most recent overall.
|
# note-b's only comment is the most recent overall.
|
||||||
assert groups[0]["note_id"] == "note-b"
|
assert groups[0]["note_id"] == "note-b"
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_each_bucket_carries_its_creator(self, client):
|
||||||
|
"""桶上必须带作品的创作者 —— 评论流最外层就是按它分组的。
|
||||||
|
|
||||||
|
少了这两个字段,前端拿到的 creator_hash / creator_name 都是 undefined,
|
||||||
|
于是所有博主塌成同一个分组、标签回退成「未知博主」:一个人都分不出来。
|
||||||
|
"""
|
||||||
|
groups = {
|
||||||
|
group["note_id"]: group
|
||||||
|
for group in (
|
||||||
|
await client.get("/api/monitor/comments", params={"group_by": "note"})
|
||||||
|
).json()["groups"]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert groups["note-a"]["creator_hash"] == "hash-a"
|
||||||
|
assert groups["note-a"]["creator_name"] == "博主甲"
|
||||||
|
assert groups["note-b"]["creator_hash"] == "hash-b"
|
||||||
|
assert groups["note-b"]["creator_name"] == "博主乙"
|
||||||
|
# 两个作品的创作者必须真的不同,否则界面上照样分不出来。
|
||||||
|
assert groups["note-a"]["creator_hash"] != groups["note-b"]["creator_hash"]
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_flat_shape_is_unchanged_without_the_flag(self, client):
|
async def test_flat_shape_is_unchanged_without_the_flag(self, client):
|
||||||
body = (await client.get("/api/monitor/comments")).json()
|
body = (await client.get("/api/monitor/comments")).json()
|
||||||
|
|||||||
Reference in New Issue
Block a user