Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+426
View File
@@ -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
}