270 lines
7.4 KiB
Go
270 lines
7.4 KiB
Go
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
|
||
}
|