Initial commit
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,575 @@
|
||||
package playletcache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"videoweb/pub/common/log"
|
||||
"videoweb/pub/models/hotsearchmod"
|
||||
"videoweb/pub/models/playletcategorymod"
|
||||
"videoweb/pub/models/playletmod"
|
||||
"videoweb/pub/models/playlettagmod"
|
||||
"videoweb/pub/models/playletthememod"
|
||||
"videoweb/pub/pubdef"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var (
|
||||
skdCron *cron.Cron
|
||||
cache struct {
|
||||
lock sync.RWMutex
|
||||
themeByID map[int64]*ThemeItem
|
||||
themeBySlug map[string]*ThemeItem
|
||||
tagByID map[int64]*TagItem
|
||||
tagBySlug map[string]*TagItem
|
||||
categoryByID map[int64]*CategoryItem
|
||||
categoryBySlug map[string]*CategoryItem
|
||||
hotSearch []HotSearchItem
|
||||
guessLike []*playletmod.Playlet
|
||||
}
|
||||
)
|
||||
|
||||
// HotSearchItem 热搜词缓存项
|
||||
type HotSearchItem struct {
|
||||
Keyword string
|
||||
Count int64
|
||||
}
|
||||
|
||||
// ThemeItem 题材缓存项(含 SEO)
|
||||
type ThemeItem struct {
|
||||
Id int64
|
||||
Name string
|
||||
Slug string
|
||||
Icon string
|
||||
Rank int64
|
||||
Status bool
|
||||
IsRecommend bool
|
||||
PlayletCount int64
|
||||
SeoInfo pubdef.SeoValue
|
||||
}
|
||||
|
||||
// TagItem 标签缓存项(含 SEO)
|
||||
type TagItem struct {
|
||||
Id int64
|
||||
Name string
|
||||
Slug string
|
||||
Rank int64
|
||||
Status bool
|
||||
SeoInfo pubdef.SeoValue
|
||||
}
|
||||
|
||||
// CategoryItem 分类缓存项(含 SEO)
|
||||
type CategoryItem struct {
|
||||
Id int64
|
||||
Name string
|
||||
Slug string
|
||||
Desc string
|
||||
Icon string
|
||||
Rank int64
|
||||
Status bool
|
||||
SeoInfo pubdef.SeoValue
|
||||
}
|
||||
|
||||
// Start 启动题材/标签/分类/热搜词/猜你喜欢缓存,每 10 分钟刷新一次。
|
||||
func Start() {
|
||||
skdCron = cron.New(cron.WithSeconds())
|
||||
UpdateCache(context.Background())
|
||||
_, _ = skdCron.AddFunc("0 */10 * * * ?", func() {
|
||||
UpdateCache(context.Background())
|
||||
})
|
||||
skdCron.Start()
|
||||
}
|
||||
|
||||
// UpdateCache 从 Mongo 全量刷新题材、标签、分类、热搜词和猜你喜欢缓存。
|
||||
func UpdateCache(ctx context.Context) {
|
||||
updateThemeCache(ctx)
|
||||
updateTagCache(ctx)
|
||||
updateCategoryCache(ctx)
|
||||
updateHotSearchCache(ctx)
|
||||
updateGuessLikeCache(ctx)
|
||||
}
|
||||
|
||||
func updateThemeCache(ctx context.Context) {
|
||||
list, err := playletthememod.FindManyPlayletTheme(ctx, bson.M{}, options.Find().
|
||||
SetProjection(bson.D{
|
||||
{Key: playletthememod.FN.PlayletTheme.Id, Value: 1},
|
||||
{Key: playletthememod.FN.PlayletTheme.Name, Value: 1},
|
||||
{Key: playletthememod.FN.PlayletTheme.Slug, Value: 1},
|
||||
{Key: playletthememod.FN.PlayletTheme.Icon, Value: 1},
|
||||
{Key: playletthememod.FN.PlayletTheme.Rank, Value: 1},
|
||||
{Key: playletthememod.FN.PlayletTheme.Status, Value: 1},
|
||||
{Key: playletthememod.FN.PlayletTheme.IsRecommend, Value: 1},
|
||||
{Key: "seoInfo", Value: 1},
|
||||
}).
|
||||
SetSort(bson.D{
|
||||
{Key: playletthememod.FN.PlayletTheme.Rank, Value: -1},
|
||||
{Key: playletthememod.FN.PlayletTheme.Id, Value: -1},
|
||||
}))
|
||||
if err != nil {
|
||||
log.Warn("playletcache.updateThemeCache failed", log.E(err))
|
||||
return
|
||||
}
|
||||
countMap := countUpPlayletsByTheme(ctx)
|
||||
temp := make(map[int64]*ThemeItem, len(list))
|
||||
tempBySlug := make(map[string]*ThemeItem, len(list))
|
||||
for _, item := range list {
|
||||
if item == nil || item.Id <= 0 {
|
||||
continue
|
||||
}
|
||||
cached := &ThemeItem{
|
||||
Id: item.Id,
|
||||
Name: item.Name,
|
||||
Slug: item.Slug,
|
||||
Icon: item.Icon,
|
||||
Rank: item.Rank,
|
||||
Status: item.Status,
|
||||
IsRecommend: item.IsRecommend,
|
||||
PlayletCount: countMap[item.Id],
|
||||
SeoInfo: item.SeoInfo,
|
||||
}
|
||||
temp[item.Id] = cached
|
||||
if slug := strings.TrimSpace(item.Slug); slug != "" {
|
||||
tempBySlug[slug] = cached
|
||||
}
|
||||
}
|
||||
cache.lock.Lock()
|
||||
cache.themeByID = temp
|
||||
cache.themeBySlug = tempBySlug
|
||||
cache.lock.Unlock()
|
||||
}
|
||||
|
||||
type themePlayletCount struct {
|
||||
Id int64 `bson:"_id"`
|
||||
Count int64 `bson:"count"`
|
||||
}
|
||||
|
||||
// countUpPlayletsByTheme 按题材统计已上架短剧数量。
|
||||
func countUpPlayletsByTheme(ctx context.Context) map[int64]int64 {
|
||||
result := make(map[int64]int64)
|
||||
list := make([]themePlayletCount, 0)
|
||||
err := playletmod.AggregatePlaylet(ctx, &list, []bson.M{
|
||||
{
|
||||
"$match": bson.M{
|
||||
playletmod.FN.Playlet.Status: playletmod.StatusUp,
|
||||
},
|
||||
},
|
||||
{
|
||||
"$unwind": "$" + playletmod.FN.Playlet.ThemeIds,
|
||||
},
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": "$" + playletmod.FN.Playlet.ThemeIds,
|
||||
"count": bson.M{"$sum": 1},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Warn("playletcache.countUpPlayletsByTheme failed", log.E(err))
|
||||
return result
|
||||
}
|
||||
for _, item := range list {
|
||||
if item.Id <= 0 || item.Count <= 0 {
|
||||
continue
|
||||
}
|
||||
result[item.Id] = item.Count
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func updateTagCache(ctx context.Context) {
|
||||
list, err := playlettagmod.FindManyPlayletTag(ctx, bson.M{}, options.Find().
|
||||
SetProjection(bson.D{
|
||||
{Key: playlettagmod.FN.PlayletTag.Id, Value: 1},
|
||||
{Key: playlettagmod.FN.PlayletTag.Name, Value: 1},
|
||||
{Key: playlettagmod.FN.PlayletTag.Slug, Value: 1},
|
||||
{Key: playlettagmod.FN.PlayletTag.Rank, Value: 1},
|
||||
{Key: playlettagmod.FN.PlayletTag.Status, Value: 1},
|
||||
{Key: "seoInfo", Value: 1},
|
||||
}).
|
||||
SetSort(bson.D{
|
||||
{Key: playlettagmod.FN.PlayletTag.Rank, Value: -1},
|
||||
{Key: playlettagmod.FN.PlayletTag.Id, Value: -1},
|
||||
}))
|
||||
if err != nil {
|
||||
log.Warn("playletcache.updateTagCache failed", log.E(err))
|
||||
return
|
||||
}
|
||||
temp := make(map[int64]*TagItem, len(list))
|
||||
tempBySlug := make(map[string]*TagItem, len(list))
|
||||
for _, item := range list {
|
||||
if item == nil || item.Id <= 0 {
|
||||
continue
|
||||
}
|
||||
cached := &TagItem{
|
||||
Id: item.Id,
|
||||
Name: item.Name,
|
||||
Slug: item.Slug,
|
||||
Rank: item.Rank,
|
||||
Status: item.Status,
|
||||
SeoInfo: item.SeoInfo,
|
||||
}
|
||||
temp[item.Id] = cached
|
||||
if slug := strings.TrimSpace(item.Slug); slug != "" {
|
||||
tempBySlug[slug] = cached
|
||||
}
|
||||
}
|
||||
cache.lock.Lock()
|
||||
cache.tagByID = temp
|
||||
cache.tagBySlug = tempBySlug
|
||||
cache.lock.Unlock()
|
||||
}
|
||||
|
||||
func updateCategoryCache(ctx context.Context) {
|
||||
list, err := playletcategorymod.FindManyPlayletCategory(ctx, bson.M{}, options.Find().
|
||||
SetProjection(bson.D{
|
||||
{Key: playletcategorymod.FN.PlayletCategory.Id, Value: 1},
|
||||
{Key: playletcategorymod.FN.PlayletCategory.Name, Value: 1},
|
||||
{Key: playletcategorymod.FN.PlayletCategory.Slug, Value: 1},
|
||||
{Key: playletcategorymod.FN.PlayletCategory.Desc, Value: 1},
|
||||
{Key: playletcategorymod.FN.PlayletCategory.Icon, Value: 1},
|
||||
{Key: playletcategorymod.FN.PlayletCategory.Rank, Value: 1},
|
||||
{Key: playletcategorymod.FN.PlayletCategory.Status, Value: 1},
|
||||
{Key: "seoInfo", Value: 1},
|
||||
}).
|
||||
SetSort(bson.D{
|
||||
{Key: playletcategorymod.FN.PlayletCategory.Rank, Value: -1},
|
||||
{Key: playletcategorymod.FN.PlayletCategory.Id, Value: -1},
|
||||
}))
|
||||
if err != nil {
|
||||
log.Warn("playletcache.updateCategoryCache failed", log.E(err))
|
||||
return
|
||||
}
|
||||
temp := make(map[int64]*CategoryItem, len(list))
|
||||
tempBySlug := make(map[string]*CategoryItem, len(list))
|
||||
for _, item := range list {
|
||||
if item == nil || item.Id <= 0 {
|
||||
continue
|
||||
}
|
||||
cached := &CategoryItem{
|
||||
Id: item.Id,
|
||||
Name: item.Name,
|
||||
Slug: item.Slug,
|
||||
Desc: item.Desc,
|
||||
Icon: item.Icon,
|
||||
Rank: item.Rank,
|
||||
Status: item.Status,
|
||||
SeoInfo: item.SeoInfo,
|
||||
}
|
||||
temp[item.Id] = cached
|
||||
if slug := strings.TrimSpace(item.Slug); slug != "" {
|
||||
tempBySlug[slug] = cached
|
||||
}
|
||||
}
|
||||
cache.lock.Lock()
|
||||
cache.categoryByID = temp
|
||||
cache.categoryBySlug = tempBySlug
|
||||
cache.lock.Unlock()
|
||||
}
|
||||
|
||||
func updateHotSearchCache(ctx context.Context) {
|
||||
list, err := hotsearchmod.FindTopHotSearch(ctx, hotsearchmod.TopLimit)
|
||||
if err != nil {
|
||||
log.Warn("playletcache.updateHotSearchCache failed", log.E(err))
|
||||
return
|
||||
}
|
||||
temp := make([]HotSearchItem, 0, len(list))
|
||||
for _, item := range list {
|
||||
if item == nil || strings.TrimSpace(item.Keyword) == "" {
|
||||
continue
|
||||
}
|
||||
temp = append(temp, HotSearchItem{
|
||||
Keyword: item.Keyword,
|
||||
Count: item.Count,
|
||||
})
|
||||
}
|
||||
cache.lock.Lock()
|
||||
cache.hotSearch = temp
|
||||
cache.lock.Unlock()
|
||||
}
|
||||
|
||||
// ListHotSearch 返回缓存的前10个热搜词。
|
||||
func ListHotSearch() []HotSearchItem {
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
if len(cache.hotSearch) == 0 {
|
||||
return make([]HotSearchItem, 0)
|
||||
}
|
||||
result := make([]HotSearchItem, len(cache.hotSearch))
|
||||
copy(result, cache.hotSearch)
|
||||
return result
|
||||
}
|
||||
|
||||
// GetTheme 按 ID 取题材缓存;不存在返回 nil。
|
||||
func GetTheme(id int64) *ThemeItem {
|
||||
if id <= 0 {
|
||||
return nil
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
item := cache.themeByID[id]
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
cp := *item
|
||||
return &cp
|
||||
}
|
||||
|
||||
// GetEnabledTheme 按 ID 取上架题材;未上架或不存在返回 nil。
|
||||
func GetEnabledTheme(id int64) *ThemeItem {
|
||||
item := GetTheme(id)
|
||||
if item == nil || !item.Status {
|
||||
return nil
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// GetThemeBySlug 按 slug 取题材缓存;不存在返回 nil。
|
||||
func GetThemeBySlug(slug string) *ThemeItem {
|
||||
slug = strings.TrimSpace(slug)
|
||||
if slug == "" {
|
||||
return nil
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
item := cache.themeBySlug[slug]
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
cp := *item
|
||||
return &cp
|
||||
}
|
||||
|
||||
// GetTag 按 ID 取标签缓存;不存在返回 nil。
|
||||
func GetTag(id int64) *TagItem {
|
||||
if id <= 0 {
|
||||
return nil
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
item := cache.tagByID[id]
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
cp := *item
|
||||
return &cp
|
||||
}
|
||||
|
||||
// GetEnabledTag 按 ID 取上架标签;未上架或不存在返回 nil。
|
||||
func GetEnabledTag(id int64) *TagItem {
|
||||
item := GetTag(id)
|
||||
if item == nil || !item.Status {
|
||||
return nil
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// GetTagBySlug 按 slug 取标签缓存;不存在返回 nil。
|
||||
func GetTagBySlug(slug string) *TagItem {
|
||||
slug = strings.TrimSpace(slug)
|
||||
if slug == "" {
|
||||
return nil
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
item := cache.tagBySlug[slug]
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
cp := *item
|
||||
return &cp
|
||||
}
|
||||
|
||||
// GetCategory 按 ID 取分类缓存;不存在返回 nil。
|
||||
func GetCategory(id int64) *CategoryItem {
|
||||
if id <= 0 {
|
||||
return nil
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
item := cache.categoryByID[id]
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
cp := *item
|
||||
return &cp
|
||||
}
|
||||
|
||||
// GetEnabledCategory 按 ID 取启用分类;未启用或不存在返回 nil。
|
||||
func GetEnabledCategory(id int64) *CategoryItem {
|
||||
item := GetCategory(id)
|
||||
if item == nil || !item.Status {
|
||||
return nil
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// GetCategoryBySlug 按 slug 取分类缓存;不存在返回 nil。
|
||||
func GetCategoryBySlug(slug string) *CategoryItem {
|
||||
slug = strings.TrimSpace(slug)
|
||||
if slug == "" {
|
||||
return nil
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
item := cache.categoryBySlug[slug]
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
cp := *item
|
||||
return &cp
|
||||
}
|
||||
|
||||
// ListEnabledThemes 返回全部上架题材,按 Rank、Id 倒序。
|
||||
func ListEnabledThemes() []*ThemeItem {
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
result := make([]*ThemeItem, 0, len(cache.themeByID))
|
||||
for _, item := range cache.themeByID {
|
||||
if item == nil || !item.Status {
|
||||
continue
|
||||
}
|
||||
cp := *item
|
||||
result = append(result, &cp)
|
||||
}
|
||||
sort.SliceStable(result, func(i, j int) bool {
|
||||
if result[i].Rank != result[j].Rank {
|
||||
return result[i].Rank > result[j].Rank
|
||||
}
|
||||
return result[i].Id > result[j].Id
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
const homeRecommendThemeLimit = 4
|
||||
|
||||
// ListRecommendedThemes 返回已上架且推荐的题材,按 Rank、Id 倒序,最多 limit 条。
|
||||
func ListRecommendedThemes(limit int) []*ThemeItem {
|
||||
if limit <= 0 {
|
||||
limit = homeRecommendThemeLimit
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
result := make([]*ThemeItem, 0, limit)
|
||||
for _, item := range cache.themeByID {
|
||||
if item == nil || !item.Status || !item.IsRecommend {
|
||||
continue
|
||||
}
|
||||
cp := *item
|
||||
result = append(result, &cp)
|
||||
}
|
||||
sort.SliceStable(result, func(i, j int) bool {
|
||||
if result[i].Rank != result[j].Rank {
|
||||
return result[i].Rank > result[j].Rank
|
||||
}
|
||||
return result[i].Id > result[j].Id
|
||||
})
|
||||
if len(result) > limit {
|
||||
result = result[:limit]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ListEnabledCategories 返回全部启用分类,按 Rank、Id 倒序。
|
||||
func ListEnabledCategories() []*CategoryItem {
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
result := make([]*CategoryItem, 0, len(cache.categoryByID))
|
||||
for _, item := range cache.categoryByID {
|
||||
if item == nil || !item.Status {
|
||||
continue
|
||||
}
|
||||
cp := *item
|
||||
result = append(result, &cp)
|
||||
}
|
||||
sort.SliceStable(result, func(i, j int) bool {
|
||||
if result[i].Rank != result[j].Rank {
|
||||
return result[i].Rank > result[j].Rank
|
||||
}
|
||||
return result[i].Id > result[j].Id
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
// ThemeNameMap 批量取题材名称(含未上架,便于列表展示历史题材名)。
|
||||
func ThemeNameMap(ids []int64) map[int64]string {
|
||||
result := make(map[int64]string, len(ids))
|
||||
if len(ids) == 0 {
|
||||
return result
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
for _, id := range ids {
|
||||
if item := cache.themeByID[id]; item != nil {
|
||||
result[id] = item.Name
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// TagNameMap 批量取标签名称(含未上架)。
|
||||
func TagNameMap(ids []int64) map[int64]string {
|
||||
result := make(map[int64]string, len(ids))
|
||||
if len(ids) == 0 {
|
||||
return result
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
for _, id := range ids {
|
||||
if item := cache.tagByID[id]; item != nil {
|
||||
result[id] = item.Name
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ThemeSlugMap 批量取题材 slug(含未上架)。
|
||||
func ThemeSlugMap(ids []int64) map[int64]string {
|
||||
result := make(map[int64]string, len(ids))
|
||||
if len(ids) == 0 {
|
||||
return result
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
for _, id := range ids {
|
||||
if item := cache.themeByID[id]; item != nil {
|
||||
result[id] = item.Slug
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// TagSlugMap 批量取标签 slug(含未上架)。
|
||||
func TagSlugMap(ids []int64) map[int64]string {
|
||||
result := make(map[int64]string, len(ids))
|
||||
if len(ids) == 0 {
|
||||
return result
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
for _, id := range ids {
|
||||
if item := cache.tagByID[id]; item != nil {
|
||||
result[id] = item.Slug
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// CategoryNameMap 批量取分类名称(含未启用)。
|
||||
func CategoryNameMap(ids []int64) map[int64]string {
|
||||
result := make(map[int64]string, len(ids))
|
||||
if len(ids) == 0 {
|
||||
return result
|
||||
}
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
for _, id := range ids {
|
||||
if item := cache.categoryByID[id]; item != nil {
|
||||
result[id] = item.Name
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package playletcache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"videoweb/pub/common/log"
|
||||
"videoweb/pub/models/playletmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
const GuessLikeLimit = 15
|
||||
|
||||
var guessLikeProjection = bson.D{
|
||||
{Key: playletmod.FN.Playlet.Id, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Status, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.IsFeatured, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.IsRecommend, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.ShowOnBanner, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Banner, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.OnlineAt, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.MediaCreatedAt, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.MediaUpdatedAt, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.ThemeIds, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Title, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.PlayName, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Description, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Slug, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Desc, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Anchor, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Cover, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CompressedCover, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.TagIds, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.TotalEpisode, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.UpdateStatus, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CountBrowse, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.HeatValue, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CountCollect, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CountLike, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.VirtualCountLike, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.IsOriginal, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.OperateType, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CreatedAt, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.UpdatedAt, Value: 1},
|
||||
{Key: "seoInfo", Value: 1},
|
||||
}
|
||||
|
||||
func updateGuessLikeCache(ctx context.Context) {
|
||||
list, err := playletmod.FindManyPlaylet(ctx, bson.M{
|
||||
playletmod.FN.Playlet.Status: playletmod.StatusUp,
|
||||
}, options.Find().
|
||||
SetProjection(guessLikeProjection).
|
||||
SetSort(bson.D{
|
||||
{Key: playletmod.FN.Playlet.CountCollect, Value: -1},
|
||||
{Key: playletmod.FN.Playlet.Id, Value: -1},
|
||||
}).
|
||||
SetLimit(GuessLikeLimit))
|
||||
if err != nil {
|
||||
log.Warn("playletcache.updateGuessLikeCache failed", log.E(err))
|
||||
return
|
||||
}
|
||||
temp := make([]*playletmod.Playlet, 0, len(list))
|
||||
for _, item := range list {
|
||||
if cloned := clonePlaylet(item); cloned != nil {
|
||||
temp = append(temp, cloned)
|
||||
}
|
||||
}
|
||||
cache.lock.Lock()
|
||||
cache.guessLike = temp
|
||||
cache.lock.Unlock()
|
||||
}
|
||||
|
||||
// ListGuessLike 返回收藏量最多的上架短剧,最多15部。
|
||||
func ListGuessLike() []*playletmod.Playlet {
|
||||
cache.lock.RLock()
|
||||
defer cache.lock.RUnlock()
|
||||
if len(cache.guessLike) == 0 {
|
||||
return make([]*playletmod.Playlet, 0)
|
||||
}
|
||||
result := make([]*playletmod.Playlet, 0, len(cache.guessLike))
|
||||
for _, item := range cache.guessLike {
|
||||
if cloned := clonePlaylet(item); cloned != nil {
|
||||
result = append(result, cloned)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func clonePlaylet(item *playletmod.Playlet) *playletmod.Playlet {
|
||||
if item == nil || item.Id <= 0 {
|
||||
return nil
|
||||
}
|
||||
cp := *item
|
||||
if item.ThemeIds != nil {
|
||||
cp.ThemeIds = append([]int64(nil), item.ThemeIds...)
|
||||
}
|
||||
if item.TagIds != nil {
|
||||
cp.TagIds = append([]int64(nil), item.TagIds...)
|
||||
}
|
||||
if item.CategoryIds != nil {
|
||||
cp.CategoryIds = append([]int64(nil), item.CategoryIds...)
|
||||
}
|
||||
return &cp
|
||||
}
|
||||
Reference in New Issue
Block a user