feat(repository): enhance repository methods with batch processing and transaction support
All checks were successful
Build Backend / build (push) Successful in 12m50s
Build Backend / build-docker (push) Successful in 2m57s

- 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:
lafay
2026-03-26 01:50:54 +08:00
parent 56bd971e42
commit 7b41dfeb00
9 changed files with 386 additions and 109 deletions

View File

@@ -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 更新帖子置顶状态