package officialWebsiteser import ( "91porn-server/common" "91porn-server/common/stderr" "91porn-server/models/v/officialWebsitemod" "91porn-server/models/v/vidmod" "sync" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo/options" ) type VideoListReq struct { Type int64 `json:"type" form:"type"` // 1: 全量,2:专辑ID,3:演员ID, 4: TagID ID string `json:"id" form:"id"` // 专辑ID或者演员ID,根据Type决定 Sort int64 `json:"sort" form:"sort"` // 1:热度,2:创建时间,3: 播放量,4:点赞量,5:评论量,6:收藏量 PageNumber int64 `json:"pageNumber" form:"pageNumber"` PageSize int64 `json:"pageSize" form:"pageSize"` } type VideoListResp struct { HasNext bool `json:"hasNext"` List []*VideoResp `json:"list"` } type VideoResp struct { ID string `json:"id"` Title string `json:"title"` SeoSlug string `json:"seoSlug"` Cover string `json:"cover"` IsHot bool `json:"isHot"` Tags []VideoTagResp `json:"tags"` } type VideoTagResp struct { ID string `json:"id"` Name string `json:"name"` } func VideoList(req *VideoListReq) (resp VideoListResp, err error) { var sort interface{} switch req.Sort { case 2: sort = bson.D{{Key: "createdAt", Value: -1}} case 3: sort = bson.D{{Key: "watchCount", Value: -1}} case 4: sort = bson.D{{Key: "likeCount", Value: -1}} case 5: sort = bson.D{{Key: "commentCount", Value: -1}} case 6: sort = bson.D{{Key: "collectCount", Value: -1}} default: sort = bson.D{{Key: "isHot", Value: -1}, {Key: "createdAt", Value: -1}} } var filter = bson.M{} objID, err := primitive.ObjectIDFromHex(req.ID) if err != nil && req.Type != 1 { err = stderr.ErrParamError return } switch req.Type { case 2: filter["albumId"] = objID case 3: filter["heroId"] = objID case 4: filter["tags._id"] = objID } filter["isActive"] = true var skip, limit = transPageAndPageNumber(req.PageSize, req.PageNumber) var ops = options.Find().SetSort(sort).SetSkip(skip).SetLimit(limit + 1) videosData, err := (&officialWebsitemod.Video{}).FindMany(filter, ops) if err != nil { return } resp = VideoListResp{ HasNext: len(videosData) > int(limit), List: make([]*VideoResp, 0), } for _, v := range videosData { var videoResp = &VideoResp{ ID: v.ID.Hex(), Title: v.Title, SeoSlug: v.SeoSlug, Cover: v.Cover, IsHot: v.IsHot, Tags: make([]VideoTagResp, 0), } for _, tag := range v.Tags { videoResp.Tags = append(videoResp.Tags, VideoTagResp{ ID: tag.ID.Hex(), Name: tag.Name, }) } resp.List = append(resp.List, videoResp) } if resp.HasNext { resp.List = resp.List[:len(resp.List)-1] } return } type VideoDetailReq struct { ID string `uri:"id" binding:"required"` } type VideoDetailResp struct { ID string `json:"id"` Title string `json:"title"` SeoSlug string `json:"seoSlug"` Description string `json:"description"` Cover string `json:"cover"` Url string `json:"url"` PlayTime uint `json:"playTime"` // 视频播放时长(秒) IsHot bool `json:"isHot"` Tags []VideoTagResp `json:"tags"` WatchCount int64 `json:"watchCount"` LikeCount int64 `json:"likeCount"` CommentCount int64 `json:"commentCount"` CollectCount int64 `json:"collectCount"` RelatedVideos []VideoResp `json:"relatedVideos"` CreatedAt time.Time `json:"createdAt"` } func VideoDetail(req *VideoDetailReq) (resp VideoDetailResp, err error) { // 兼容 id 与 seoSlug:24 位 hex 按 _id 查,否则按 seoSlug 查 filter := bson.M{"isActive": true} if id, e := primitive.ObjectIDFromHex(req.ID); e == nil { filter["_id"] = id } else { filter["seoSlug"] = req.ID } video := &officialWebsitemod.Video{} err = video.FindOne(filter) if err != nil { return } if video.ID == primitive.NilObjectID { err = stderr.OfficialWebsiteVideoNotExist return } resp = VideoDetailResp{ ID: video.ID.Hex(), Title: video.Title, SeoSlug: video.SeoSlug, Description: video.Description, Cover: video.Cover, Url: video.Url, IsHot: video.IsHot, Tags: make([]VideoTagResp, 0), WatchCount: video.WatchCount, LikeCount: video.LikeCount, CommentCount: video.CommentCount, CollectCount: video.CollectCount, CreatedAt: video.CreatedAt, } // 播放时长:官网视频复用了视频库(vidmod)的视频 ID,按 ID 反查视频库获取 if vid, e := vidmod.GetVideoByID(video.ID); e == nil && vid != nil { resp.PlayTime = vid.PlayTime } for _, tag := range video.Tags { resp.Tags = append(resp.Tags, VideoTagResp{ ID: tag.ID.Hex(), Name: tag.Name, }) } var tagsID = make([]primitive.ObjectID, 0) for _, tag := range video.Tags { tagsID = append(tagsID, tag.ID) } var videoTags []officialWebsitemod.Video var videoNormal []officialWebsitemod.Video var wg = &sync.WaitGroup{} wg.Add(2) common.Go(func() { defer wg.Done() if len(tagsID) == 0 { return } filterTags := bson.M{"tags.id": bson.M{"$in": tagsID}, "isActive": true} videoTags, _ = (&officialWebsitemod.Video{}).FindMany(filterTags, options.Find().SetSort(bson.D{{Key: "isHot", Value: -1}, {Key: "createdAt", Value: -1}}).SetLimit(10)) }) common.Go(func() { defer wg.Done() filterNormal := bson.M{"isActive": true} videoNormal, _ = (&officialWebsitemod.Video{}).FindMany(filterNormal, options.Find().SetSort(bson.D{{Key: "isHot", Value: -1}, {Key: "createdAt", Value: -1}}).SetLimit(10)) }) wg.Wait() var relatedVideosData []officialWebsitemod.Video if len(videoTags) > 0 { relatedVideosData = videoTags } else { relatedVideosData = videoNormal } resp.RelatedVideos = make([]VideoResp, 0) for _, v := range relatedVideosData { var videoResp = VideoResp{ ID: v.ID.Hex(), Title: v.Title, SeoSlug: v.SeoSlug, Cover: v.Cover, IsHot: v.IsHot, Tags: make([]VideoTagResp, 0), } for _, tag := range v.Tags { videoResp.Tags = append(videoResp.Tags, VideoTagResp{ ID: tag.ID.Hex(), Name: tag.Name, }) } resp.RelatedVideos = append(resp.RelatedVideos, videoResp) } return }