package radio import ( "errors" "sundynix-go/global" common "sundynix-go/model/commom/request" "sundynix-go/model/radio" radioReq "sundynix-go/model/radio/request" "time" "go.uber.org/zap" "gorm.io/gorm" ) type ChannelService struct{} func (s *ChannelService) GetFreeChannelList(req common.PageInfo) ([]radio.RadioChannel, int64, error) { db := global.DB.Model(&radio.RadioChannel{}).Where("is_free = 1").Where("status = ?", 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{}).Where("status = ?", 1) var list []radio.RadioChannel var total int64 if info.CategoryId != "" { db = db.Where("category_id = ?", info.CategoryId) } if info.Name != "" { db = db.Where("name LIKE ?", "%"+info.Name+"%") } if info.Status > 0 { db = db.Where("status = ?", info.Status) } err := db.Count(&total).Error if err != nil { return nil, 0, err } offset := (info.Current - 1) * info.PageSize err = db.Offset(offset).Limit(info.PageSize).Order("is_free desc,sort ASC").Find(&list).Error if err != nil { return nil, 0, err } //查询用户的订阅频道 now := time.Now() var subIds []string err = global.DB.Model(&radio.RadioSubscription{}). Where("user_id = ?", userId). Where("status = ?", 1). // 建议将常量也参数化,提高安全性 Where("expired_at > ?", now). Pluck("channel_id", &subIds). Error // 使用map subMap := make(map[string]bool) for _, id := range subIds { subMap[id] = true } for i := range list { list[i].HasSubscribed = 0 if subMap[list[i].Id] { list[i].HasSubscribed = 1 } } return list, total, nil } // GetChannelById 获取频道详情 func (s *ChannelService) GetChannelById(userId, id string) (radio.RadioChannel, error) { var channel radio.RadioChannel err := global.DB.Where("id = ?", id).First(&channel).Error if err != nil { return channel, err } if channel.IsFree == 1 { return channel, nil } channel.HasSubscribed = 0 if userId != "" && userId != "0" { var sub radio.RadioSubscription err = global.DB.Model(&radio.RadioSubscription{}). Where("user_id = ?", userId). Where("channel_id = ?", id). Where("status = ?", 1). Where("expired_at > ?", time.Now()). First(&sub).Error if err != nil { // 记录日志但不返回错误,避免影响主流程 global.Logger.Warn("query subscription status failed", zap.Error(err)) return channel, nil } channel.HasSubscribed = 1 channel.ExpiredAt = &sub.ExpiredAt } return channel, nil } // SaveChannel 保存频道 func (s *ChannelService) SaveChannel(req radioReq.SaveChannel) error { channel := radio.RadioChannel{ CategoryId: req.CategoryId, Name: req.Name, Description: req.Description, Cover: req.Cover, 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 } // UpdateChannel 更新频道 func (s *ChannelService) UpdateChannel(req radioReq.UpdateChannel) error { updates := map[string]interface{}{ "category_id": req.CategoryId, "name": req.Name, "description": req.Description, "cover": req.Cover, "tags": req.Tags, "is_free": req.IsFree, "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 } // DeleteChannel 删除频道 func (s *ChannelService) DeleteChannel(id string) error { return global.DB.Transaction(func(tx *gorm.DB) error { // 检查是否有节目使用此频道 var count int64 tx.Model(&radio.RadioProgram{}).Where("channel_id = ?", id).Count(&count) if count > 0 { return errors.New("该频道下存在节目,无法删除") } return tx.Where("id = ?", id).Delete(&radio.RadioChannel{}).Error }) }