feat: 订阅列表和免费列表
This commit is contained in:
@@ -34,9 +34,26 @@ func (s *CategoryService) GetCategoryList(info radioReq.GetCategoryList) ([]radi
|
||||
return list, total, err
|
||||
}
|
||||
|
||||
// GetCategoryTree 返回带频道的分类树
|
||||
func (s *CategoryService) GetCategoryTree() ([]radio.RadioCategory, error) {
|
||||
var res []radio.RadioCategory
|
||||
|
||||
// 1. 查询分类并预加载关联的频道
|
||||
// Preload("Channels") 会自动根据 CategoryId 匹配
|
||||
// Preload("Icon") 和 Preload("Cover") 用于加载 OSS 信息
|
||||
err := global.DB.Model(&radio.RadioCategory{}).
|
||||
Preload("Channels", "status = ?", 1). // 只加载启用的频道
|
||||
Preload("Channels.Cover"). // 级联加载频道的封面
|
||||
Preload("Icon").
|
||||
Preload("Cover").
|
||||
Order("sort desc").
|
||||
Find(&res).Error
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (s *CategoryService) GetAllCategory() ([]radio.RadioCategory, error) {
|
||||
var res []radio.RadioCategory
|
||||
err := global.DB.Find(&res).Preload(":Icon").Preload("Cover").Error
|
||||
err := global.DB.Find(&res).Preload("Icon").Preload("Cover").Error
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ package radio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"sundynix-go/global"
|
||||
common "sundynix-go/model/commom/request"
|
||||
"sundynix-go/model/radio"
|
||||
radioReq "sundynix-go/model/radio/request"
|
||||
|
||||
@@ -12,6 +12,23 @@ import (
|
||||
|
||||
type ChannelService struct{}
|
||||
|
||||
func (s *ChannelService) GetFreeChannelList(req common.PageInfo) ([]radio.RadioChannel, int64, error) {
|
||||
db := global.DB.Model(&radio.RadioChannel{}).Where("is_free = 1")
|
||||
var list []radio.RadioChannel
|
||||
var total int64
|
||||
err := db.Count(&total).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
offset := (req.Current - 1) * req.PageSize
|
||||
err = db.Offset(offset).Limit(req.PageSize).Order("sort ASC").Find(&list).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return list, total, nil
|
||||
}
|
||||
|
||||
// GetChannelList 获取频道列表
|
||||
func (s *ChannelService) GetChannelList(userId string, info radioReq.GetChannelList) ([]radio.RadioChannel, int64, error) {
|
||||
db := global.DB.Model(&radio.RadioChannel{})
|
||||
@@ -34,33 +51,19 @@ func (s *ChannelService) GetChannelList(userId string, info radioReq.GetChannelL
|
||||
}
|
||||
|
||||
offset := (info.Current - 1) * info.PageSize
|
||||
err = db.Offset(offset).Limit(info.PageSize).Order("sort ASC").Find(&list).Error
|
||||
err = db.Offset(offset).Limit(info.PageSize).Order("is_free desc,sort ASC").Find(&list).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 批量查询用户订阅的频道,避免N+1问题
|
||||
if userId != "" {
|
||||
subService := &SubscriptionService{}
|
||||
subscribedChannelIds, _ := subService.GetUserSubscriptionHistory(userId)
|
||||
// 转换为map以便快速查找
|
||||
subscribedMap := make(map[string]bool)
|
||||
for _, cid := range subscribedChannelIds {
|
||||
subscribedMap[cid] = true
|
||||
}
|
||||
// 填充HasSubscribed字段
|
||||
for i := range list {
|
||||
if subscribedMap[list[i].Id] {
|
||||
list[i].HasSubscribed = 1
|
||||
} else {
|
||||
list[i].HasSubscribed = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list, total, nil
|
||||
}
|
||||
|
||||
func (s *ChannelService) GetAllChannelList(categoryId, userId string) ([]radio.RadioChannel, error) {
|
||||
var res []radio.RadioChannel
|
||||
err := global.DB.Where("category_id = ?", categoryId).Find(&res).Preload("Cover").Error
|
||||
return res, err
|
||||
}
|
||||
|
||||
// GetChannelById 获取频道详情
|
||||
func (s *ChannelService) GetChannelById(userId, id string) (radio.RadioChannel, error) {
|
||||
var channel radio.RadioChannel
|
||||
@@ -68,32 +71,23 @@ func (s *ChannelService) GetChannelById(userId, id string) (radio.RadioChannel,
|
||||
if err != nil {
|
||||
return channel, err
|
||||
}
|
||||
|
||||
// 填充HasSubscribed字段
|
||||
if userId != "" {
|
||||
subService := &SubscriptionService{}
|
||||
hasSub, _ := subService.HasSubscription(userId, channel.Id)
|
||||
if hasSub {
|
||||
channel.HasSubscribed = 1
|
||||
} else {
|
||||
channel.HasSubscribed = 0
|
||||
}
|
||||
}
|
||||
|
||||
return channel, nil
|
||||
}
|
||||
|
||||
// SaveChannel 保存频道
|
||||
func (s *ChannelService) SaveChannel(req radioReq.SaveChannel) error {
|
||||
channel := radio.RadioChannel{
|
||||
CategoryId: req.CategoryId,
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
CoverId: req.CoverId,
|
||||
Tags: req.Tags,
|
||||
IsVipOnly: req.IsVipOnly,
|
||||
Sort: req.Sort,
|
||||
Status: req.Status,
|
||||
CategoryId: req.CategoryId,
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
CoverId: req.CoverId,
|
||||
Tags: req.Tags,
|
||||
IsVipOnly: req.IsVipOnly,
|
||||
MonthlyPrice: req.MonthlyPrice,
|
||||
QuarterlyPrice: req.QuarterlyPrice,
|
||||
AnnualPrice: req.AnnualPrice,
|
||||
Sort: req.Sort,
|
||||
Status: req.Status,
|
||||
}
|
||||
return global.DB.Create(&channel).Error
|
||||
}
|
||||
@@ -101,14 +95,17 @@ func (s *ChannelService) SaveChannel(req radioReq.SaveChannel) error {
|
||||
// UpdateChannel 更新频道
|
||||
func (s *ChannelService) UpdateChannel(req radioReq.UpdateChannel) error {
|
||||
updates := map[string]interface{}{
|
||||
"category_id": req.CategoryId,
|
||||
"name": req.Name,
|
||||
"description": req.Description,
|
||||
"cover_id": req.CoverId,
|
||||
"tags": req.Tags,
|
||||
"is_vip_only": req.IsVipOnly,
|
||||
"sort": req.Sort,
|
||||
"status": req.Status,
|
||||
"category_id": req.CategoryId,
|
||||
"name": req.Name,
|
||||
"description": req.Description,
|
||||
"cover_id": req.CoverId,
|
||||
"tags": req.Tags,
|
||||
"is_vip_only": req.IsVipOnly,
|
||||
"monthly_price": req.MonthlyPrice,
|
||||
"quarterly_price": req.QuarterlyPrice,
|
||||
"annual_price": req.AnnualPrice,
|
||||
"sort": req.Sort,
|
||||
"status": req.Status,
|
||||
}
|
||||
return global.DB.Model(&radio.RadioChannel{}).Where("id = ?", req.Id).Updates(updates).Error
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func (s *InteractionService) AddHistory(userId string, req radioReq.AddHistory)
|
||||
|
||||
// GetHistoryList 获取收听历史列表
|
||||
func (s *InteractionService) GetHistoryList(userId string, info radioReq.GetHistoryList) ([]radio.RadioHistory, int64, error) {
|
||||
db := global.DB.Model(&radio.RadioHistory{}).Where("user_id = ?", userId)
|
||||
db := global.DB.Model(&radio.RadioHistory{}).Where("user_id = ?", userId).Preload("RadioProgram")
|
||||
var list []radio.RadioHistory
|
||||
var total int64
|
||||
|
||||
|
||||
@@ -16,18 +16,44 @@ const MaxFreeSubscription = 2
|
||||
|
||||
// GetUserSubscription 获取用户订阅列表
|
||||
func (s *SubscriptionService) GetUserSubscription(userId string, info common.PageInfo) ([]radio.RadioSubscription, int64, error) {
|
||||
db := global.DB.Model(&radio.RadioSubscription{}).Where("user_id = ?", userId)
|
||||
var list []radio.RadioSubscription
|
||||
var subscriptions []radio.RadioSubscription
|
||||
var total int64
|
||||
|
||||
err := db.Count(&total).Error
|
||||
db := global.DB // 替换为你实际的 GORM 变量
|
||||
// 2. 统计该用户订阅的总数 (Status=1 表示订阅中)
|
||||
err := db.Model(&radio.RadioSubscription{}).
|
||||
Where("user_id = ? AND status = 1", userId).
|
||||
Count(&total).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
// 3. 执行分页关联查询
|
||||
err = db.Model(&radio.RadioSubscription{}).
|
||||
Where("user_id = ? AND status = 1", userId).
|
||||
Limit(info.PageSize).
|
||||
Offset((info.Current-1)*info.PageSize).
|
||||
Order("created_at DESC").
|
||||
// 级联加载频道及其封面
|
||||
Preload("Channel").
|
||||
Preload("Channel.Cover").
|
||||
// 关键:子查询过滤——只预加载每个频道 ID 最大的那一条节目
|
||||
Preload("Channel.Programs", func(db *gorm.DB) *gorm.DB {
|
||||
// 子查询:找到每个频道下 ID 最大的节目(通常 ID 越大代表越新,也可以用 CreatedAt)
|
||||
subQuery := db.Table("sundynix_radio_program").
|
||||
Select("id").
|
||||
Where("status = 1"). // 只找上架的
|
||||
Where("created_at = (SELECT MAX(created_at) FROM sundynix_radio_program AS rp WHERE rp.channel_id = sundynix_radio_program.channel_id AND rp.status = 1)")
|
||||
|
||||
offset := (info.Current - 1) * info.PageSize
|
||||
err = db.Offset(offset).Limit(info.PageSize).Order("created_at DESC").Find(&list).Error
|
||||
return list, total, err
|
||||
// 嵌套预加载:节目里的音频和封面也一并带出来
|
||||
return db.Where("id IN (?)", subQuery).
|
||||
Preload("Cover").
|
||||
Preload("Audio")
|
||||
}).
|
||||
Find(&subscriptions).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, total, err
|
||||
}
|
||||
return subscriptions, total, err
|
||||
}
|
||||
|
||||
// GetUserSubscriptionHistory 获取用户历史订阅过的频道ID列表
|
||||
|
||||
Reference in New Issue
Block a user