package service import ( "context" "github.com/topfans/backend/pkg/proto/ranking" "github.com/topfans/backend/pkg/proto/common" "github.com/topfans/backend/services/assetService/client" "github.com/topfans/backend/services/assetService/repository" ) // RankingService 排行榜Service接口 type RankingService interface { // GetHotRanking 获取热度排行榜 GetHotRanking(ctx context.Context, req *ranking.GetRankingRequest) (*ranking.GetRankingResponse, error) // GetOriginalRanking 获取自制排行榜 GetOriginalRanking(ctx context.Context, req *ranking.GetRankingRequest) (*ranking.GetRankingResponse, error) } // rankingService 排行榜Service实现 type rankingService struct { rankingRepo repository.RankingRepository userClient client.UserServiceClient } // NewRankingService 创建排行榜Service实例 func NewRankingService(rankingRepo repository.RankingRepository, userClient client.UserServiceClient) RankingService { return &rankingService{ rankingRepo: rankingRepo, userClient: userClient, } } // GetHotRanking 获取热度排行榜 func (s *rankingService) GetHotRanking(ctx context.Context, req *ranking.GetRankingRequest) (*ranking.GetRankingResponse, error) { // 参数校验 if req.Dimension == "" { req.Dimension = "total" } if req.Page <= 0 { req.Page = 1 } if req.PageSize <= 0 { req.PageSize = 10 } starID := req.StarId if starID <= 0 { // TODO: 从ctx获取当前用户的starID starID = 87 // 默认值,待从JWT获取 } offset := (int(req.Page) - 1) * int(req.PageSize) // 获取排行榜列表 var items []*repository.RankingItem var total int64 var err error switch req.Dimension { case "displaying": items, total, err = s.rankingRepo.GetHotRankingDisplaying(starID, int(req.PageSize), offset) case "month": items, total, err = s.rankingRepo.GetHotRankingMonth(starID, int(req.PageSize), offset) case "total": items, total, err = s.rankingRepo.GetHotRankingTotal(starID, int(req.PageSize), offset) default: items, total, err = s.rankingRepo.GetHotRankingTotal(starID, int(req.PageSize), offset) } if err != nil { return &ranking.GetRankingResponse{ Base: &common.BaseResponse{ Code: 500, Message: "获取排行榜失败: " + err.Error(), }, }, nil } // 转换结果 rankingItems := make([]*ranking.RankingItem, len(items)) for i, item := range items { rankingItems[i] = &ranking.RankingItem{ Rank: int32(i + 1 + (int(req.Page)-1)*int(req.PageSize)), AssetId: item.AssetID, AssetName: item.AssetName, CoverUrl: item.CoverURL, OwnerUid: item.OwnerUID, OwnerNickname: item.OwnerNickname, OwnerAvatar: getStringPointer(item.OwnerAvatar), LikeCount: item.LikeCount, IsOriginal: item.IsOriginal, } } // 获取当前用户的最佳排名 var myRanking *ranking.MyRanking if req.UserId > 0 && starID > 0 { // 获取用户信息(昵称和头像) var ownerNickname, ownerAvatar string fanProfile, err := s.userClient.GetFanProfile(ctx, req.UserId, starID) if err == nil && fanProfile != nil { ownerNickname = fanProfile.Nickname ownerAvatar = fanProfile.AvatarUrl } // 获取用户最佳排名(非自制) myItem, myRank, err := s.rankingRepo.GetMyBestRanking(req.UserId, starID, req.Dimension, false) if err == nil && myItem != nil && myRank > 0 { myRanking = &ranking.MyRanking{ Rank: myRank, AssetId: myItem.AssetID, AssetName: myItem.AssetName, CoverUrl: myItem.CoverURL, LikeCount: myItem.LikeCount, Status: "ranked", OwnerNickname: ownerNickname, OwnerAvatar: ownerAvatar, } } else { // 用户没有上榜,返回默认值 myRanking = &ranking.MyRanking{ Rank: 0, AssetId: 0, AssetName: "", CoverUrl: "", LikeCount: 0, Status: "unranked", OwnerNickname: ownerNickname, OwnerAvatar: ownerAvatar, } } } return &ranking.GetRankingResponse{ Base: &common.BaseResponse{ Code: 200, Message: "ok", }, MyRanking: myRanking, Items: rankingItems, Page: req.Page, PageSize: req.PageSize, Total: int32(total), }, nil } // GetOriginalRanking 获取自制排行榜 func (s *rankingService) GetOriginalRanking(ctx context.Context, req *ranking.GetRankingRequest) (*ranking.GetRankingResponse, error) { // 参数校验 if req.Dimension == "" { req.Dimension = "total" } if req.Page <= 0 { req.Page = 1 } if req.PageSize <= 0 { req.PageSize = 10 } starID := req.StarId if starID <= 0 { // TODO: 从ctx获取当前用户的starID starID = 87 // 默认值,待从JWT获取 } offset := (int(req.Page) - 1) * int(req.PageSize) // 获取排行榜列表 var items []*repository.RankingItem var total int64 var err error switch req.Dimension { case "displaying": items, total, err = s.rankingRepo.GetOriginalRankingDisplaying(starID, int(req.PageSize), offset) case "month": items, total, err = s.rankingRepo.GetOriginalRankingMonth(starID, int(req.PageSize), offset) case "total": items, total, err = s.rankingRepo.GetOriginalRankingTotal(starID, int(req.PageSize), offset) default: items, total, err = s.rankingRepo.GetOriginalRankingTotal(starID, int(req.PageSize), offset) } if err != nil { return &ranking.GetRankingResponse{ Base: &common.BaseResponse{ Code: 500, Message: "获取自制排行榜失败: " + err.Error(), }, }, nil } // 转换结果 rankingItems := make([]*ranking.RankingItem, len(items)) for i, item := range items { rankingItems[i] = &ranking.RankingItem{ Rank: int32(i + 1 + (int(req.Page)-1)*int(req.PageSize)), AssetId: item.AssetID, AssetName: item.AssetName, CoverUrl: item.CoverURL, OwnerUid: item.OwnerUID, OwnerNickname: item.OwnerNickname, OwnerAvatar: getStringPointer(item.OwnerAvatar), LikeCount: item.LikeCount, IsOriginal: item.IsOriginal, } } // 获取当前用户的最佳排名 var myRanking *ranking.MyRanking if req.UserId > 0 && starID > 0 { // 获取用户信息(昵称和头像) var ownerNickname, ownerAvatar string fanProfile, err := s.userClient.GetFanProfile(ctx, req.UserId, starID) if err == nil && fanProfile != nil { ownerNickname = fanProfile.Nickname ownerAvatar = fanProfile.AvatarUrl } // 获取用户最佳排名(自制) myItem, myRank, err := s.rankingRepo.GetMyBestRanking(req.UserId, starID, req.Dimension, true) if err == nil && myItem != nil && myRank > 0 { myRanking = &ranking.MyRanking{ Rank: myRank, AssetId: myItem.AssetID, AssetName: myItem.AssetName, CoverUrl: myItem.CoverURL, LikeCount: myItem.LikeCount, Status: "ranked", OwnerNickname: ownerNickname, OwnerAvatar: ownerAvatar, } } else { // 用户没有上榜,返回默认值 myRanking = &ranking.MyRanking{ Rank: 0, AssetId: 0, AssetName: "", CoverUrl: "", LikeCount: 0, Status: "unranked", OwnerNickname: ownerNickname, OwnerAvatar: ownerAvatar, } } } return &ranking.GetRankingResponse{ Base: &common.BaseResponse{ Code: 200, Message: "ok", }, MyRanking: myRanking, Items: rankingItems, Page: req.Page, PageSize: req.PageSize, Total: int32(total), }, nil } // getStringPointer 返回字符串的指针 func getStringPointer(s *string) string { if s == nil { return "" } return *s }