203 lines
7.2 KiB
Go
203 lines
7.2 KiB
Go
package models
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
"videoweb/pub/common/log"
|
|
"videoweb/pub/common/srvdef"
|
|
"videoweb/pub/models/actress"
|
|
"videoweb/pub/models/announcementmod"
|
|
"videoweb/pub/models/cfg"
|
|
"videoweb/pub/models/commentlikemod"
|
|
"videoweb/pub/models/commentmod"
|
|
"videoweb/pub/models/contactusmod"
|
|
"videoweb/pub/models/contenttagmod"
|
|
"videoweb/pub/models/detailnavmod"
|
|
"videoweb/pub/models/esmod"
|
|
"videoweb/pub/models/eventmod"
|
|
"videoweb/pub/models/homebannermod"
|
|
"videoweb/pub/models/hotnavmod"
|
|
"videoweb/pub/models/ipblackmod"
|
|
"videoweb/pub/models/ipdailystatmod"
|
|
"videoweb/pub/models/m3u8requestlogmod"
|
|
"videoweb/pub/models/mwacc"
|
|
"videoweb/pub/models/oplog"
|
|
"videoweb/pub/models/playletbackflowstatmod"
|
|
"videoweb/pub/models/playletcategorymod"
|
|
"videoweb/pub/models/playletchaptermod"
|
|
"videoweb/pub/models/playletfavoritemod"
|
|
"videoweb/pub/models/playlethomeconfigmod"
|
|
"videoweb/pub/models/playletlikemod"
|
|
"videoweb/pub/models/playletmod"
|
|
"videoweb/pub/models/playlettagmod"
|
|
"videoweb/pub/models/playletthememod"
|
|
"videoweb/pub/models/questionnairemod"
|
|
"videoweb/pub/models/richtextcontentmod"
|
|
"videoweb/pub/models/seopushmod"
|
|
"videoweb/pub/models/syncfilemod"
|
|
"videoweb/pub/models/translationcategorymod"
|
|
"videoweb/pub/models/translationmod"
|
|
"videoweb/pub/models/userlogin"
|
|
"videoweb/pub/models/usermod"
|
|
"videoweb/pub/models/videocategorymod"
|
|
"videoweb/pub/models/videocollectionmediamod"
|
|
"videoweb/pub/models/videocreatermod"
|
|
"videoweb/pub/models/videofavoritemod"
|
|
"videoweb/pub/mongos"
|
|
|
|
"videoweb/pub/models/videoinformationmod"
|
|
"videoweb/pub/models/videolikemod"
|
|
"videoweb/pub/models/videotagmod"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
func Init() {
|
|
log.Info("models init start..")
|
|
ctx := context.Background()
|
|
cfg.Init(ctx)
|
|
mwacc.Init(ctx)
|
|
oplog.Init(ctx)
|
|
m3u8requestlogmod.Init(ctx)
|
|
|
|
videocategorymod.Init(ctx)
|
|
videoinformationmod.Init(ctx)
|
|
videofavoritemod.Init(ctx)
|
|
videolikemod.Init(ctx)
|
|
videotagmod.Init(ctx)
|
|
|
|
translationcategorymod.Init(ctx)
|
|
translationmod.Init(ctx)
|
|
contenttagmod.Init(ctx)
|
|
playletcategorymod.Init(ctx)
|
|
playlethomeconfigmod.Init(ctx)
|
|
playlettagmod.Init(ctx)
|
|
playletthememod.Init(ctx)
|
|
playletmod.Init(ctx)
|
|
playletbackflowstatmod.Init(ctx)
|
|
playletchaptermod.Init(ctx)
|
|
playletlikemod.Init(ctx)
|
|
playletfavoritemod.Init(ctx)
|
|
initWatchHistory(ctx)
|
|
videocategorymod.Init(ctx)
|
|
videocreatermod.Init(ctx)
|
|
videotagmod.Init(ctx)
|
|
videoinformationmod.Init(ctx)
|
|
videocreatermod.Init(ctx)
|
|
syncfilemod.Init(ctx)
|
|
seopushmod.Init(ctx)
|
|
richtextcontentmod.Init(ctx)
|
|
announcementmod.Init(ctx)
|
|
commentmod.Init(ctx)
|
|
commentlikemod.Init(ctx)
|
|
videocollectionmediamod.Init(ctx)
|
|
ipblackmod.Init(ctx)
|
|
esmod.Init(ctx)
|
|
actress.Init(ctx)
|
|
contactusmod.Init(ctx)
|
|
detailnavmod.Init(ctx)
|
|
hotnavmod.Init(ctx)
|
|
homebannermod.Init(ctx)
|
|
eventmod.Init(ctx)
|
|
usermod.Init(ctx)
|
|
userlogin.Init(ctx)
|
|
questionnairemod.Init(ctx)
|
|
ipdailystatmod.Init(ctx)
|
|
log.Info("models init end")
|
|
}
|
|
|
|
const (
|
|
WatchHistoryTypePlaylet int64 = 1
|
|
WatchHistoryTypeVideo int64 = 2
|
|
WatchHistoryRetentionDays = 60
|
|
watchHistoryCollectionName = "watch_history"
|
|
WatchHistoryCollectionName = watchHistoryCollectionName
|
|
WatchHistoryUserID = "userId"
|
|
WatchHistoryDataType = "dataType"
|
|
WatchHistoryContentID = "contentId"
|
|
WatchHistoryChapterID = "chapterId"
|
|
WatchHistoryEpisode = "episode"
|
|
WatchHistoryCreatedAt = "createdAt"
|
|
WatchHistoryUpdatedAt = "updatedAt"
|
|
)
|
|
|
|
// WatchHistory 保存当前用户最近观看的内容
|
|
type WatchHistory struct {
|
|
UserID int64 `bson:"userId"`
|
|
DataType int64 `bson:"dataType"`
|
|
ContentID int64 `bson:"contentId"`
|
|
ChapterID int64 `bson:"chapterId"`
|
|
Episode int64 `bson:"episode"`
|
|
CreatedAt time.Time `bson:"createdAt"`
|
|
UpdatedAt time.Time `bson:"updatedAt"`
|
|
}
|
|
|
|
var watchHistoryColl *mongos.Collection
|
|
|
|
// initWatchHistory 初始化观看历史及 60 天 TTL 索引
|
|
func initWatchHistory(ctx context.Context) {
|
|
watchHistoryColl = mongos.Shop.Coll(watchHistoryCollectionName)
|
|
indexes := []mongo.IndexModel{
|
|
{Keys: bson.D{{Key: WatchHistoryUserID, Value: 1}, {Key: WatchHistoryDataType, Value: 1}, {Key: WatchHistoryContentID, Value: 1}}, Options: options.Index().SetUnique(true)},
|
|
{Keys: bson.D{{Key: WatchHistoryUserID, Value: 1}, {Key: WatchHistoryDataType, Value: 1}, {Key: WatchHistoryUpdatedAt, Value: -1}, {Key: "_id", Value: -1}}},
|
|
{Keys: bson.D{{Key: WatchHistoryUpdatedAt, Value: 1}}, Options: options.Index().SetExpireAfterSeconds(WatchHistoryRetentionDays * 24 * 60 * 60)},
|
|
}
|
|
if _, err := watchHistoryColl.CreateIndex(ctx, indexes); err != nil {
|
|
panic(fmt.Sprintf("(models:initWatchHistory) Create Index failed! err:%+v:", err))
|
|
}
|
|
}
|
|
|
|
// TouchWatchHistory 从已验证的播放清单刷新历史
|
|
func TouchWatchHistory(ctx context.Context, item WatchHistory) *srvdef.SrvErr {
|
|
filter := bson.M{WatchHistoryUserID: item.UserID, WatchHistoryDataType: item.DataType, WatchHistoryContentID: item.ContentID}
|
|
if item.DataType == WatchHistoryTypePlaylet {
|
|
sameChapter := bson.M{WatchHistoryUserID: item.UserID, WatchHistoryDataType: item.DataType, WatchHistoryContentID: item.ContentID, WatchHistoryChapterID: item.ChapterID}
|
|
result, err := watchHistoryColl.UpdateOne(ctx, sameChapter, bson.M{"$set": bson.M{WatchHistoryUpdatedAt: item.UpdatedAt, WatchHistoryEpisode: item.Episode}})
|
|
if err != nil {
|
|
log.Warn("TouchWatchHistory failed", log.Any("filter", sameChapter), log.E(err))
|
|
return srvdef.New(srvdef.ErrDbUpdateError, "", "")
|
|
}
|
|
if result.MatchedCount > 0 {
|
|
return nil
|
|
}
|
|
}
|
|
update := bson.M{
|
|
"$set": bson.M{WatchHistoryChapterID: item.ChapterID, WatchHistoryEpisode: item.Episode, WatchHistoryUpdatedAt: item.UpdatedAt},
|
|
"$setOnInsert": bson.M{WatchHistoryUserID: item.UserID, WatchHistoryDataType: item.DataType, WatchHistoryContentID: item.ContentID, WatchHistoryCreatedAt: item.CreatedAt},
|
|
}
|
|
if _, err := watchHistoryColl.UpdateOne(ctx, filter, update, options.Update().SetUpsert(true)); err != nil {
|
|
if mongo.IsDuplicateKeyError(err) {
|
|
_, err = watchHistoryColl.UpdateOne(ctx, filter, bson.M{"$set": update["$set"]})
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
}
|
|
log.Warn("TouchWatchHistory failed", log.Any("filter", filter), log.E(err))
|
|
return srvdef.New(srvdef.ErrDbUpdateError, "", "")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// AggregateWatchHistory 聚合查询观看历史
|
|
func AggregateWatchHistory(ctx context.Context, bind interface{}, pipeline []bson.M) *srvdef.SrvErr {
|
|
if err := watchHistoryColl.Aggregate(ctx, bind, pipeline); err != nil {
|
|
log.Warn("AggregateWatchHistory failed", log.Any("pipeline", pipeline), log.E(err))
|
|
return srvdef.New(srvdef.ErrDbQueryError, "", "")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// DeleteWatchHistory 删除当前用户指定类型的观看历史
|
|
func DeleteWatchHistory(ctx context.Context, userID, dataType int64) (int64, *srvdef.SrvErr) {
|
|
filter := bson.M{WatchHistoryUserID: userID, WatchHistoryDataType: dataType}
|
|
count, err := watchHistoryColl.DeleteMany(ctx, filter)
|
|
if err != nil {
|
|
log.Warn("DeleteWatchHistory failed", log.Any("filter", filter), log.E(err))
|
|
return 0, srvdef.New(srvdef.ErrDbDeleteError, "", "")
|
|
}
|
|
return count, nil
|
|
}
|