|
|
|
@@ -0,0 +1,426 @@
|
|
|
|
|
package playlgmod
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"math"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"91porn-server/common/db"
|
|
|
|
|
"91porn-server/common/log"
|
|
|
|
|
"91porn-server/models"
|
|
|
|
|
|
|
|
|
|
"github.com/jinzhu/now"
|
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
|
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
|
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const table = models.PlayLog
|
|
|
|
|
const maxReadVideos = 200
|
|
|
|
|
|
|
|
|
|
// initIndex 初始化索引
|
|
|
|
|
func initIndex() {
|
|
|
|
|
many := []mongo.IndexModel{
|
|
|
|
|
{
|
|
|
|
|
Keys: bson.D{{Key: "uid", Value: 1}},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Keys: bson.D{{Key: "videoID", Value: 1}},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Keys: bson.D{{Key: "createdAt", Value: -1}},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
if _, err := coll(nil).CreateIndex(many); err != nil {
|
|
|
|
|
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func coll(t *db.MongoTool) *db.MongoTool {
|
|
|
|
|
if t == nil {
|
|
|
|
|
return mdb.Coll(table)
|
|
|
|
|
}
|
|
|
|
|
return t.Coll(table)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// InsertPlayRecord 记录一个播放行为
|
|
|
|
|
func InsertPlayRecord(p PlayLog) error {
|
|
|
|
|
if _, err := coll(nil).InsertOne(&p); err != nil {
|
|
|
|
|
log.Error("InsertPlayRecord error", log.Any("p", p), log.E(err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HasWatchedVideo 已经观看的视频
|
|
|
|
|
func HasWatchedVideo(uid uint64) ([]primitive.ObjectID, error) {
|
|
|
|
|
now := time.Now()
|
|
|
|
|
begin := now.AddDate(0, 0, -7)
|
|
|
|
|
var logs []*PlayLog
|
|
|
|
|
opts := options.FindOptions{}
|
|
|
|
|
opts.SetSort(bson.D{{Key: "createdAt", Value: -1}}).SetLimit(maxReadVideos)
|
|
|
|
|
if err := coll(nil).Find(&logs, bson.M{"uid": uid, "createdAt": bson.M{"$gt": begin}}, &opts); err != nil {
|
|
|
|
|
log.Error("HasWatchedVideo error", log.Any("uid", uid), log.E(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
vids := make([]primitive.ObjectID, len(logs))
|
|
|
|
|
for i, l := range logs {
|
|
|
|
|
vids[i] = l.VideoID
|
|
|
|
|
}
|
|
|
|
|
return vids, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HasWatchedVideoCnt 已经观看的视频数
|
|
|
|
|
func HasWatchedVideoCnt(uids []uint64) ([]UIDCount, error) {
|
|
|
|
|
now := time.Now()
|
|
|
|
|
begin := now.AddDate(0, 0, -4)
|
|
|
|
|
var datas []UIDCount
|
|
|
|
|
cond := bson.M{"uid": bson.M{"$in": uids}, "createdAt": bson.M{"$gt": begin}}
|
|
|
|
|
if err := coll(nil).Aggregate(&datas, []bson.M{
|
|
|
|
|
bson.M{"$match": cond},
|
|
|
|
|
bson.M{"$group": bson.M{"_id": "$uid", "count": bson.M{"$sum": 1}}},
|
|
|
|
|
}); err != nil {
|
|
|
|
|
log.Error("HasWatchedVideoCnt error", log.Any("uids", uids), log.E(err))
|
|
|
|
|
}
|
|
|
|
|
return datas, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HasWatchedTags 当天已经观看过的标签id
|
|
|
|
|
func HasWatchedTags(uid uint64, top int) ([]string, error) {
|
|
|
|
|
tagIDs := []string{}
|
|
|
|
|
var data []TagIDCount
|
|
|
|
|
if err := coll(nil).Aggregate(&data, []bson.M{
|
|
|
|
|
bson.M{"$match": bson.M{"uid": uid, "tagID": bson.M{"$exists": true}, "createdAt": bson.M{"$gte": now.BeginningOfDay()}}},
|
|
|
|
|
bson.M{"$group": bson.M{"_id": "$tagID", "count": bson.M{"$sum": 1}}},
|
|
|
|
|
bson.M{"$sort": bson.D{{Key: "count", Value: -1}}},
|
|
|
|
|
bson.M{"$limit": top},
|
|
|
|
|
}); err != nil {
|
|
|
|
|
log.Error("HasWatchedTags error", log.Any("uid", uid), log.Any("top", top), log.E(err))
|
|
|
|
|
return tagIDs, err
|
|
|
|
|
}
|
|
|
|
|
tagIDs = make([]string, len(data))
|
|
|
|
|
for i, d := range data {
|
|
|
|
|
tagIDs[i] = d.TagID.Hex()
|
|
|
|
|
}
|
|
|
|
|
return tagIDs, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getPlayRecordSkipSize 计算跳转
|
|
|
|
|
func getPlayRecordSkipSize(page, size uint64, cond bson.M) (uint64, uint64, uint64, error) {
|
|
|
|
|
var total uint64 = 10000
|
|
|
|
|
totalpages := uint64(math.Ceil(float64(total) / float64(size)))
|
|
|
|
|
if page > totalpages {
|
|
|
|
|
page = totalpages
|
|
|
|
|
}
|
|
|
|
|
if page < 1 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
return (page - 1) * size, totalpages, total, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPlayRecordList 获取播放记录
|
|
|
|
|
func getPlayRecordList(page, size uint64, cond bson.M, sort bson.D) ([]*PlayLog, uint64, uint64, error) {
|
|
|
|
|
skip, totalPages, total, err := getPlayRecordSkipSize(page, size, cond)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, 0, err
|
|
|
|
|
}
|
|
|
|
|
opts := options.FindOptions{}
|
|
|
|
|
if sort != nil {
|
|
|
|
|
opts.SetSort(sort)
|
|
|
|
|
}
|
|
|
|
|
opts.SetSkip(int64(skip)).SetLimit(int64(size))
|
|
|
|
|
var back []*PlayLog
|
|
|
|
|
if err = coll(nil).Find(&back, cond, &opts); err != nil {
|
|
|
|
|
log.Error("GetPlayRecordList error", log.Any("page", page), log.Any("size", size),
|
|
|
|
|
log.Any("cond", cond), log.Any("sort", sort), log.E(err))
|
|
|
|
|
return nil, totalPages, total, err
|
|
|
|
|
}
|
|
|
|
|
return back, totalPages, total, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetNearPlayLog 获取用户最近的观影记录
|
|
|
|
|
func GetNearPlayLog(uid uint64) error {
|
|
|
|
|
var p PlayLog
|
|
|
|
|
opts := options.FindOne().SetSort(bson.D{{Key: "createdAt", Value: -1}})
|
|
|
|
|
return coll(nil).FindOne(&p, bson.M{"uid": uid}, opts)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetViewLogToday 当天是否看过此视频
|
|
|
|
|
func GetViewLogToday(uid uint64, vid primitive.ObjectID) bool {
|
|
|
|
|
cond := bson.M{"uid": uid, "videoID": vid, "createdAt": bson.M{"$gte": now.BeginningOfDay(), "$lte": now.EndOfDay()}}
|
|
|
|
|
cnt, _ := coll(nil).Count(cond)
|
|
|
|
|
return cnt > 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 当天是否观看过视频
|
|
|
|
|
func IsViewToday(uid uint64) bool {
|
|
|
|
|
cond := bson.M{"uid": uid, "createdAt": bson.M{"$gte": now.BeginningOfDay(), "$lte": now.EndOfDay()}}
|
|
|
|
|
cnt, _ := coll(nil).Count(cond)
|
|
|
|
|
return cnt > 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PlayCountMapByTime PlayCountMapByTime playWays 0免费 1付费 2.试看
|
|
|
|
|
func PlayCountMapByTime(start time.Time, end time.Time, playWays []int) (map[primitive.ObjectID]int64, error) {
|
|
|
|
|
if len(playWays) == 0 {
|
|
|
|
|
return make(map[primitive.ObjectID]int64), nil
|
|
|
|
|
}
|
|
|
|
|
filter := bson.M{
|
|
|
|
|
"createdAt": bson.M{
|
|
|
|
|
"$gte": start,
|
|
|
|
|
"$lt": end,
|
|
|
|
|
},
|
|
|
|
|
"playWay": bson.M{"$in": playWays}, //0免费 1付费 2.试看
|
|
|
|
|
}
|
|
|
|
|
pipeline := []bson.M{
|
|
|
|
|
{
|
|
|
|
|
"$match": filter,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"$group": bson.M{
|
|
|
|
|
"_id": "$videoID",
|
|
|
|
|
"count": bson.M{
|
|
|
|
|
"$sum": 1,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
list := make([]struct {
|
|
|
|
|
VID primitive.ObjectID `bson:"_id"`
|
|
|
|
|
Count int64 `bson:"count"`
|
|
|
|
|
}, 0)
|
|
|
|
|
if err := coll(nil).Aggregate(&list, pipeline); err != nil {
|
|
|
|
|
return nil, fmt.Errorf("PlayLog PlayCountMapByTime err: %s", err.Error())
|
|
|
|
|
}
|
|
|
|
|
ret := make(map[primitive.ObjectID]int64)
|
|
|
|
|
for _, v := range list {
|
|
|
|
|
ret[v.VID] = v.Count
|
|
|
|
|
}
|
|
|
|
|
return ret, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetPayUserCount(vid []primitive.ObjectID) (int64, error) {
|
|
|
|
|
if len(vid) == 0 {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
pipeline := []bson.M{
|
|
|
|
|
{
|
|
|
|
|
"$match": bson.M{
|
|
|
|
|
"videoID": bson.M{
|
|
|
|
|
"$in": vid,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"$group": bson.M{
|
|
|
|
|
"_id": "$uid",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
count, err := coll(nil).Count(pipeline)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, fmt.Errorf("GetPatUserCount err: %s", err.Error())
|
|
|
|
|
}
|
|
|
|
|
return count, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PlayUIDListByTime
|
|
|
|
|
// playWay 0,免费 1付费 2.试看 ,nil All
|
|
|
|
|
func PlayUIDListByTime(start time.Time, end time.Time, playWay *int) ([]uint64, error) {
|
|
|
|
|
match := bson.M{
|
|
|
|
|
"$match": bson.M{
|
|
|
|
|
"createdAt": bson.M{
|
|
|
|
|
"$gte": start,
|
|
|
|
|
"$lt": end,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
if playWay != nil {
|
|
|
|
|
match["playWay"] = *playWay //0,免费 1付费 2.试看
|
|
|
|
|
}
|
|
|
|
|
pipeline := []bson.M{match}
|
|
|
|
|
pipeline = append(pipeline,
|
|
|
|
|
bson.M{
|
|
|
|
|
"$group": bson.M{
|
|
|
|
|
"_id": "$uid",
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
list := []struct {
|
|
|
|
|
UID uint64 `bson:"_id"`
|
|
|
|
|
}{}
|
|
|
|
|
if err := coll(nil).Aggregate(&list, pipeline); err != nil {
|
|
|
|
|
return nil, fmt.Errorf("PlayUIDListByTime err: %s", err.Error())
|
|
|
|
|
}
|
|
|
|
|
uidList := make([]uint64, len(list))
|
|
|
|
|
for i, v := range list {
|
|
|
|
|
uidList[i] = v.UID
|
|
|
|
|
}
|
|
|
|
|
return uidList, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func backWatchParam(param WatchReq) map[string]interface{} {
|
|
|
|
|
m := make(map[string]interface{})
|
|
|
|
|
if param.UID > 0 {
|
|
|
|
|
m["uid"] = param.UID
|
|
|
|
|
}
|
|
|
|
|
if param.PlayWay == 1 {
|
|
|
|
|
m["playWay"] = 0
|
|
|
|
|
}
|
|
|
|
|
if param.PlayWay == 2 {
|
|
|
|
|
m["playWay"] = 1
|
|
|
|
|
}
|
|
|
|
|
if param.PlayWay == 3 {
|
|
|
|
|
m["playWay"] = 2
|
|
|
|
|
}
|
|
|
|
|
if !param.End.IsZero() {
|
|
|
|
|
i := make(map[string]time.Time)
|
|
|
|
|
i["$gte"] = param.Start
|
|
|
|
|
i["$lt"] = param.End
|
|
|
|
|
m["createdAt"] = i
|
|
|
|
|
}
|
|
|
|
|
return m
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPlayLog 获取播放日志
|
|
|
|
|
func GetPlayLog(param WatchReq) ([]*PlayLog, uint64, error) {
|
|
|
|
|
cond := backWatchParam(param)
|
|
|
|
|
sort := bson.D{{Key: "createdAt", Value: -1}}
|
|
|
|
|
infos, _, total, err := getPlayRecordList(param.PageNumber, param.PageSize, bson.M(cond), sort)
|
|
|
|
|
return infos, total, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetUIDPlaySecondMap 用户播放时长(秒)map
|
|
|
|
|
func GetUIDPlaySecondMap(uidList []uint64) (map[uint64]int64, error) {
|
|
|
|
|
pipeline := []bson.M{
|
|
|
|
|
{
|
|
|
|
|
"$match": bson.M{
|
|
|
|
|
"uid": bson.M{
|
|
|
|
|
"$in": uidList,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"$group": bson.M{
|
|
|
|
|
"_id": "$uid",
|
|
|
|
|
"playSecond": bson.M{
|
|
|
|
|
"$sum": "$longer",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
list := []struct {
|
|
|
|
|
UID uint64 `bson:"_id"`
|
|
|
|
|
PlaySecond int64 `bson:"playSecond"`
|
|
|
|
|
}{}
|
|
|
|
|
if err := coll(nil).Aggregate(&list, pipeline); err != nil {
|
|
|
|
|
return nil, fmt.Errorf("GetUIDPlayTimeMap err: %s", err.Error())
|
|
|
|
|
}
|
|
|
|
|
playSecondMap := make(map[uint64]int64, len(list))
|
|
|
|
|
for _, v := range list {
|
|
|
|
|
playSecondMap[v.UID] = v.PlaySecond
|
|
|
|
|
}
|
|
|
|
|
return playSecondMap, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据时间范围获取标签下的视频的播放次数
|
|
|
|
|
func GetTagPlayByTimeRange(start time.Time, end time.Time) ([]TagPlayCount, error) {
|
|
|
|
|
list := make([]TagPlayCount, 0)
|
|
|
|
|
pipeline := []bson.M{
|
|
|
|
|
{
|
|
|
|
|
"$match": bson.M{
|
|
|
|
|
"tagID": bson.M{"$exists": true},
|
|
|
|
|
"createdAt": bson.M{"$gte": start, "$lt": end},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"$group": bson.M{
|
|
|
|
|
"_id": bson.M{"videoID": "$videoID", "tagID": "$tagID"},
|
|
|
|
|
"playCount": bson.M{"$sum": 1},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
if err := coll(nil).Aggregate(&list, pipeline); err != nil {
|
|
|
|
|
log.Error("models log play log model GetTagPlayByTimeRange error", log.E(err), log.Any("start", start), log.Any("end", end))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return list, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取播放量最多的视频
|
|
|
|
|
func GetHotVid(start time.Time, end time.Time) ([]TagPlayCount, error) {
|
|
|
|
|
list := make([]TagPlayCount, 0)
|
|
|
|
|
pipeline := []bson.M{
|
|
|
|
|
{
|
|
|
|
|
"$match": bson.M{
|
|
|
|
|
"tagID": bson.M{"$exists": true},
|
|
|
|
|
"createdAt": bson.M{"$gte": start, "$lt": end},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"$group": bson.M{
|
|
|
|
|
"_id": bson.M{"videoID": "$videoID", "tagID": "$tagID"},
|
|
|
|
|
"playCount": bson.M{"$sum": 1},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
if err := coll(nil).Aggregate(&list, pipeline); err != nil {
|
|
|
|
|
log.Error("models log play log model GetTagPlayByTimeRange error", log.E(err), log.Any("start", start), log.Any("end", end))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return list, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取播放量最多的视频
|
|
|
|
|
func GetHotVidIDs() ([]VidCount, error) {
|
|
|
|
|
list := make([]VidCount, 0)
|
|
|
|
|
pipeline := []bson.M{
|
|
|
|
|
{
|
|
|
|
|
"$match": bson.M{
|
|
|
|
|
"createdAt": bson.M{
|
|
|
|
|
"$gte": time.Now().AddDate(0, 0, -1),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"$group": bson.M{
|
|
|
|
|
"_id": "$videoID",
|
|
|
|
|
"count": bson.M{"$sum": 1},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{"$sort": bson.M{
|
|
|
|
|
"count": -1,
|
|
|
|
|
}},
|
|
|
|
|
{
|
|
|
|
|
"$limit": 20,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
return list, coll(nil).Aggregate(&list, pipeline)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取播放量最多的视频
|
|
|
|
|
func GetHotPublishesr() ([]PublisherCount, error) {
|
|
|
|
|
list := make([]PublisherCount, 0)
|
|
|
|
|
pipeline := []bson.M{
|
|
|
|
|
{
|
|
|
|
|
"$group": bson.M{
|
|
|
|
|
"_id": "$publisher",
|
|
|
|
|
"count": bson.M{"$sum": 1},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{"$match": bson.M{
|
|
|
|
|
"_id": bson.M{"$gt": 0},
|
|
|
|
|
}},
|
|
|
|
|
{"$sort": bson.M{
|
|
|
|
|
"count": -1,
|
|
|
|
|
}},
|
|
|
|
|
{
|
|
|
|
|
"$limit": 20,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
return list, coll(nil).Aggregate(&list, pipeline)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func DeleteBeforeCreatedAt(t *db.MongoTool, tm time.Time) error {
|
|
|
|
|
_, err := coll(t).DeleteMany(bson.M{"createdAt": bson.M{"$lt": tm}})
|
|
|
|
|
return err
|
|
|
|
|
}
|