feat: 评论支持回复(两级 + @某人)

不做无限层级——手机屏幕撑不住层层缩进,读到第四层就没法看了。
微信、小红书、B站清一色是两级:一级评论 + 其下的回复列表,回复里
用「回复 @某人」表达指向谁。

数据结构:comments 加 parent_id + reply_to_name。回复的回复会被
压平到同一条一级评论下(parent_id 取爷爷的),同时把被回复人的名字
记进 reply_to_name —— 这样既保住两级,又不丢「在跟谁说话」的信息。

几个容易做错的地方:
- 一次查完这一页所有一级评论的回复,不是每条一次查询(N+1)
- 一级评论默认只带 3 条回复,其余点「展开全部 N 条」再拉,避免热门
  评论一次返回几百条
- 删一级评论要连它下面的回复一起删,否则回复变成挂在空处的孤儿;
  帖子的 comment_count 也要按实际删除条数减,不是减 1
- total 统计含回复,和帖子上显示的数字对得上
- replies 为空时返回 [],不是 null

实测四条评论(含一条回复的回复):
  ▸ 甲:一级评论   (2 条回复)
      └ 乙:多久了?
      └ 甲 回复 乙:三天了
  ▸ 乙:另一条一级评论   (0 条回复)
删掉第一条一级评论后 total 4→1,comment_count 同步。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-29 16:33:50 +08:00
parent 535ef08da7
commit 9fc61e878e
8 changed files with 182 additions and 25 deletions
@@ -127,3 +127,16 @@
.cm-count{margin-left:auto;color:var(--muted2);font-size:var(--fs-cap)}
.cm-imgs{display:flex;flex-wrap:wrap;gap:var(--sp-1);margin-top:var(--sp-2)}
.cm-img{width:150rpx;height:150rpx;border-radius:var(--r-sm)}
/* 回复:只缩进一层,再深手机上就没法读了 */
.cm-replies{margin-top:var(--sp-2);padding:var(--sp-2) var(--sp-3);background:var(--surface-2);border-radius:var(--r-sm)}
.cm-reply{font-size:var(--fs-sm);line-height:1.6;color:var(--text);padding:4rpx 0}
.cm-at{color:var(--muted)}
.cm-more{margin-top:6rpx;font-size:var(--fs-cap);color:var(--primary-dark)}
.cm-act{margin-top:var(--sp-2);font-size:var(--fs-cap);color:var(--muted)}
.cm-replying{
display:flex;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-2);
padding:var(--sp-1) var(--sp-3);border-radius:var(--r-full);
background:var(--primary-soft);color:var(--primary-ink);font-size:var(--fs-cap);align-self:flex-start;
}
.cm-cancel{display:flex;align-items:center}