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;
});