package vidser import ( "91porn-server/app/appg" "91porn-server/app/service/vidhelpser" "91porn-server/common" "91porn-server/common/constant/redisconst" "91porn-server/common/log" "91porn-server/common/timeutil" topser "91porn-server/common/top" topasist "91porn-server/common/top/asistant" "91porn-server/common/top/dailytop" "91porn-server/common/top/monthtop" "91porn-server/common/top/weektop" "91porn-server/models/cache/sysconfdata" "91porn-server/models/cache/viddata" "91porn-server/models/commod" "91porn-server/models/v/sysconfmod" "91porn-server/models/v/vidmod" "encoding/json" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo/options" "time" ) type RankingReq struct { Type int `json:"type" form:"type"` // 1-日榜 2-周榜 3-月榜 4-总榜 5-年榜 NewsType string `json:"newsType" form:"newsType"` // SP-长视频 SHORT-短视频 COVER-帖子 PIC-图集 HOT-热点榜单 UID uint64 `json:"-" form:"-"` commod.Page } type RankingResp struct { List []*vidmod.VideoInfo `json:"list"` HasNext bool `json:"hasNext"` } const ( DailyRank = 1 // 日榜 WeekRank = 2 // 周榜 MonthRank = 3 // 周榜 AllRank = 4 // 总榜 YearRank = 5 // 年榜 ) func (q *RankingReq) List() (res RankingResp, err error) { defer func() { vidhelpser.ApplyFreeTrialBadgeToVideoInfos(vidhelpser.LoadFreeTrialBadgeContext(q.UID), res.List) }() if q.NewsType == "HOT" { return q.getHotRank() } switch q.Type { case DailyRank, WeekRank, MonthRank: // 日榜 res, err = q.getRank(q.Type, q.NewsType) case AllRank, YearRank: res, err = q.getAllRank(q.NewsType, q.Type == YearRank) } return } func (q *RankingReq) getHotRank() (res RankingResp, err error) { // 获取配置的标签 configure, _ := sysconfdata.GetAllFromCache() tagStrList := configure.GetStrSlice(sysconfmod.VCodeHotRankingTags) tagIds := []primitive.ObjectID{} for _, v := range tagStrList { tagId, _ := primitive.ObjectIDFromHex(v) if tagId.IsZero() { continue } tagIds = append(tagIds, tagId) } if len(tagIds) == 0 { return } key := redisconst.GetHotRankingListCacheKey(tagIds, q.PageNumber, q.PageSize) s, err := appg.Redis.Get(key) if err != nil { return res, err } if s != nil { err = json.Unmarshal([]byte(*s), &res) if err == nil { return res, nil } } defer func() { b, err := json.Marshal(res) if err != nil { log.Error("video getRank json.Marshal(res) error:", log.E(err)) return } ran := time.Duration(common.RandInt(20, 60) + 240) appg.Redis.Set(key, string(b), time.Second*ran) }() t := timeutil.BeginningOfDay(time.Now()) filter := bson.M{ "tags": bson.M{"$in": tagIds}, "newsType": bson.M{"$in": []string{vidmod.SP, vidmod.SHORT}}, "status": bson.M{"$in": []int{1, 3}}, "reviewAt": bson.M{"$gt": t.AddDate(0, 0, -30)}, } sorts := bson.D{{Key: "liaoBaTopSort", Value: -1}, {Key: "playCount", Value: -1}, {Key: "reviewAt", Value: -1}} opts := options.Find().SetLimit(q.Limit64()).SetSkip(q.Skip64()).SetSort(sorts) vidList, hasNext, err := vidmod.FindList(filter, opts) if err != nil { return } res.List = vidhelpser.EncodeVideoInfoNoUID(vidList) res.HasNext = hasNext return res, nil } func (q *RankingReq) getAllRank(newsType string, isYear bool) (res RankingResp, err error) { key := redisconst.GetRankingListCacheKey(q.Type, newsType, q.PageSize, q.PageNumber) s, err := appg.Redis.Get(key) if err != nil { return res, err } if s != nil { err = json.Unmarshal([]byte(*s), &res) if err == nil { return res, nil } } defer func() { b, err := json.Marshal(res) if err != nil { log.Error("video getRank json.Marshal(res) error:", log.E(err)) return } ran := time.Duration(common.RandInt(20, 60) + 60) appg.Redis.Set(key, string(b), time.Second*ran) }() t := timeutil.BeginningOfDay(time.Now()) t = t.AddDate(-1, -2, 0) if isYear { t = t.AddDate(0, -6, 0) } filter := bson.M{ "newsType": newsType, "status": bson.M{"$in": []int{1, 3}}, "reviewAt": bson.M{"$gt": t}, } sorts := bson.D{{Key: "collectCount", Value: -1}, {Key: "reviewAt", Value: -1}} vidList, hasNext, err := viddata.GetListFromCache(filter, int64(q.Skip()), int64(q.Limit()), sorts) if err != nil { return } res.List = vidhelpser.EncodeVideoInfoNoUID(vidList) res.HasNext = hasNext return res, nil } func (q *RankingReq) getRank(rankinType int, newsType string) (res RankingResp, err error) { var list []string var hasNext bool switch rankinType { case DailyRank: list, _, hasNext = dailytop.GetTopByPage(topser.TypeVideo(newsType), int64(q.Skip()), int64(q.Limit())) case WeekRank: list, _, hasNext = weektop.GetTopByPage(topser.TypeVideo(newsType), int64(q.Skip()), int64(q.Limit())) case MonthRank: list, _, hasNext = monthtop.GetTopByPage(topser.TypeVideo(newsType), int64(q.Skip()), int64(q.Limit())) default: return } periodRankHasContent := len(list) > 0 if !periodRankHasContent && q.Skip64() > 0 { periodRankHasContent = q.periodRankHasContent(rankinType, newsType) } ids := []primitive.ObjectID{} for _, v := range list { id, _ := primitive.ObjectIDFromHex(v) if id.IsZero() { continue } ids = append(ids, id) } // 通过id获取列表 vidList, _, err := vidmod.FindList(bson.M{"_id": bson.M{"$in": ids}}, options.Find()) if err != nil { return } vidMap := make(map[primitive.ObjectID]*vidmod.VideoModel) var videoList []*vidmod.VideoModel for _, v := range vidList { vidMap[v.ID] = v } for _, id := range ids { item, ok := vidMap[id] if !ok || (item.Status != 1 && item.Status != 3) { topasist.Remove(topser.TypeVideo(newsType), id.Hex()) continue } videoList = append(videoList, item) } if len(videoList) == 0 && !periodRankHasContent { videoList, hasNext, err = vidmod.FindCumulativeRanking(newsType, q.Page) if err != nil { return res, err } } res.List = vidhelpser.EncodeVideoInfoNoUID(videoList) res.HasNext = hasNext return res, nil } func (q *RankingReq) periodRankHasContent(rankingType int, newsType string) bool { var list []string switch rankingType { case DailyRank: list, _, _ = dailytop.GetTopByPage(topser.TypeVideo(newsType), 0, 1) case WeekRank: list, _, _ = weektop.GetTopByPage(topser.TypeVideo(newsType), 0, 1) case MonthRank: list, _, _ = monthtop.GetTopByPage(topser.TypeVideo(newsType), 0, 1) } return len(list) > 0 }