topfans/backend/services/assetService/service/ranking_service.go
2026-05-16 02:42:32 +08:00

270 lines
7.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}