Initial commit: web_hghl_server

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 16:28:14 +08:00
co-authored by Claude Opus 4.7
commit 65fca60622
653 changed files with 135901 additions and 0 deletions
+233
View File
@@ -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
}