From 7cdb4d66988a14e262c7663a4a0a0e77e156feb1 Mon Sep 17 00:00:00 2001 From: Victor_Jay Date: Tue, 2 Jun 2026 15:25:17 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20GetOverview=205=20=E6=AC=A1?= =?UTF-8?q?=E7=8B=AC=E7=AB=8B=E6=9F=A5=E8=AF=A2=E5=90=88=E5=B9=B6=E4=B8=BA?= =?UTF-8?q?=E5=8D=95=E6=AC=A1=20GROUP=20BY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 PostRepo.GetOverviewByUserID 单次 CASE WHEN + GROUP BY 查询 - Service 层 GetOverview 从 5 次 DB 查询减少为 1 次 - 接口 postStore 新增 GetOverviewByUserID 声明 --- internal/repository/post_repo.go | 25 +++++++++++++++++++++++++ internal/service/post_service.go | 10 ++-------- internal/service/repository.go | 1 + 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/internal/repository/post_repo.go b/internal/repository/post_repo.go index 507b75b..279923c 100644 --- a/internal/repository/post_repo.go +++ b/internal/repository/post_repo.go @@ -108,6 +108,31 @@ func (r *PostRepo) GetUserStats(userID uint) (likes, favorites, reads int64, err return s.TotalLikes, s.TotalFavorites, s.TotalReads, err } +// overviewRow GetOverviewByUserID 单次 GROUP BY 查询结果行 +type overviewRow struct { + TotalPosts int64 + DraftCount int64 + PendingCount int64 + ApprovedCount int64 + RejectedCount int64 +} + +// GetOverviewByUserID 用单次 GROUP BY 查询聚合用户各状态文章数 +func (r *PostRepo) GetOverviewByUserID(userID uint) (totalPosts, draftCount, pendingCount, approvedCount, rejectedCount int64, err error) { + var row overviewRow + err = r.db.Model(&model.Post{}). + Select(` + COUNT(*) AS total_posts, + COALESCE(SUM(CASE WHEN status = 'draft' THEN 1 ELSE 0 END), 0) AS draft_count, + COALESCE(SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END), 0) AS pending_count, + COALESCE(SUM(CASE WHEN status = 'approved' THEN 1 ELSE 0 END), 0) AS approved_count, + COALESCE(SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END), 0) AS rejected_count + `). + Where("user_id = ? AND deleted_at IS NULL", userID). + Scan(&row).Error + return row.TotalPosts, row.DraftCount, row.PendingCount, row.ApprovedCount, row.RejectedCount, err +} + // FindByUserIDAndStatus 分页查询某用户指定状态的帖子(空 status=全状态) func (r *PostRepo) FindByUserIDAndStatus(userID uint, status string, offset, limit int) ([]model.Post, int64, error) { query := r.buildQuery("", status). diff --git a/internal/service/post_service.go b/internal/service/post_service.go index fb20820..683d4a6 100644 --- a/internal/service/post_service.go +++ b/internal/service/post_service.go @@ -187,18 +187,12 @@ type StudioOverview struct { RejectedCount int64 `json:"rejected_count"` } -// GetOverview 获取创作中心数据概览 +// GetOverview 获取创作中心数据概览(单次 GROUP BY 查询) func (s *PostService) GetOverview(userID uint) (*StudioOverview, error) { - // 获取各状态文章数量(分页传 1 条只取 total) - _, totalPosts, err := s.repo.FindByUserIDAndStatus(userID, "", 0, 1) + totalPosts, draftCount, pendingCount, approvedCount, rejectedCount, err := s.repo.GetOverviewByUserID(userID) if err != nil { return nil, err } - _, draftCount, _ := s.repo.FindByUserIDAndStatus(userID, model.PostStatusDraft, 0, 1) - _, pendingCount, _ := s.repo.FindByUserIDAndStatus(userID, model.PostStatusPending, 0, 1) - _, approvedCount, _ := s.repo.FindByUserIDAndStatus(userID, model.PostStatusApproved, 0, 1) - _, rejectedCount, _ := s.repo.FindByUserIDAndStatus(userID, model.PostStatusRejected, 0, 1) - return &StudioOverview{ TotalPosts: totalPosts, DraftCount: draftCount, diff --git a/internal/service/repository.go b/internal/service/repository.go index c67bf1d..d0ab248 100644 --- a/internal/service/repository.go +++ b/internal/service/repository.go @@ -37,6 +37,7 @@ type postStore interface { FindPageable(keyword string, offset, limit int) ([]model.Post, int64, error) FindAdminPageable(keyword, status string, offset, limit int) ([]model.Post, int64, error) FindByUserIDAndStatus(userID uint, status string, offset, limit int) ([]model.Post, int64, error) + GetOverviewByUserID(userID uint) (totalPosts, draftCount, pendingCount, approvedCount, rejectedCount int64, err error) FindPendingRevisions(keyword string, offset, limit int) ([]model.Post, int64, error) Update(post *model.Post) error SoftDelete(id uint) error