互动:评论 / 投票 / 收藏 / 点赞 / 关注
互动(Engagement)子域承载「人对内容的反应」。它的核心设计是一句话:互动与具体内容解耦。评论、点赞、收藏、微反应都用 SubjectId + 一个形态枚举(CommentSubjectType / UserLike 的 SubjectType / BookmarkSubjectType)指向「被作用的内容」,而不是为文章和沸点各建一套 CommentForArticle / CommentForShortMsg 表。
为什么这样划:Content 关注「内容本体」,Engagement 关注「人对内容的反应」。二者通过
SubjectId关联而非互相引用,让点赞、收藏、评论可以无差别地作用到文章或沸点上,新增内容形态时互动层几乎不用改。
概念与关系
评论(Comment)
Comment(cms_comment)通过 SubjectId + SubjectType(CommentSubjectType.ArticleComment 等)挂到内容;RootCommentId + RespId 支撑多级回复(评论下还能再评论)。发表评论要过三重可评论校验:系统级总开关、用户级、内容级(Article.Commentable / ShortMsg.CommentType)——只有三者都允许才放行。
投票(Poll)
Poll 由 IPollService 管理,支持单选/多选、起止时间、选项计票。它主要挂在沸点上(ShortMsg.PollId),是内容生产侧就内嵌的互动组件。
收藏(Bookmark / BookmarkItem)
两层结构:Bookmark 是收藏夹,BookmarkItem 是收藏项。对内容的收藏/取消是幂等切换(CreateCancelBookmarkItemReq),同一用户同一内容反复点击只产生一条收藏项。
点赞 / 踩(UserLike)
UserLike 提供点赞与「踩」两类反馈,均为幂等切换(CreateOrCancelAsync / CreateOrCancelDislikeAsync)。SubjectType 区分文章/沸点等目标。
微反应 Boost
介于「点赞」与「评论」之间的轻量表情反应(BoostService),内容不超过若干字符——适合快速表达情绪而不必写评论。
关注 / 粉丝(UserSubscribe)
UserSubscribe 维护用户间关注关系(SubscribeUserId 指向被关注者),支撑「我的关注 / 我的粉丝」。
用户标签(UserTag)
用户可订阅标签,用于个性化推荐与聚合(标签权重会进入用户画像,见 发现)。
互动日志(UserInteractionLog)
IUserInteractionLogService 记录浏览/点赞/评论/收藏/分享等行为(带 EntityType / EntityId),供推荐画像与看板使用。每日全量重算用户画像(CmsKitJobService.DailyProfileRebuildAsync)正是以这些日志 + 点赞 + 收藏 + 关注为输入,按时间衰减算出用户对标签/频道/话题/圈子/作者的权重。
业务能力
- 多级评论,系统/用户/内容三重可评论校验;
- 单选/多选投票,起止时间与计票;
- 收藏夹 + 收藏项,幂等切换;
- 点赞 / 踩,幂等切换;
- 微反应 Boost;
- 用户间关注 / 粉丝;
- 用户标签订阅(驱动个性化);
- 互动行为日志(驱动推荐与统计看板)。
开发示例
// 注入 ICommentService 对文章发表评论(SubjectType 区分内容形态)
await _commentService.CreateAsync(new CreateCommentReq
{
SubjectType = CommentSubjectType.ArticleComment,
SubjectId = articleId,
Text = "写得很棒!"
});
// 注入 IUserLikeService 给文章点赞(幂等)
await _userLikeService.CreateOrCancelAsync(new CreateUpdateUserLikeReq
{
SubjectType = UserLikeSubjectType.UserLikeArticle,
SubjectId = articleId
});