feat(repository): enhance repository methods with batch processing and transaction support
- Updated Like and Unlike methods in CommentRepository to use transactions for data consistency. - Introduced IsLikedBatch method for batch checking if comments are liked, addressing N+1 query issues. - Enhanced BatchDelete method in PostRepository to perform batch deletions within a single transaction, improving efficiency. - Added BatchUpdateStatus method for posts to utilize a single SQL update for status changes, reducing database load. - Implemented BatchUpdateSortOrder in StickerRepository using CASE WHEN for efficient sorting updates. - Added IsFollowingBatch and IsBlockedBatch methods in UserRepository for batch checking follow and block relationships, optimizing performance.
This commit is contained in:
@@ -255,46 +255,49 @@ func (r *CommentRepository) GetReplies(parentID string) ([]*model.Comment, error
|
||||
return comments, err
|
||||
}
|
||||
|
||||
// Like 点赞评论
|
||||
// Like 点赞评论(使用事务保证数据一致性)
|
||||
func (r *CommentRepository) Like(commentID, userID string) error {
|
||||
// 检查是否已经点赞
|
||||
var existing model.CommentLike
|
||||
err := r.db.Where("comment_id = ? AND user_id = ?", commentID, userID).First(&existing).Error
|
||||
if err == nil {
|
||||
// 已经点赞
|
||||
return nil
|
||||
}
|
||||
if err != gorm.ErrRecordNotFound {
|
||||
return err
|
||||
}
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
// 检查是否已经点赞
|
||||
var existing model.CommentLike
|
||||
err := tx.Where("comment_id = ? AND user_id = ?", commentID, userID).First(&existing).Error
|
||||
if err == nil {
|
||||
// 已经点赞
|
||||
return nil
|
||||
}
|
||||
if err != gorm.ErrRecordNotFound {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建点赞记录
|
||||
like := &model.CommentLike{
|
||||
CommentID: commentID,
|
||||
UserID: userID,
|
||||
}
|
||||
err = r.db.Create(like).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 创建点赞记录
|
||||
like := &model.CommentLike{
|
||||
CommentID: commentID,
|
||||
UserID: userID,
|
||||
}
|
||||
if err := tx.Create(like).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 增加评论点赞数
|
||||
return r.db.Model(&model.Comment{}).Where("id = ?", commentID).
|
||||
UpdateColumn("likes_count", gorm.Expr("likes_count + 1")).Error
|
||||
// 增加评论点赞数
|
||||
return tx.Model(&model.Comment{}).Where("id = ?", commentID).
|
||||
UpdateColumn("likes_count", gorm.Expr("likes_count + 1")).Error
|
||||
})
|
||||
}
|
||||
|
||||
// Unlike 取消点赞评论
|
||||
// Unlike 取消点赞评论(使用事务保证数据一致性)
|
||||
func (r *CommentRepository) Unlike(commentID, userID string) error {
|
||||
result := r.db.Where("comment_id = ? AND user_id = ?", commentID, userID).Delete(&model.CommentLike{})
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected > 0 {
|
||||
// 减少评论点赞数
|
||||
return r.db.Model(&model.Comment{}).Where("id = ?", commentID).
|
||||
UpdateColumn("likes_count", gorm.Expr("likes_count - 1")).Error
|
||||
}
|
||||
return nil
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
result := tx.Where("comment_id = ? AND user_id = ?", commentID, userID).Delete(&model.CommentLike{})
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected > 0 {
|
||||
// 减少评论点赞数
|
||||
return tx.Model(&model.Comment{}).Where("id = ?", commentID).
|
||||
UpdateColumn("likes_count", gorm.Expr("likes_count - 1")).Error
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// IsLiked 检查是否已点赞
|
||||
@@ -304,6 +307,33 @@ func (r *CommentRepository) IsLiked(commentID, userID string) bool {
|
||||
return count > 0
|
||||
}
|
||||
|
||||
// IsLikedBatch 批量检查是否点赞(解决 N+1 问题)
|
||||
// 返回 map[commentID]bool
|
||||
func (r *CommentRepository) IsLikedBatch(commentIDs []string, userID string) map[string]bool {
|
||||
result := make(map[string]bool)
|
||||
if len(commentIDs) == 0 || userID == "" {
|
||||
return result
|
||||
}
|
||||
|
||||
// 初始化所有 commentID 为 false
|
||||
for _, commentID := range commentIDs {
|
||||
result[commentID] = false
|
||||
}
|
||||
|
||||
// 一次性查询所有点赞记录
|
||||
var likedCommentIDs []string
|
||||
r.db.Model(&model.CommentLike{}).
|
||||
Where("comment_id IN ? AND user_id = ?", commentIDs, userID).
|
||||
Pluck("comment_id", &likedCommentIDs)
|
||||
|
||||
// 更新已点赞的评论
|
||||
for _, commentID := range likedCommentIDs {
|
||||
result[commentID] = true
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// AdminCommentListFilter 管理端评论列表筛选条件
|
||||
type AdminCommentListFilter struct {
|
||||
Keyword string
|
||||
@@ -367,17 +397,58 @@ func (r *CommentRepository) GetAdminCommentByID(id string) (*model.Comment, erro
|
||||
return &comment, nil
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除评论
|
||||
// BatchDelete 批量删除评论(使用单次事务批量删除,避免 N+1 问题)
|
||||
func (r *CommentRepository) BatchDelete(ids []string) ([]string, error) {
|
||||
var failedIDs []string
|
||||
|
||||
for _, id := range ids {
|
||||
if err := r.Delete(id); err != nil {
|
||||
failedIDs = append(failedIDs, id)
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return failedIDs, nil
|
||||
// 先查询所有评论获取 post_id 和状态信息
|
||||
type commentInfo struct {
|
||||
ID string
|
||||
PostID string
|
||||
Status model.CommentStatus
|
||||
}
|
||||
var comments []commentInfo
|
||||
if err := r.db.Model(&model.Comment{}).Where("id IN ?", ids).Scan(&comments).Error; err != nil {
|
||||
return ids, err
|
||||
}
|
||||
|
||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
||||
// 批量删除评论点赞记录
|
||||
if err := tx.Where("comment_id IN ?", ids).Delete(&model.CommentLike{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 批量删除评论(软删除)
|
||||
if err := tx.Where("id IN ?", ids).Delete(&model.Comment{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新帖子的评论数(仅统计已发布评论)
|
||||
postCountMap := make(map[string]int)
|
||||
for _, c := range comments {
|
||||
if c.Status == model.CommentStatusPublished {
|
||||
postCountMap[c.PostID]++
|
||||
}
|
||||
}
|
||||
for postID, count := range postCountMap {
|
||||
if err := tx.Model(&model.Post{}).Where("id = ?", postID).
|
||||
UpdateColumns(map[string]any{
|
||||
"comments_count": gorm.Expr("comments_count - ?", count),
|
||||
"updated_at": gorm.Expr("updated_at"),
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return ids, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// GetCommentsByPostIDForAdmin 管理端获取帖子的评论列表(包含所有状态)
|
||||
|
||||
Reference in New Issue
Block a user