Initial commit: web_hghl_server
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
package configser
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"sync"
|
||||
"videoweb/app/api/proto"
|
||||
"videoweb/pub/common/log"
|
||||
"videoweb/pub/models/actress"
|
||||
"videoweb/pub/models/contenttagmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type TopicCache struct {
|
||||
Lock sync.RWMutex // 读写锁
|
||||
|
||||
ActressWorks []proto.ActressInfoData
|
||||
ActressModelMaps map[int64]*actress.Actress
|
||||
|
||||
AllTagMaps map[int64]proto.TagsInfoData
|
||||
VideoTagMaps map[int64]proto.TagsInfoData
|
||||
|
||||
// 首页展示的标签,按当前类型绑定数量降序
|
||||
HomeVideoTagList []proto.TagsInfoData
|
||||
HomePlayletTagList []proto.TagsInfoData
|
||||
}
|
||||
|
||||
var TopicMgr TopicCache
|
||||
|
||||
func StartTopicCache() {
|
||||
TopicMgr = TopicCache{}
|
||||
TopicMgr.Lock = sync.RWMutex{}
|
||||
TopicMgr.ActressWorks = make([]proto.ActressInfoData, 0)
|
||||
TopicMgr.ActressModelMaps = make(map[int64]*actress.Actress)
|
||||
TopicMgr.HomeVideoTagList = make([]proto.TagsInfoData, 0)
|
||||
TopicMgr.HomePlayletTagList = make([]proto.TagsInfoData, 0)
|
||||
TopicMgr.AllTagMaps = make(map[int64]proto.TagsInfoData)
|
||||
TopicMgr.VideoTagMaps = make(map[int64]proto.TagsInfoData)
|
||||
|
||||
updateTagCache()
|
||||
updateCreateCache(context.Background())
|
||||
updateCategoryCache()
|
||||
_, _ = skdCron.AddFunc("0 */5 * * * ?", func() {
|
||||
updateTagCache()
|
||||
updateCreateCache(context.Background())
|
||||
updateCategoryCache()
|
||||
})
|
||||
}
|
||||
func updateTagCache() {
|
||||
updateContentTagCache()
|
||||
}
|
||||
func updateCategoryCache() {
|
||||
updateActressCache()
|
||||
}
|
||||
|
||||
func updateActressCache() {
|
||||
ctx := context.Background()
|
||||
filter := bson.M{actress.FN.Actress.Status: true}
|
||||
config := GetConfigInfo()
|
||||
otps := &options.FindOptions{}
|
||||
otps.SetSort(bson.D{
|
||||
{Key: actress.FN.Actress.HotValue, Value: -1},
|
||||
{Key: actress.FN.Actress.Id, Value: -1},
|
||||
})
|
||||
list, err := actress.FindManyActresss(ctx, filter, otps)
|
||||
if err != nil {
|
||||
log.Warn("updateActressCache", log.E(err))
|
||||
return
|
||||
}
|
||||
tempWorks := make([]proto.ActressInfoData, len(list))
|
||||
tempModel := make(map[int64]*actress.Actress)
|
||||
for i := 0; i < len(list); i++ {
|
||||
info := proto.ActressInfoToData(*list[i], config.ImgCdn)
|
||||
tempWorks[i] = info
|
||||
tempModel[info.Id] = list[i]
|
||||
}
|
||||
sort.SliceStable(tempWorks, func(i, j int) bool {
|
||||
if tempWorks[i].HotValue == tempWorks[j].HotValue {
|
||||
return tempWorks[i].Id > tempWorks[j].Id
|
||||
}
|
||||
return tempWorks[i].HotValue > tempWorks[j].HotValue
|
||||
})
|
||||
TopicMgr.Lock.Lock()
|
||||
defer TopicMgr.Lock.Unlock()
|
||||
TopicMgr.ActressWorks = tempWorks
|
||||
TopicMgr.ActressModelMaps = tempModel
|
||||
}
|
||||
|
||||
func GetActressInfo(actressId int64) *actress.Actress {
|
||||
TopicMgr.Lock.RLock()
|
||||
defer TopicMgr.Lock.RUnlock()
|
||||
v, ok := TopicMgr.ActressModelMaps[actressId]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return v
|
||||
}
|
||||
func updateContentTagCache() {
|
||||
ctx := context.Background()
|
||||
filter := bson.M{
|
||||
contenttagmod.FN.ContentTag.Status: true,
|
||||
"$or": []bson.M{
|
||||
{contenttagmod.FN.ContentTag.VideoCount: bson.M{"$gt": 0}},
|
||||
{contenttagmod.FN.ContentTag.PlayletCount: bson.M{"$gt": 0}},
|
||||
},
|
||||
}
|
||||
list, err := contenttagmod.FindManyContentTag(ctx, filter, options.Find().
|
||||
SetSort(bson.D{
|
||||
{Key: contenttagmod.FN.ContentTag.Rank, Value: -1},
|
||||
{Key: contenttagmod.FN.ContentTag.Id, Value: -1},
|
||||
}).
|
||||
SetProjection(bson.M{
|
||||
contenttagmod.FN.ContentTag.Id: 1,
|
||||
contenttagmod.FN.ContentTag.Name: 1,
|
||||
contenttagmod.FN.ContentTag.Slug: 1,
|
||||
contenttagmod.FN.ContentTag.Types: 1,
|
||||
contenttagmod.FN.ContentTag.Rank: 1,
|
||||
contenttagmod.FN.ContentTag.VideoCount: 1,
|
||||
contenttagmod.FN.ContentTag.PlayletCount: 1,
|
||||
"seoInfo": 1,
|
||||
}))
|
||||
if err != nil {
|
||||
log.Warn("updateContentTagCache", log.E(err))
|
||||
return
|
||||
}
|
||||
allMaps := make(map[int64]proto.TagsInfoData, len(list))
|
||||
videoMaps := make(map[int64]proto.TagsInfoData)
|
||||
videoHomeList := make([]proto.TagsInfoData, 0)
|
||||
playletHomeList := make([]proto.TagsInfoData, 0)
|
||||
for _, item := range list {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
for _, tagType := range item.Types {
|
||||
info := contentTagInfoByType(item, tagType)
|
||||
allMaps[item.Id] = info
|
||||
switch tagType {
|
||||
case contenttagmod.ContentTagTypeVideo:
|
||||
videoMaps[item.Id] = info
|
||||
if info.Works > 0 {
|
||||
videoHomeList = append(videoHomeList, info)
|
||||
}
|
||||
case contenttagmod.ContentTagTypePlaylet:
|
||||
if info.Works > 0 {
|
||||
playletHomeList = append(playletHomeList, info)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sortHomeContentTagList(videoHomeList)
|
||||
sortHomeContentTagList(playletHomeList)
|
||||
TopicMgr.Lock.Lock()
|
||||
defer TopicMgr.Lock.Unlock()
|
||||
TopicMgr.AllTagMaps = allMaps
|
||||
TopicMgr.VideoTagMaps = videoMaps
|
||||
TopicMgr.HomeVideoTagList = videoHomeList
|
||||
TopicMgr.HomePlayletTagList = playletHomeList
|
||||
}
|
||||
|
||||
func contentTagInfoByType(item *contenttagmod.ContentTag, tagType contenttagmod.ContentTagType) proto.TagsInfoData {
|
||||
return proto.TagsInfoData{
|
||||
Id: item.Id,
|
||||
Name: item.Name,
|
||||
Slug: item.Slug,
|
||||
SeoInfo: item.SeoInfo,
|
||||
Works: contentTagWorksByType(item, tagType),
|
||||
}
|
||||
}
|
||||
|
||||
func contentTagWorksByType(item *contenttagmod.ContentTag, tagType contenttagmod.ContentTagType) int64 {
|
||||
switch tagType {
|
||||
case contenttagmod.ContentTagTypeVideo:
|
||||
return item.VideoCount
|
||||
case contenttagmod.ContentTagTypePlaylet:
|
||||
return item.PlayletCount
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func sortHomeContentTagList(list []proto.TagsInfoData) {
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
if list[i].Works == list[j].Works {
|
||||
return list[i].Id > list[j].Id
|
||||
}
|
||||
return list[i].Works > list[j].Works
|
||||
})
|
||||
}
|
||||
|
||||
func GetActressWorks() []proto.ActressInfoData {
|
||||
TopicMgr.Lock.RLock()
|
||||
defer TopicMgr.Lock.RUnlock()
|
||||
return TopicMgr.ActressWorks
|
||||
}
|
||||
|
||||
func GetVideoTag(tagId int64) *proto.TagsInfoData {
|
||||
TopicMgr.Lock.RLock()
|
||||
defer TopicMgr.Lock.RUnlock()
|
||||
tag, ok := TopicMgr.VideoTagMaps[tagId]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return &tag
|
||||
}
|
||||
|
||||
// VideoTagNamesAndSlugs 按视频标签ID顺序返回名称和slug
|
||||
func VideoTagNamesAndSlugs(tagIDs []int64) ([]string, []string) {
|
||||
names := make([]string, 0, len(tagIDs))
|
||||
slugs := make([]string, 0, len(tagIDs))
|
||||
TopicMgr.Lock.RLock()
|
||||
defer TopicMgr.Lock.RUnlock()
|
||||
for _, id := range tagIDs {
|
||||
if tag, ok := TopicMgr.VideoTagMaps[id]; ok {
|
||||
names = append(names, tag.Name)
|
||||
slugs = append(slugs, tag.Slug)
|
||||
}
|
||||
}
|
||||
return names, slugs
|
||||
}
|
||||
|
||||
func GetHomeVideoTagList() []proto.TagsInfoData {
|
||||
TopicMgr.Lock.RLock()
|
||||
defer TopicMgr.Lock.RUnlock()
|
||||
return TopicMgr.HomeVideoTagList
|
||||
}
|
||||
|
||||
func GetHomePlayletTagList() []proto.TagsInfoData {
|
||||
TopicMgr.Lock.RLock()
|
||||
defer TopicMgr.Lock.RUnlock()
|
||||
return TopicMgr.HomePlayletTagList
|
||||
}
|
||||
Reference in New Issue
Block a user