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:
@@ -802,30 +802,101 @@ func (r *PostRepository) GetByIDForAdmin(id string) (*model.Post, error) {
|
||||
return &post, nil
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除帖子
|
||||
// BatchDelete 批量删除帖子(使用单次事务批量删除,避免 N+1 问题)
|
||||
func (r *PostRepository) 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
|
||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
||||
// 批量删除帖子图片
|
||||
if err := tx.Where("post_id IN ?", ids).Delete(&model.PostImage{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 批量删除帖子点赞记录
|
||||
if err := tx.Where("post_id IN ?", ids).Delete(&model.PostLike{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 批量删除帖子收藏记录
|
||||
if err := tx.Where("post_id IN ?", ids).Delete(&model.Favorite{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 批量删除评论点赞记录(子查询获取所有评论ID)
|
||||
if err := tx.Where("comment_id IN (SELECT id FROM comments WHERE post_id IN ?)", ids).Delete(&model.CommentLike{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 批量删除帖子评论
|
||||
if err := tx.Where("post_id IN ?", ids).Delete(&model.Comment{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 批量删除投票选项
|
||||
if err := tx.Where("post_id IN ?", ids).Delete(&model.VoteOption{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 批量删除用户投票记录
|
||||
if err := tx.Where("post_id IN ?", ids).Delete(&model.UserVote{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 最后批量删除帖子本身(软删除)
|
||||
return tx.Where("id IN ?", ids).Delete(&model.Post{}).Error
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return ids, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// BatchUpdateStatus 批量更新帖子审核状态
|
||||
// BatchUpdateStatus 批量更新帖子审核状态(使用单条 SQL 批量更新,避免 N+1 问题)
|
||||
func (r *PostRepository) BatchUpdateStatus(ids []string, status model.PostStatus, reviewedBy string) ([]string, error) {
|
||||
var failedIDs []string
|
||||
|
||||
for _, id := range ids {
|
||||
if err := r.UpdateModerationStatus(id, status, "", reviewedBy); err != nil {
|
||||
failedIDs = append(failedIDs, id)
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return failedIDs, nil
|
||||
// 使用单条 SQL 批量更新
|
||||
result := r.db.Model(&model.Post{}).
|
||||
Where("id IN ?", ids).
|
||||
Updates(map[string]any{
|
||||
"status": status,
|
||||
"reviewed_at": gorm.Expr("CURRENT_TIMESTAMP"),
|
||||
"reviewed_by": reviewedBy,
|
||||
"reject_reason": "",
|
||||
"updated_at": gorm.Expr("updated_at"),
|
||||
})
|
||||
|
||||
if result.Error != nil {
|
||||
return ids, result.Error
|
||||
}
|
||||
|
||||
// 返回实际更新的帖子数量
|
||||
if result.RowsAffected < int64(len(ids)) {
|
||||
// 部分帖子可能不存在,查询实际更新的 ID
|
||||
var updatedIDs []string
|
||||
r.db.Model(&model.Post{}).Where("id IN ?", ids).Pluck("id", &updatedIDs)
|
||||
|
||||
// 找出未更新的 ID
|
||||
updatedMap := make(map[string]bool, len(updatedIDs))
|
||||
for _, id := range updatedIDs {
|
||||
updatedMap[id] = true
|
||||
}
|
||||
|
||||
var failedIDs []string
|
||||
for _, id := range ids {
|
||||
if !updatedMap[id] {
|
||||
failedIDs = append(failedIDs, id)
|
||||
}
|
||||
}
|
||||
return failedIDs, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// UpdatePinStatus 更新帖子置顶状态
|
||||
|
||||
Reference in New Issue
Block a user