From ae15025b1d0566c100b1c990e83e7bbbf2baf59d Mon Sep 17 00:00:00 2001 From: Victor_Jay Date: Wed, 3 Jun 2026 01:00:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20@=E6=8F=90=E5=8F=8A=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=94=B9=E5=90=8D=E5=90=8E=E9=93=BE=E6=8E=A5=E8=B7=9F=E9=9A=8F?= =?UTF-8?q?UID=20+=20=E6=98=BE=E7=A4=BA=E5=90=8D=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - comment_mentions新增original_username列,创建时记录原始@用户名 - Mentions map改为{original_username: {uid, name}}结构,name为当前显示名 - 用户改名后:旧@文本仍能匹配original_username,链接跟随uid不变,显示名自动更新 - 前端renderMentions适配新结构 --- internal/model/comment.go | 21 ++++++++++----- internal/repository/comment_mention_repo.go | 26 +++++++++++-------- internal/service/comment_service.go | 5 ++-- .../MetaLab-2026/static/js/post-comments.js | 10 +++---- 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/internal/model/comment.go b/internal/model/comment.go index 082bb47..e81e9c3 100644 --- a/internal/model/comment.go +++ b/internal/model/comment.go @@ -25,16 +25,23 @@ type Comment struct { ReplyToName string `gorm:"-:migration;<-:false" json:"reply_to_name,omitempty"` // RepliesCount 回复数(非DB字段,查询填充) RepliesCount int `gorm:"-:migration;<-:false" json:"replies_count,omitempty"` - // Mentions 有效@提及映射 username -> uid(非DB字段,批量查询填充) - // 前端据此判断 @username 是否为有效提及并生成链接 - Mentions map[string]uint `gorm:"-" json:"mentions,omitempty"` + // Mentions 有效@提及映射 original_username -> {uid, 当前显示名}(非DB字段,批量查询填充) + // key=创建时的原始@用户名,value={uid,当前显示名},用户改名后链接仍有效且显示新名 + Mentions map[string]MentionInfo `gorm:"-" json:"mentions,omitempty"` } -// CommentMention @提及映射(绑定UID,不是username,支持改名后自动更新显示名) +// CommentMention @提及映射(绑定UID + 原始用户名,支持改名后自动更新显示名) type CommentMention struct { - ID uint `gorm:"primarykey" json:"id"` - CommentID uint `gorm:"uniqueIndex:idx_comment_uid,priority:1;not null" json:"comment_id"` - UID uint `gorm:"uniqueIndex:idx_comment_uid,priority:2;not null" json:"uid"` + ID uint `gorm:"primarykey" json:"id"` + CommentID uint `gorm:"uniqueIndex:idx_comment_uid,priority:1;not null" json:"comment_id"` + UID uint `gorm:"uniqueIndex:idx_comment_uid,priority:2;not null" json:"uid"` + OriginalUsername string `gorm:"type:varchar(64);not null;default:''" json:"original_username"` +} + +// MentionInfo @提及显示信息(前端渲染用) +type MentionInfo struct { + UID uint `json:"uid"` + Name string `json:"name"` // 当前显示名 } // UserSearchResult @搜索用户结果 diff --git a/internal/repository/comment_mention_repo.go b/internal/repository/comment_mention_repo.go index 647ba0a..cdbfd3a 100644 --- a/internal/repository/comment_mention_repo.go +++ b/internal/repository/comment_mention_repo.go @@ -17,8 +17,9 @@ func (r *CommentRepo) FindMentionsByComment(commentID uint) ([]model.CommentMent return list, err } -// LoadMentionsForComments 批量加载多条评论的有效@提及映射(username -> uid) -// 传入的 comments 会被原地修改,填充 Mentions 字段 +// LoadMentionsForComments 批量加载多条评论的有效@提及映射 +// key=创建时的原始@用户名, value={uid, 用户当前显示名} +// 用户改名后:原始名匹配body中的旧@文本,显示名随users表更新 func (r *CommentRepo) LoadMentionsForComments(comments []model.Comment) error { if len(comments) == 0 { return nil @@ -29,15 +30,15 @@ func (r *CommentRepo) LoadMentionsForComments(comments []model.Comment) error { commentIDs[i] = c.ID } - // 查询 comment_mentions JOIN users,拿到 username 和 uid type mentionRow struct { - CommentID uint - UID uint - Username string + CommentID uint + UID uint + OriginalUsername string + CurrentName string } var rows []mentionRow err := r.db.Table("comment_mentions"). - Select("comment_mentions.comment_id, comment_mentions.uid, users.username"). + Select("comment_mentions.comment_id, comment_mentions.uid, comment_mentions.original_username, users.username AS current_name"). Joins("LEFT JOIN users ON users.id = comment_mentions.uid"). Where("comment_mentions.comment_id IN ?", commentIDs). Find(&rows).Error @@ -45,13 +46,16 @@ func (r *CommentRepo) LoadMentionsForComments(comments []model.Comment) error { return err } - // 按 comment_id 分组 - mentionMap := make(map[uint]map[string]uint) + // 按 comment_id 分组,key = original_username, value = MentionInfo + mentionMap := make(map[uint]map[string]model.MentionInfo) for _, row := range rows { if mentionMap[row.CommentID] == nil { - mentionMap[row.CommentID] = make(map[string]uint) + mentionMap[row.CommentID] = make(map[string]model.MentionInfo) + } + mentionMap[row.CommentID][row.OriginalUsername] = model.MentionInfo{ + UID: row.UID, + Name: row.CurrentName, } - mentionMap[row.CommentID][row.Username] = row.UID } for i := range comments { diff --git a/internal/service/comment_service.go b/internal/service/comment_service.go index 387b073..ea31107 100644 --- a/internal/service/comment_service.go +++ b/internal/service/comment_service.go @@ -222,8 +222,9 @@ func (s *CommentService) parseMentions(commentID uint, body string) { rows, _ := s.repo.SearchUsersByLevel(username, 2, 1) if len(rows) > 0 { _ = s.repo.CreateMention(&model.CommentMention{ - CommentID: commentID, - UID: rows[0].UID, + CommentID: commentID, + UID: rows[0].UID, + OriginalUsername: username, }) } } diff --git a/templates/MetaLab-2026/static/js/post-comments.js b/templates/MetaLab-2026/static/js/post-comments.js index 26809bd..a196bd4 100644 --- a/templates/MetaLab-2026/static/js/post-comments.js +++ b/templates/MetaLab-2026/static/js/post-comments.js @@ -14,17 +14,17 @@ var currentPage = 1; var totalPages = 1; - // 渲染@提及:有效提及渲染为蓝色链接,无效提及保持纯文本 + // 渲染@提及:有效提及渲染为蓝色链接(显示当前用户名),无效提及保持纯文本 + // mentions: { original_username: {uid, name} } — name为当前显示名,用户改名后自动更新 function renderMentions(body, mentions) { body = escapeHtml(body); if (!mentions || Object.keys(mentions).length === 0) { - // 无 mentions 数据时仍高亮@,但不加链接(降级处理) return body.replace(/@(\S{1,16})/g, '@$1'); } return body.replace(/@(\S{1,16})/g, function(match, username) { - var uid = mentions[username]; - if (uid) { - return '@' + escapeHtml(username) + ''; + var info = mentions[username]; + if (info && info.uid) { + return '@' + escapeHtml(info.name) + ''; } return match; });