Files
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

245 lines
7.7 KiB
Go

package mediaser
import (
"91porn-server/app/appg"
"91porn-server/app/service/mediatagser"
"91porn-server/common"
"91porn-server/common/constant/redisconst"
"91porn-server/common/timeutil/timerange"
"91porn-server/models/s/statrecordmod"
"91porn-server/models/v/mediamod"
"91porn-server/models/v/mediatagmod"
"91porn-server/models/v/usermod"
"strings"
"sync"
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
func buildDedupTagsAndDetails(tagIDs []primitive.ObjectID, tagMap map[primitive.ObjectID]*mediatagmod.MediaTag) ([]primitive.ObjectID, []mediamod.TagDetail) {
if len(tagIDs) == 0 {
return nil, nil
}
seen := make(map[string]struct{}, len(tagIDs))
uniqueTagIDs := make([]primitive.ObjectID, 0, len(tagIDs))
tagDetails := make([]mediamod.TagDetail, 0, len(tagIDs))
for _, id := range tagIDs {
tag, ok := tagMap[id]
if !ok {
continue
}
name := strings.TrimSpace(tag.Name)
if _, exists := seen[name]; exists {
continue
}
seen[name] = struct{}{}
uniqueTagIDs = append(uniqueTagIDs, tag.ID)
tagDetails = append(tagDetails, mediamod.TagDetail{
Id: tag.ID,
Name: tag.Name,
})
}
return uniqueTagIDs, tagDetails
}
func FillMedias(medias []*mediamod.Media, uid uint64, needDefaultContent bool, dramaCard ...bool) []*mediamod.AppMediaBase {
if len(medias) == 0 {
return nil
}
tagIDs := make([]primitive.ObjectID, 0)
var (
mIds []primitive.ObjectID
mStatus map[primitive.ObjectID]mediamod.MediaStatus
hasDrama bool
hasDramaCard bool
)
for i := range medias {
if medias[i] == nil {
continue
}
mIds = append(mIds, medias[i].ID)
tagIDs = append(tagIDs, medias[i].Tags...)
if medias[i].MediaType == mediamod.MediaTypeDrama {
hasDrama = true
}
}
var wg sync.WaitGroup
wg.Add(1)
common.Go(func() {
defer wg.Done()
mStatus = GetUserStatus(uid, mIds)
})
if hasDrama {
if len(dramaCard) > 0 {
hasDramaCard = dramaCard[0]
} else {
wg.Add(1)
common.Go(func() {
defer wg.Done()
user, err := usermod.FindUserByUID(uid)
hasDramaCard = err == nil && user != nil && user.DramaExpire.After(time.Now())
})
}
}
wg.Wait()
var infos []*mediamod.AppMediaBase
tagMap := mediatagser.GetTagsByIDs2Map(tagIDs)
for i := range medias {
if medias[i] == nil {
continue
}
mid := ""
if !medias[i].MID.IsZero() {
mid = medias[i].MID.Hex()
}
temp := mediamod.AppMediaBase{
ID: medias[i].ID,
SortCode: medias[i].SortCode,
Status: medias[i].Status,
Title: medias[i].Title,
HorizontalCover: medias[i].HorizontalCover,
VerticalCover: medias[i].VerticalCover,
Tags: make([]primitive.ObjectID, 0),
TagDetails: make([]mediamod.TagDetail, 0),
Summary: medias[i].Summary,
TotalEpisode: medias[i].TotalEpisode,
CurrentEpisode: medias[i].CurrentEpisode,
FreeEpisode: medias[i].FreeEpisode,
MediaType: medias[i].MediaType,
MediaSubType: medias[i].MediaSubType,
Kind: medias[i].Kind,
Price: medias[i].Price,
ContentsPrice: medias[i].ContentsPrice,
Direction: medias[i].Direction,
UpdateStatus: medias[i].UpdateStatus,
Permission: medias[i].Permission,
PermissionIconHide: medias[i].PermissionIconHide,
Style: medias[i].Style,
FreeTime: medias[i].FreeTime,
CountPurchases: medias[i].CountPurchases,
CountBrowse: medias[i].CountBrowse,
CountCollect: medias[i].CountCollect,
CountLike: medias[i].CountLike,
CountDisLike: medias[i].CountDisLike,
CountView: medias[i].CountView,
CountShare: medias[i].CountShare,
HasFollow: medias[i].HasFollow,
MediaStatus: mStatus[medias[i].ID],
CountComment: medias[i].CountComment,
Number: medias[i].Number,
CreatedAt: medias[i].CreatedAt,
UpdateTime: medias[i].UpdateTime,
LatestPublishedAt: medias[i].LatestPublishedAt,
MID: mid,
ModuleName: medias[i].ModuleName,
SectionName: medias[i].SectionName,
SID: medias[i].SID,
SectionSort: medias[i].SectionSort,
LsjId: medias[i].LsjId,
}
if medias[i].MediaType == mediamod.MediaTypeDrama {
temp.HasDramaCard = hasDramaCard
}
if temp.MediaStatus.HasCollected {
temp.CountCollect = temp.CountCollect + 1 // 避免缓存详情的情况,收藏完成之后数字没有任何变化
}
if needDefaultContent {
temp.DefaultContent = medias[i].DefaultContent
}
if temp.DefaultContent.Cover == "" && len(temp.DefaultContent.UrlSet) > 0 {
temp.DefaultContent.Cover = temp.DefaultContent.UrlSet[0]
}
if strings.TrimSpace(temp.DefaultContent.Name) == "" {
temp.DefaultContent.Name = "第一集"
}
temp.Tags, temp.TagDetails = buildDedupTagsAndDetails(medias[i].Tags, tagMap)
infos = append(infos, &temp)
}
return infos
}
func FillNotStatusMedias(medias []*mediamod.Media, needDefaultContent bool) []*mediamod.AppMediaBase {
if len(medias) == 0 {
return []*mediamod.AppMediaBase{}
}
tagIDs := make([]primitive.ObjectID, 0)
var (
mIds []primitive.ObjectID
)
for i := range medias {
mIds = append(mIds, medias[i].ID)
if medias[i] != nil {
tagIDs = append(tagIDs, medias[i].Tags...)
}
}
infos := []*mediamod.AppMediaBase{}
tagMap := mediatagser.GetTagsByIDs2Map(tagIDs)
for i := range medias {
if medias[i] == nil {
continue
}
temp := mediamod.AppMediaBase{
ID: medias[i].ID,
Title: medias[i].Title,
HorizontalCover: medias[i].HorizontalCover,
VerticalCover: medias[i].VerticalCover,
Tags: make([]primitive.ObjectID, 0),
TagDetails: make([]mediamod.TagDetail, 0),
Summary: medias[i].Summary,
TotalEpisode: medias[i].TotalEpisode,
CurrentEpisode: medias[i].CurrentEpisode,
FreeEpisode: medias[i].FreeEpisode,
MediaType: medias[i].MediaType,
MediaSubType: medias[i].MediaSubType,
Kind: medias[i].Kind,
Price: medias[i].Price,
ContentsPrice: medias[i].ContentsPrice,
Direction: medias[i].Direction,
UpdateStatus: medias[i].UpdateStatus,
Permission: medias[i].Permission,
CountPurchases: medias[i].CountPurchases,
CountBrowse: medias[i].CountBrowse,
CountCollect: medias[i].CountCollect,
CountLike: medias[i].CountLike,
HasFollow: medias[i].HasFollow,
CountComment: medias[i].CountComment,
Number: medias[i].Number,
CreatedAt: medias[i].CreatedAt,
UpdateTime: medias[i].UpdateTime,
LatestPublishedAt: medias[i].LatestPublishedAt,
}
if temp.MediaStatus.HasCollected {
temp.CountCollect = temp.CountCollect + 1 // 避免缓存详情的情况,收藏完成之后数字没有任何变化
}
if needDefaultContent {
temp.DefaultContent = medias[i].DefaultContent
}
if temp.DefaultContent.Cover == "" && len(temp.DefaultContent.UrlSet) > 0 {
temp.DefaultContent.Cover = temp.DefaultContent.UrlSet[0]
}
if strings.TrimSpace(temp.DefaultContent.Name) == "" {
temp.DefaultContent.Name = "第一集"
}
temp.Tags, temp.TagDetails = buildDedupTagsAndDetails(medias[i].Tags, tagMap)
infos = append(infos, &temp)
}
return infos
}
// IncrCountBrowse 增加播放量
func IncrCountBrowse(mediaId primitive.ObjectID) {
now := time.Now()
recentMinute := timerange.RecentMinute(now, statrecordmod.FiveMinuteScale)
key := redisconst.AcgBrowseCountListKey(recentMinute.Unix())
if err := appg.Redis.RPush(key, mediaId.Hex()); err != nil {
return
}
_, _ = appg.Redis.ExpireKey(key, time.Minute*20)
}