fix: UID 类型混用统一(uint ↔ string)

- Comment.ReplyToUID string→uint, 移除 varchar(36) gorm 约束
- CommentMention.UID string→uint, 移除 varchar(36) gorm 约束
- UserSearchResult.UID string→uint
- 移除 SearchUsersByLevel 中 strconv.FormatUint 转换
- 删除 GetUserUIDByID 方法,CreateReply 直接使用 parent.UserID
- fillReplyToNames 使用 map[uint]string 替代 map[string]string
- 更新 commentStore 接口声明
- 修复前端 mention 下拉 show.html 中 u.id→u.uid
This commit is contained in:
2026-06-02 19:26:44 +08:00
parent 5911cee01c
commit 99d16190a8
6 changed files with 18 additions and 34 deletions

View File

@ -8,7 +8,7 @@ type Comment struct {
PostID uint `gorm:"index;not null" json:"post_id"` PostID uint `gorm:"index;not null" json:"post_id"`
RootID uint `gorm:"index;not null" json:"root_id"` // 根评论ID顶级评论指向自身 RootID uint `gorm:"index;not null" json:"root_id"` // 根评论ID顶级评论指向自身
ParentID *uint `gorm:"index" json:"parent_id"` // 父评论IDNULL=顶级评论 ParentID *uint `gorm:"index" json:"parent_id"` // 父评论IDNULL=顶级评论
ReplyToUID string `gorm:"type:varchar(36);default:''" json:"reply_to_uid"` // 被回复者UID ReplyToUID uint `gorm:"default:0" json:"reply_to_uid"` // 被回复者UID
Body string `gorm:"type:text;not null" json:"body"` // 评论内容(纯文本 + 图片URL Body string `gorm:"type:text;not null" json:"body"` // 评论内容(纯文本 + 图片URL
IsDeleted bool `gorm:"default:false;index" json:"is_deleted"` IsDeleted bool `gorm:"default:false;index" json:"is_deleted"`
LikesCount int `gorm:"default:0" json:"likes_count"` LikesCount int `gorm:"default:0" json:"likes_count"`
@ -31,12 +31,12 @@ type Comment struct {
type CommentMention struct { type CommentMention struct {
ID uint `gorm:"primarykey" json:"id"` ID uint `gorm:"primarykey" json:"id"`
CommentID uint `gorm:"uniqueIndex:idx_comment_uid,priority:1;not null" json:"comment_id"` CommentID uint `gorm:"uniqueIndex:idx_comment_uid,priority:1;not null" json:"comment_id"`
UID string `gorm:"type:varchar(36);uniqueIndex:idx_comment_uid,priority:2;not null" json:"uid"` UID uint `gorm:"uniqueIndex:idx_comment_uid,priority:2;not null" json:"uid"`
} }
// UserSearchResult @搜索用户结果 // UserSearchResult @搜索用户结果
type UserSearchResult struct { type UserSearchResult struct {
UID string `json:"uid"` UID uint `json:"uid"`
Username string `json:"username"` Username string `json:"username"`
Level int `json:"level"` Level int `json:"level"`
} }

View File

@ -1,8 +1,6 @@
package repository package repository
import ( import (
"strconv"
"metazone.cc/metalab/internal/model" "metazone.cc/metalab/internal/model"
"metazone.cc/metalab/internal/service" "metazone.cc/metalab/internal/service"
) )
@ -21,7 +19,7 @@ func (r *CommentRepo) FindMentionsByComment(commentID uint) ([]model.CommentMent
// SearchUsersByLevel 搜索指定等级及以上用户(用于@艾特),返回 uid/username/exp // SearchUsersByLevel 搜索指定等级及以上用户(用于@艾特),返回 uid/username/exp
func (r *CommentRepo) SearchUsersByLevel(keyword string, minLevel int, limit int) ([]struct { func (r *CommentRepo) SearchUsersByLevel(keyword string, minLevel int, limit int) ([]struct {
UID string UID uint
Username string Username string
Exp int Exp int
}, error) { }, error) {
@ -42,30 +40,20 @@ func (r *CommentRepo) SearchUsersByLevel(keyword string, minLevel int, limit int
Find(&list).Error Find(&list).Error
var res []struct { var res []struct {
UID string UID uint
Username string Username string
Exp int Exp int
} }
for _, u := range list { for _, u := range list {
res = append(res, struct { res = append(res, struct {
UID string UID uint
Username string Username string
Exp int Exp int
}{UID: strconv.FormatUint(uint64(u.UID), 10), Username: u.Username, Exp: u.Exp}) }{UID: u.UID, Username: u.Username, Exp: u.Exp})
} }
return res, err return res, err
} }
// GetUserUIDByID 通过 uint ID 获取 user 的 UID 字符串
func (r *CommentRepo) GetUserUIDByID(userID uint) (string, error) {
var uid uint
err := r.db.Table("users").Select("id").Where("id = ?", userID).Scan(&uid).Error
if err != nil {
return "", err
}
return strconv.FormatUint(uint64(uid), 10), nil
}
// GetUsernameByID 通过 userID 获取用户名(用于通知内容) // GetUsernameByID 通过 userID 获取用户名(用于通知内容)
func (r *CommentRepo) GetUsernameByID(userID uint) (string, error) { func (r *CommentRepo) GetUsernameByID(userID uint) (string, error) {
var username string var username string

View File

@ -96,7 +96,7 @@ func (r *CommentRepo) fillReplyToNames(list []model.Comment) {
return return
} }
type nameRow struct { type nameRow struct {
UID string UID uint
Username string Username string
} }
var rows []nameRow var rows []nameRow
@ -105,12 +105,12 @@ func (r *CommentRepo) fillReplyToNames(list []model.Comment) {
Where("id IN (SELECT reply_to_uid FROM comments WHERE root_id IN (?) AND parent_id IS NOT NULL)", r.rootIDsFromList(list)). Where("id IN (SELECT reply_to_uid FROM comments WHERE root_id IN (?) AND parent_id IS NOT NULL)", r.rootIDsFromList(list)).
Find(&rows) Find(&rows)
m := make(map[string]string) m := make(map[uint]string)
for _, row := range rows { for _, row := range rows {
m[row.UID] = row.Username m[row.UID] = row.Username
} }
for i := range list { for i := range list {
if list[i].ReplyToUID != "" { if list[i].ReplyToUID != 0 {
list[i].ReplyToName = m[list[i].ReplyToUID] list[i].ReplyToName = m[list[i].ReplyToUID]
} }
} }

View File

@ -93,10 +93,7 @@ func (s *CommentService) CreateReply(userID uint, parentID uint, body string) (*
ParentID: &parentID, ParentID: &parentID,
Body: body, Body: body,
UserID: userID, UserID: userID,
} ReplyToUID: parent.UserID,
// 获取被回复者UID
if replyToUID, err := s.repo.GetUserUIDByID(parent.UserID); err == nil {
comment.ReplyToUID = replyToUID
} }
if err := s.repo.Create(comment); err != nil { if err := s.repo.Create(comment); err != nil {

View File

@ -154,11 +154,10 @@ type commentStore interface {
FindPostIDByComment(commentID uint) (uint, error) FindPostIDByComment(commentID uint) (uint, error)
FindPostAuthorID(postID uint) (uint, error) FindPostAuthorID(postID uint) (uint, error)
SearchUsersByLevel(keyword string, minLevel, limit int) ([]struct { SearchUsersByLevel(keyword string, minLevel, limit int) ([]struct {
UID string UID uint
Username string Username string
Exp int Exp int
}, error) }, error)
GetUserUIDByID(userID uint) (string, error)
GetUsernameByID(userID uint) (string, error) GetUsernameByID(userID uint) (string, error)
ListAllComments(keyword string, showDeleted bool, offset, limit int) ([]model.AdminCommentRow, int64, error) ListAllComments(keyword string, showDeleted bool, offset, limit int) ([]model.AdminCommentRow, int64, error)
} }

View File

@ -931,7 +931,7 @@
let u = users[i]; let u = users[i];
var item = document.createElement('div'); var item = document.createElement('div');
item.className = 'mention-item'; item.className = 'mention-item';
item.innerHTML = '<span class="mention-username">' + escapeHtml(u.username) + '</span><span class="mention-uid">' + escapeHtml(u.id) + '</span>'; item.innerHTML = '<span class="mention-username">' + escapeHtml(u.username) + '</span><span class="mention-uid">' + escapeHtml(u.uid) + '</span>';
item.addEventListener('mousedown', function(e) { item.addEventListener('mousedown', function(e) {
e.preventDefault(); e.preventDefault();
selectMention(u); selectMention(u);