228 lines
6.3 KiB
Go
228 lines
6.3 KiB
Go
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
|
||
}
|