refactor(comment): unify status transitions with atomic count maintenance
Consolidate comment status changes through transitionStatus() to ensure posts.comments_count and comments.replies_count are atomically maintained within the same transaction, preventing inconsistencies between displayed and stored counts. - Remove separate ApplyPublishedStats() calls, now handled in UpdateModerationStatus - Add cache invalidation for admin moderation operations - Update report auto-hide to use unified status transition
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"with_you/internal/cache"
|
||||
"with_you/internal/dto"
|
||||
"with_you/internal/model"
|
||||
"with_you/internal/repository"
|
||||
@@ -24,13 +25,15 @@ type AdminCommentService interface {
|
||||
type adminCommentServiceImpl struct {
|
||||
commentRepo repository.CommentRepository
|
||||
postRepo repository.PostRepository
|
||||
cache cache.Cache
|
||||
}
|
||||
|
||||
// NewAdminCommentService 创建管理端评论服务
|
||||
func NewAdminCommentService(commentRepo repository.CommentRepository, postRepo repository.PostRepository) AdminCommentService {
|
||||
func NewAdminCommentService(commentRepo repository.CommentRepository, postRepo repository.PostRepository, cacheBackend cache.Cache) AdminCommentService {
|
||||
return &adminCommentServiceImpl{
|
||||
commentRepo: commentRepo,
|
||||
postRepo: postRepo,
|
||||
cache: cacheBackend,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,29 +104,49 @@ func (s *adminCommentServiceImpl) BatchDeleteComments(ctx context.Context, ids [
|
||||
}
|
||||
|
||||
func (s *adminCommentServiceImpl) ModerateComment(ctx context.Context, commentID string, status model.CommentStatus, reason, reviewedBy string) (*dto.AdminCommentDetailResponse, error) {
|
||||
_, err := s.commentRepo.GetAdminCommentByID(commentID)
|
||||
if _, err := s.commentRepo.GetAdminCommentByID(commentID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// UpdateModerationStatus 内部已原子地维护帖子评论数/父评论回复数,
|
||||
// 因此管理端审核与自动审核路径的计数行为完全一致。
|
||||
updated, err := s.commentRepo.UpdateModerationStatus(commentID, status, reason, reviewedBy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.commentRepo.UpdateModerationStatus(commentID, status, reason, reviewedBy); err != nil {
|
||||
return nil, err
|
||||
// 状态变更后失效该帖子相关缓存,确保前端立即看到正确计数
|
||||
if s.cache != nil {
|
||||
cache.InvalidatePostDetail(s.cache, updated.PostID)
|
||||
cache.InvalidatePostList(s.cache)
|
||||
}
|
||||
|
||||
comment, err := s.commentRepo.GetAdminCommentByID(commentID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.convertCommentToAdminDetailResponse(comment), nil
|
||||
return s.convertCommentToAdminDetailResponse(updated), nil
|
||||
}
|
||||
|
||||
func (s *adminCommentServiceImpl) BatchModerateComments(ctx context.Context, ids []string, status model.CommentStatus, reviewedBy string) (*dto.AdminBatchOperationResponse, error) {
|
||||
var failedIDs []string
|
||||
// 收集受影响的帖子,用于审核完成后统一失效缓存
|
||||
affectedPostIDs := make(map[string]struct{})
|
||||
|
||||
for _, id := range ids {
|
||||
if err := s.commentRepo.UpdateModerationStatus(id, status, "", reviewedBy); err != nil {
|
||||
// UpdateModerationStatus 内部已原子地维护计数,这里只需收集结果
|
||||
updated, err := s.commentRepo.UpdateModerationStatus(id, status, "", reviewedBy)
|
||||
if err != nil {
|
||||
failedIDs = append(failedIDs, id)
|
||||
continue
|
||||
}
|
||||
if updated != nil {
|
||||
affectedPostIDs[updated.PostID] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// 统一失效受影响帖子的缓存
|
||||
if s.cache != nil {
|
||||
for postID := range affectedPostIDs {
|
||||
cache.InvalidatePostDetail(s.cache, postID)
|
||||
}
|
||||
cache.InvalidatePostList(s.cache)
|
||||
}
|
||||
|
||||
if len(failedIDs) == 0 {
|
||||
|
||||
Reference in New Issue
Block a user