@@ -0,0 +1,423 @@
|
||||
package Init
|
||||
|
||||
import (
|
||||
"91porn-server/models/s/dailyretentionmod"
|
||||
"91porn-server/models/s/useradverstatmod"
|
||||
"91porn-server/models/v/advanceconfigmod"
|
||||
"91porn-server/models/v/advanceordermod"
|
||||
"91porn-server/models/v/aichangefaceimgmod"
|
||||
"91porn-server/models/v/aichangefacemod"
|
||||
"91porn-server/models/v/aichangefacevidmod"
|
||||
"91porn-server/models/v/aiimagetovideomod"
|
||||
"91porn-server/models/v/aiplazamod"
|
||||
"91porn-server/models/v/aitemplatemodulemod"
|
||||
"91porn-server/models/v/aitexttoimagemod"
|
||||
"91porn-server/models/v/aitexttonovelmod"
|
||||
"91porn-server/models/v/bannerjumpmod"
|
||||
"91porn-server/models/v/checkinconfigmod"
|
||||
"91porn-server/models/v/checkinprizemod"
|
||||
"91porn-server/models/v/cmtmod"
|
||||
"91porn-server/models/v/collectmod"
|
||||
"91porn-server/models/v/coupon_record_mod"
|
||||
"91porn-server/models/v/discount_area_mod"
|
||||
"91porn-server/models/v/discount_area_video_mod"
|
||||
"91porn-server/models/v/eventmod"
|
||||
"91porn-server/models/v/export_task_mod"
|
||||
"91porn-server/models/v/followmod"
|
||||
"91porn-server/models/v/fundtransferlogmod"
|
||||
"91porn-server/models/v/imgroupmembermod"
|
||||
"91porn-server/models/v/imgroupmod"
|
||||
"91porn-server/models/v/immessagemod"
|
||||
"91porn-server/models/v/integralconfigmod"
|
||||
"91porn-server/models/v/integralexcangemod"
|
||||
"91porn-server/models/v/jingangmod"
|
||||
"91porn-server/models/v/likemod"
|
||||
"91porn-server/models/v/media_buy_record_mod"
|
||||
"91porn-server/models/v/mediabookshelfmod"
|
||||
"91porn-server/models/v/mediacontentmod"
|
||||
"91porn-server/models/v/mediamod"
|
||||
"91porn-server/models/v/mediatagdimensionmod"
|
||||
"91porn-server/models/v/mediatagmod"
|
||||
"91porn-server/models/v/messagemod"
|
||||
"91porn-server/models/v/nakedchatmod"
|
||||
"91porn-server/models/v/nakedchatordermod"
|
||||
"91porn-server/models/v/officialWebsitemod"
|
||||
"91porn-server/models/v/officialmod"
|
||||
"91porn-server/models/v/paymentguidemod"
|
||||
"91porn-server/models/v/sessionmod"
|
||||
"91porn-server/models/v/signrecordmod"
|
||||
"91porn-server/models/v/signtaskmod"
|
||||
"91porn-server/models/v/sysconfmod"
|
||||
"91porn-server/models/v/taskrecordmod"
|
||||
"91porn-server/models/v/userResourcemod"
|
||||
"91porn-server/models/v/usercheckinmod"
|
||||
"91porn-server/models/v/videogoldcoinmod"
|
||||
"91porn-server/models/v/vidtimeonlinemod"
|
||||
"91porn-server/models/v/vipcardexperimentmod"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models/l/adsclicklogmod"
|
||||
"91porn-server/models/l/exchlogmod"
|
||||
"91porn-server/models/l/loginlgmod"
|
||||
"91porn-server/models/l/lotterylgmod"
|
||||
"91porn-server/models/l/operatorlgmod"
|
||||
"91porn-server/models/l/payvidlgmod"
|
||||
"91porn-server/models/l/playlgmod"
|
||||
"91porn-server/models/l/pullgmod"
|
||||
"91porn-server/models/l/registermod"
|
||||
"91porn-server/models/l/searchlogmod"
|
||||
"91porn-server/models/l/synccdnmod"
|
||||
"91porn-server/models/l/userdailytasklogmod"
|
||||
"91porn-server/models/l/visitlogmod"
|
||||
"91porn-server/models/l/welfarelgmod"
|
||||
"91porn-server/models/s/hotstatmod"
|
||||
"91porn-server/models/s/kwrankmod"
|
||||
"91porn-server/models/s/kwstatmod"
|
||||
"91porn-server/models/s/sectionstatmod"
|
||||
"91porn-server/models/s/statordermod"
|
||||
"91porn-server/models/s/statrecordmod"
|
||||
"91porn-server/models/s/stattagplaymod"
|
||||
"91porn-server/models/s/statusermod"
|
||||
"91porn-server/models/s/statvidmod"
|
||||
"91porn-server/models/s/statvidtotalmod"
|
||||
"91porn-server/models/v/active2023mod"
|
||||
"91porn-server/models/v/activitymod"
|
||||
"91porn-server/models/v/actmod"
|
||||
"91porn-server/models/v/adminmod"
|
||||
"91porn-server/models/v/adreviewmod"
|
||||
"91porn-server/models/v/adsmod"
|
||||
"91porn-server/models/v/aiUnDressmod"
|
||||
"91porn-server/models/v/annoumod"
|
||||
"91porn-server/models/v/audioanchormod"
|
||||
"91porn-server/models/v/audiobookmod"
|
||||
"91porn-server/models/v/authoritymod"
|
||||
"91porn-server/models/v/backpackmod"
|
||||
"91porn-server/models/v/chatrobotmod"
|
||||
"91porn-server/models/v/contentlibmod"
|
||||
"91porn-server/models/v/contentreviewmod"
|
||||
"91porn-server/models/v/currencymod"
|
||||
"91porn-server/models/v/dailytaskmod"
|
||||
"91porn-server/models/v/errfedbkmod"
|
||||
"91porn-server/models/v/exchcodemod"
|
||||
"91porn-server/models/v/faqmod"
|
||||
"91porn-server/models/v/feedbackmod"
|
||||
"91porn-server/models/v/fictionmod"
|
||||
"91porn-server/models/v/filtermod"
|
||||
"91porn-server/models/v/freeVidmod"
|
||||
"91porn-server/models/v/fsuidmod"
|
||||
"91porn-server/models/v/goldcfgmod"
|
||||
"91porn-server/models/v/goldextramod"
|
||||
"91porn-server/models/v/hevctaskmod"
|
||||
"91porn-server/models/v/idmod"
|
||||
"91porn-server/models/v/imagetopmod"
|
||||
"91porn-server/models/v/immod"
|
||||
"91porn-server/models/v/imusermod"
|
||||
"91porn-server/models/v/ipblockmod"
|
||||
"91porn-server/models/v/ipwhitemod"
|
||||
"91porn-server/models/v/ldycfgmod"
|
||||
"91porn-server/models/v/locmod"
|
||||
"91porn-server/models/v/marqueemod"
|
||||
"91porn-server/models/v/moduleconfmod"
|
||||
"91porn-server/models/v/modulesectionmod"
|
||||
"91porn-server/models/v/modulevidmod"
|
||||
"91porn-server/models/v/newactivity"
|
||||
"91porn-server/models/v/noticefmtmod"
|
||||
"91porn-server/models/v/noticerecdmod"
|
||||
"91porn-server/models/v/oncetaskmod"
|
||||
"91porn-server/models/v/operationlogmod"
|
||||
"91porn-server/models/v/payaudiobookmod"
|
||||
"91porn-server/models/v/prdcthsomod"
|
||||
"91porn-server/models/v/prizemod"
|
||||
"91porn-server/models/v/productbenefitmod"
|
||||
"91porn-server/models/v/productmod"
|
||||
"91porn-server/models/v/productposimod"
|
||||
"91porn-server/models/v/proxyincomemod"
|
||||
"91porn-server/models/v/proxymod"
|
||||
"91porn-server/models/v/proxyrecordmod"
|
||||
"91porn-server/models/v/pushmod"
|
||||
"91porn-server/models/v/questionnremod"
|
||||
"91porn-server/models/v/quicksearchmod"
|
||||
"91porn-server/models/v/rchgamegoldmod"
|
||||
"91porn-server/models/v/rchgamtmod"
|
||||
"91porn-server/models/v/rchgchanmod"
|
||||
"91porn-server/models/v/rchgordmod"
|
||||
"91porn-server/models/v/recmdtag"
|
||||
"91porn-server/models/v/recommod"
|
||||
"91porn-server/models/v/reptmod"
|
||||
"91porn-server/models/v/repttypemod"
|
||||
"91porn-server/models/v/rjctmpltmod"
|
||||
"91porn-server/models/v/rolemod"
|
||||
"91porn-server/models/v/scenebannermod"
|
||||
"91porn-server/models/v/sensitivewordmod"
|
||||
"91porn-server/models/v/settingmod"
|
||||
"91porn-server/models/v/sourcemod"
|
||||
"91porn-server/models/v/systemmod"
|
||||
"91porn-server/models/v/tagconfmod"
|
||||
"91porn-server/models/v/tagmod"
|
||||
"91porn-server/models/v/taskmod"
|
||||
"91porn-server/models/v/tonemod"
|
||||
"91porn-server/models/v/tonerecomod"
|
||||
"91porn-server/models/v/txnactmod"
|
||||
"91porn-server/models/v/txnmod"
|
||||
"91porn-server/models/v/useractmod"
|
||||
"91porn-server/models/v/usermod"
|
||||
"91porn-server/models/v/userrecomod"
|
||||
"91porn-server/models/v/usertagmod"
|
||||
"91porn-server/models/v/userwatchrecordmod"
|
||||
"91porn-server/models/v/verifyreportmod"
|
||||
"91porn-server/models/v/versionmod"
|
||||
"91porn-server/models/v/videoactivitymod"
|
||||
"91porn-server/models/v/videocoupon"
|
||||
"91porn-server/models/v/videodiscountmod"
|
||||
"91porn-server/models/v/vidmod"
|
||||
"91porn-server/models/v/vidpopmod"
|
||||
"91porn-server/models/v/vipconfigmod"
|
||||
"91porn-server/models/v/walletmod"
|
||||
"91porn-server/models/v/wdchannmod"
|
||||
"91porn-server/models/v/wdordmod"
|
||||
"91porn-server/models/v/wdtaxmod"
|
||||
)
|
||||
|
||||
// initVideoDB 初始化主业务数据库
|
||||
func initVideoDB() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Warn("[Init Index Error]===>", log.Any("Detail ", r))
|
||||
os.Exit(-1)
|
||||
}
|
||||
}()
|
||||
log.Info("【DB-Video】init start..")
|
||||
filtermod.Init()
|
||||
repttypemod.Init()
|
||||
reptmod.Init()
|
||||
tagmod.Init()
|
||||
tonemod.Init()
|
||||
tonerecomod.Init()
|
||||
locmod.Init()
|
||||
vidmod.Init()
|
||||
hevctaskmod.Init()
|
||||
adminmod.Init()
|
||||
adsmod.Init()
|
||||
adreviewmod.Init()
|
||||
annoumod.Init()
|
||||
pushmod.Init()
|
||||
activitymod.Init()
|
||||
sourcemod.Init()
|
||||
productmod.Init()
|
||||
productposimod.Init()
|
||||
proxyincomemod.Init()
|
||||
proxymod.Init()
|
||||
proxyrecordmod.Init()
|
||||
idmod.Init()
|
||||
usermod.Init()
|
||||
rchgamtmod.Init()
|
||||
rchgamegoldmod.Init()
|
||||
goldcfgmod.Init()
|
||||
rchgchanmod.Init()
|
||||
rchgordmod.Init()
|
||||
prdcthsomod.Init()
|
||||
settingmod.Init()
|
||||
versionmod.Init()
|
||||
walletmod.Init()
|
||||
fundtransferlogmod.Init()
|
||||
wdchannmod.Init()
|
||||
wdordmod.Init()
|
||||
wdtaxmod.Init()
|
||||
authoritymod.Init()
|
||||
rolemod.Init()
|
||||
faqmod.Init()
|
||||
feedbackmod.Init()
|
||||
txnactmod.Init()
|
||||
txnmod.Init()
|
||||
useractmod.Init()
|
||||
usertagmod.Init()
|
||||
immod.Init()
|
||||
imusermod.Init()
|
||||
ipblockmod.Init()
|
||||
ipwhitemod.Init()
|
||||
noticefmtmod.Init()
|
||||
noticerecdmod.Init()
|
||||
officialmod.Init()
|
||||
userrecomod.Init()
|
||||
exchcodemod.Init()
|
||||
chatrobotmod.Init()
|
||||
contentlibmod.Init()
|
||||
fsuidmod.Init()
|
||||
recmdtag.Init()
|
||||
freeVidmod.Init()
|
||||
newactivity.Init()
|
||||
ldycfgmod.Init()
|
||||
questionnremod.Init()
|
||||
verifyreportmod.Init()
|
||||
fictionmod.Init()
|
||||
audiobookmod.Init()
|
||||
audioanchormod.Init()
|
||||
errfedbkmod.Init()
|
||||
payaudiobookmod.Init()
|
||||
vipconfigmod.Init()
|
||||
taskmod.Init()
|
||||
taskrecordmod.Init()
|
||||
backpackmod.Init()
|
||||
prizemod.Init()
|
||||
currencymod.Init()
|
||||
systemmod.Init()
|
||||
videodiscountmod.Init()
|
||||
moduleconfmod.Init()
|
||||
modulesectionmod.Init()
|
||||
recommod.Init()
|
||||
modulevidmod.Init()
|
||||
tagconfmod.Init()
|
||||
operationlogmod.Init()
|
||||
videocoupon.Init()
|
||||
marqueemod.Init()
|
||||
videoactivitymod.Init()
|
||||
vidpopmod.Init()
|
||||
userwatchrecordmod.Index()
|
||||
productbenefitmod.Init()
|
||||
imagetopmod.Init()
|
||||
active2023mod.Init()
|
||||
goldextramod.Init()
|
||||
actmod.Init()
|
||||
dailytaskmod.Init()
|
||||
oncetaskmod.Init()
|
||||
rjctmpltmod.Init()
|
||||
aiUnDressmod.Init()
|
||||
likemod.Init()
|
||||
integralconfigmod.Init()
|
||||
integralexcangemod.Init()
|
||||
followmod.Init()
|
||||
cmtmod.Init()
|
||||
collectmod.Init()
|
||||
userResourcemod.Init()
|
||||
aichangefacevidmod.Init()
|
||||
aichangefacemod.Init()
|
||||
sessionmod.Init()
|
||||
messagemod.Init()
|
||||
aichangefaceimgmod.Init()
|
||||
advanceordermod.Init()
|
||||
videogoldcoinmod.Init()
|
||||
advanceconfigmod.Init()
|
||||
coupon_record_mod.Init()
|
||||
signrecordmod.Init()
|
||||
vidtimeonlinemod.Init()
|
||||
discount_area_mod.Init()
|
||||
discount_area_video_mod.Init()
|
||||
export_task_mod.Init()
|
||||
quicksearchmod.Init()
|
||||
sysconfmod.Init()
|
||||
bannerjumpmod.Init()
|
||||
paymentguidemod.Init()
|
||||
scenebannermod.Init()
|
||||
vipcardexperimentmod.Init()
|
||||
mediamod.Init()
|
||||
mediacontentmod.Init()
|
||||
mediatagmod.Init()
|
||||
mediatagdimensionmod.Init()
|
||||
mediabookshelfmod.Init()
|
||||
media_buy_record_mod.Init()
|
||||
imgroupmod.Init()
|
||||
imgroupmembermod.Init()
|
||||
immessagemod.Init()
|
||||
nakedchatmod.Init()
|
||||
nakedchatordermod.Init()
|
||||
aitexttoimagemod.Init()
|
||||
aiimagetovideomod.Init()
|
||||
aitemplatemodulemod.Init()
|
||||
aiplazamod.Init()
|
||||
signtaskmod.Init()
|
||||
aitexttonovelmod.Init()
|
||||
eventmod.Init()
|
||||
checkinprizemod.Init()
|
||||
usercheckinmod.Init()
|
||||
checkinconfigmod.Init()
|
||||
sensitivewordmod.Init()
|
||||
contentreviewmod.Init()
|
||||
officialWebsitemod.Init()
|
||||
log.Info("【DB-Video】init end")
|
||||
}
|
||||
|
||||
// initStatDB 初始化统计数据库
|
||||
func initStatDB() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Warn("[Init Index Error]===>", log.Any("Detail ", r))
|
||||
os.Exit(-1)
|
||||
}
|
||||
}()
|
||||
log.Info("【DB-Stat】init start..")
|
||||
statrecordmod.Init()
|
||||
sectionstatmod.Init()
|
||||
statvidmod.Init()
|
||||
statordermod.Init()
|
||||
kwstatmod.Init()
|
||||
kwrankmod.Init()
|
||||
stattagplaymod.Init()
|
||||
statvidtotalmod.Init()
|
||||
statusermod.Init()
|
||||
hotstatmod.Init()
|
||||
dailyretentionmod.Init()
|
||||
useradverstatmod.Init()
|
||||
log.Info("【DB-Stat】init end")
|
||||
}
|
||||
|
||||
// initLogDB 初始化日志数据库
|
||||
func initLogDB() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Warn("[Init Index Error]===>", log.Any("Detail ", r))
|
||||
os.Exit(-1)
|
||||
}
|
||||
}()
|
||||
log.Info("【DB-Log】 db init start..")
|
||||
loginlgmod.Init()
|
||||
payvidlgmod.Init()
|
||||
playlgmod.Init()
|
||||
pullgmod.Init()
|
||||
searchlogmod.Init()
|
||||
visitlogmod.Init()
|
||||
welfarelgmod.Init()
|
||||
synccdnmod.Init()
|
||||
operatorlgmod.Init()
|
||||
registermod.Init()
|
||||
exchlogmod.Init()
|
||||
lotterylgmod.Init()
|
||||
adsclicklogmod.Init()
|
||||
userdailytasklogmod.Init()
|
||||
jingangmod.Init()
|
||||
log.Info("【DB-Log】db init end")
|
||||
}
|
||||
|
||||
// Init 设置索引//
|
||||
func InitMongo() {
|
||||
log.Info("DB init start..")
|
||||
initLogDB()
|
||||
initVideoDB()
|
||||
initStatDB()
|
||||
log.Info("DB init end")
|
||||
}
|
||||
|
||||
func ESInit() {
|
||||
log.Info("ES init start...")
|
||||
initESIndex()
|
||||
log.Info("ES init end")
|
||||
}
|
||||
|
||||
// 初始化ES index
|
||||
func initESIndex() {
|
||||
vidmod.InitESIndex()
|
||||
tagmod.InitESIndex()
|
||||
usermod.InitESIndex()
|
||||
audiobookmod.InitESIndex()
|
||||
}
|
||||
|
||||
func InitCache() {
|
||||
go func() {
|
||||
ticker := time.NewTicker(29 * time.Minute)
|
||||
for {
|
||||
<-ticker.C
|
||||
vidmod.SetAllVidWithPopCache()
|
||||
}
|
||||
}()
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package aiimagetovideodata
|
||||
|
||||
import (
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/aiimagetovideomod"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []aiimagetovideomod.AiImageToVideo
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]aiimagetovideomod.AiImageToVideo, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.AiImageToVideo).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = aiimagetovideomod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res aiimagetovideomod.AiImageToVideo, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoInfoKey(models.AiImageToVideo, id.Hex()).ResBind(&res).Cache(aiimagetovideomod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []aiimagetovideomod.AiImageToVideo, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoListKey(models.AiImageToVideo+"-all").ResBind(&res).Cache(aiimagetovideomod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data aiimagetovideomod.AiImageToVideo) (primitive.ObjectID, error) {
|
||||
newID, err := aiimagetovideomod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.AiImageToVideo).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := aiimagetovideomod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.AiImageToVideo).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = aiimagetovideomod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.AiImageToVideo).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package aiimagetovideodata
|
||||
|
||||
import "91porn-server/models/v/aiimagetovideomod"
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []aiimagetovideomod.AiImageToVideo) (res []*aiimagetovideomod.AiImageToVideoInfo) {
|
||||
res = make([]*aiimagetovideomod.AiImageToVideoInfo, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item aiimagetovideomod.AiImageToVideo) (res *aiimagetovideomod.AiImageToVideoInfo) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &aiimagetovideomod.AiImageToVideoInfo{
|
||||
ID: item.ID,
|
||||
UID: item.UID,
|
||||
ImgUrl: item.ImgUrl,
|
||||
NewImgUrl: item.NewImgUrl,
|
||||
Status: item.Status,
|
||||
Coin: item.Coin,
|
||||
IsFreeTimes: item.IsFreeTimes,
|
||||
IsHide: item.IsHide,
|
||||
Remark: item.Remark,
|
||||
IsDelete: item.IsDelete,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package aiplazadata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/aiplazamod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []aiplazamod.AiPlaza
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]aiplazamod.AiPlaza, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.AiPlaza).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = aiplazamod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res aiplazamod.AiPlaza, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoInfoKey(models.AiPlaza, id.Hex()).ResBind(&res).Cache(aiplazamod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []aiplazamod.AiPlaza, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoListKey(models.AiPlaza+"-all").ResBind(&res).Cache(aiplazamod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data aiplazamod.AiPlaza) (primitive.ObjectID, error) {
|
||||
newID, err := aiplazamod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.AiPlaza).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := aiplazamod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.AiPlaza).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id ...primitive.ObjectID) (err error) {
|
||||
err = aiplazamod.DeleteByID(t, id...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.AiPlaza).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
package aiplazadata
|
||||
|
||||
import (
|
||||
"91porn-server/app/service/vidhelpser"
|
||||
"91porn-server/common"
|
||||
"91porn-server/models/v/aiplazamod"
|
||||
"91porn-server/models/v/collectmod"
|
||||
"91porn-server/models/v/likemod"
|
||||
"91porn-server/models/v/vidmod"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []aiplazamod.AiPlaza) (res []*aiplazamod.AiPlazaInfo) {
|
||||
res = make([]*aiplazamod.AiPlazaInfo, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
// 获取用户数据
|
||||
uids := []uint64{}
|
||||
for _, item := range origin {
|
||||
uids = append(uids, item.Uid)
|
||||
}
|
||||
userMap := vidhelpser.GetSimpleUserMapNoUID(uids)
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppSimpleData(item, userMap)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppSimpleData 格式化app数据
|
||||
func FormatAppSimpleData(item aiplazamod.AiPlaza, userMap map[uint64]*vidmod.Publisher) (res *aiplazamod.AiPlazaInfo) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &aiplazamod.AiPlazaInfo{
|
||||
ID: item.ID,
|
||||
Type: item.Type,
|
||||
Template: item.Template,
|
||||
Uid: item.Uid,
|
||||
Title: item.Title,
|
||||
OriginalImage: item.OriginalImage,
|
||||
OriginalVideo: item.OriginalVideo,
|
||||
OriginalVideoCover: item.OriginalVideoCover,
|
||||
OriginContent: item.OriginContent,
|
||||
GenerateImage: item.GenerateImage,
|
||||
GenerateVideo: item.GenerateVideo,
|
||||
GenerateVideoCover: item.GenerateVideoCover,
|
||||
Status: item.Status,
|
||||
Reason: item.Reason,
|
||||
SortCode: item.SortCode,
|
||||
LikeCount: item.LikeCount,
|
||||
CollectCount: item.CollectCount,
|
||||
CommentCount: item.CommentCount,
|
||||
ViewCount: item.ViewCount,
|
||||
ReviewAt: item.ReviewAt,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
if userMap != nil {
|
||||
user, ok := userMap[item.Uid]
|
||||
if ok && user != nil {
|
||||
res.Name = user.Name
|
||||
res.Gender = user.Gender
|
||||
res.Portrait = user.Portrait
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app列表数据
|
||||
func FormatAppData(uid uint64, item aiplazamod.AiPlaza) (res *aiplazamod.AiPlazaInfo) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
userMap := vidhelpser.GetSimpleUserMapNoUID([]uint64{item.Uid})
|
||||
// 获取是否点赞,收藏数据
|
||||
dataStatus := GetDataStatus(uid, []primitive.ObjectID{item.ID})
|
||||
// 组装返回数据
|
||||
res = &aiplazamod.AiPlazaInfo{
|
||||
ID: item.ID,
|
||||
Type: item.Type,
|
||||
Template: item.Template,
|
||||
Uid: item.Uid,
|
||||
Title: item.Title,
|
||||
OriginalImage: item.OriginalImage,
|
||||
OriginalVideo: item.OriginalVideo,
|
||||
OriginalVideoCover: item.OriginalVideoCover,
|
||||
OriginContent: item.OriginContent,
|
||||
GenerateImage: item.GenerateImage,
|
||||
GenerateVideo: item.GenerateVideo,
|
||||
GenerateVideoCover: item.GenerateVideoCover,
|
||||
Status: item.Status,
|
||||
Reason: item.Reason,
|
||||
SortCode: item.SortCode,
|
||||
ReviewAt: item.ReviewAt,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
if userMap != nil {
|
||||
user, ok := userMap[item.Uid]
|
||||
if ok && user != nil {
|
||||
res.Name = user.Name
|
||||
res.Gender = user.Gender
|
||||
res.Portrait = user.Portrait
|
||||
}
|
||||
}
|
||||
if dataStatus != nil {
|
||||
res.HasLiked = dataStatus[item.ID].HasLiked
|
||||
res.HasCollected = dataStatus[item.ID].HasCollected
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DataStatus 数据状态
|
||||
type DataStatus struct {
|
||||
//已点赞
|
||||
HasLiked bool `json:"hasLiked" bson:"hasLiked"`
|
||||
//已收藏
|
||||
HasCollected bool `json:"hasCollected" bson:"hasCollected"`
|
||||
}
|
||||
|
||||
// GetDataStatus 获取数据状态信息
|
||||
func GetDataStatus(uid uint64, objIds []primitive.ObjectID) map[primitive.ObjectID]DataStatus {
|
||||
mLike := make(map[primitive.ObjectID]bool)
|
||||
mCollect := make(map[primitive.ObjectID]bool)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
common.Go(func() {
|
||||
defer wg.Done()
|
||||
mLike, _ = likemod.IsLikeVideos(uid, objIds)
|
||||
})
|
||||
common.Go(func() {
|
||||
defer wg.Done()
|
||||
mCollect, _ = collectmod.IsCollectVideos(uid, objIds)
|
||||
})
|
||||
wg.Wait()
|
||||
m := make(map[primitive.ObjectID]DataStatus)
|
||||
for _, v := range objIds {
|
||||
info := DataStatus{
|
||||
HasLiked: mLike[v],
|
||||
HasCollected: mCollect[v],
|
||||
}
|
||||
m[v] = info
|
||||
}
|
||||
return m
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package aitemplatemoduledata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/aitemplatemodulemod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []aitemplatemodulemod.AiTemplateModule
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]aitemplatemodulemod.AiTemplateModule, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(3*time.Minute).AutoListKey(models.AiTemplateModule).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = aitemplatemodulemod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res aitemplatemodulemod.AiTemplateModule, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(5*time.Minute).AutoInfoKey(models.AiTemplateModule, id.Hex()).ResBind(&res).Cache(aitemplatemodulemod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []aitemplatemodulemod.AiTemplateModule, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(8*time.Minute).AutoListKey(models.AiTemplateModule+"-all").ResBind(&res).Cache(aitemplatemodulemod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data aitemplatemodulemod.AiTemplateModule) (primitive.ObjectID, error) {
|
||||
newID, err := aitemplatemodulemod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.AiTemplateModule).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := aitemplatemodulemod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.AiTemplateModule).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = aitemplatemodulemod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.AiTemplateModule).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package aitemplatemoduledata
|
||||
|
||||
import (
|
||||
"91porn-server/models/v/aitemplatemodulemod"
|
||||
)
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []aitemplatemodulemod.AiTemplateModule) (res []*aitemplatemodulemod.AiTemplateModuleInfo) {
|
||||
res = make([]*aitemplatemodulemod.AiTemplateModuleInfo, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item aitemplatemodulemod.AiTemplateModule) (res *aitemplatemodulemod.AiTemplateModuleInfo) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &aitemplatemodulemod.AiTemplateModuleInfo{
|
||||
ID: item.ID,
|
||||
Type: item.Type,
|
||||
Name: item.Name,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package aitexttoimagedata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/aitexttoimagemod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []aitexttoimagemod.AiTextToImage
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]aitexttoimagemod.AiTextToImage, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(3*time.Minute).AutoListKey(models.AiTextToImage).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = aitexttoimagemod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res aitexttoimagemod.AiTextToImage, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(5*time.Minute).AutoInfoKey(models.AiTextToImage, id.Hex()).ResBind(&res).Cache(aitexttoimagemod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []aitexttoimagemod.AiTextToImage, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(8*time.Minute).AutoListKey(models.AiTextToImage+"-all").ResBind(&res).Cache(aitexttoimagemod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data aitexttoimagemod.AiTextToImage) (primitive.ObjectID, error) {
|
||||
newID, err := aitexttoimagemod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.AiTextToImage).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := aitexttoimagemod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.AiTextToImage).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = aitexttoimagemod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.AiTextToImage).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package aitexttoimagedata
|
||||
|
||||
import (
|
||||
"91porn-server/models/v/aitexttoimagemod"
|
||||
)
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []aitexttoimagemod.AiTextToImage) (res []*aitexttoimagemod.AiTextToImageInfo) {
|
||||
res = make([]*aitexttoimagemod.AiTextToImageInfo, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item aitexttoimagemod.AiTextToImage) (res *aitexttoimagemod.AiTextToImageInfo) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &aitexttoimagemod.AiTextToImageInfo{
|
||||
ID: item.ID,
|
||||
UID: item.UID,
|
||||
Text: item.Text,
|
||||
NewImgUrl: item.NewImgUrl,
|
||||
Status: item.Status,
|
||||
AspectRatio: item.AspectRatio,
|
||||
StyleType: item.StyleType,
|
||||
Coin: item.Coin,
|
||||
DebitAmountCoin: item.DebitAmountCoin,
|
||||
DebitIncomeCoin: item.DebitIncomeCoin,
|
||||
IsFreeTimes: item.IsFreeTimes,
|
||||
IsHide: item.IsHide,
|
||||
Remark: item.Remark,
|
||||
IsDelete: item.IsDelete,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package aitexttonoveldata
|
||||
|
||||
import (
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/aitexttonovelmod"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []aitexttonovelmod.AiTextToNovel
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]aitexttonovelmod.AiTextToNovel, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.AiTextToNovel).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = aitexttonovelmod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res aitexttonovelmod.AiTextToNovel, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoInfoKey(models.AiTextToNovel, id.Hex()).ResBind(&res).Cache(aitexttonovelmod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []aitexttonovelmod.AiTextToNovel, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoListKey(models.AiTextToNovel+"-all").ResBind(&res).Cache(aitexttonovelmod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data aitexttonovelmod.AiTextToNovel) (primitive.ObjectID, error) {
|
||||
newID, err := aitexttonovelmod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.AiTextToNovel).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := aitexttonovelmod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.AiTextToNovel).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = aitexttonovelmod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.AiTextToNovel).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package aitexttonoveldata
|
||||
|
||||
import "91porn-server/models/v/aitexttonovelmod"
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []aitexttonovelmod.AiTextToNovel) (res []*aitexttonovelmod.AiTextToNovel) {
|
||||
res = make([]*aitexttonovelmod.AiTextToNovel, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item aitexttonovelmod.AiTextToNovel) (res *aitexttonovelmod.AiTextToNovel) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &aitexttonovelmod.AiTextToNovel{
|
||||
ID: item.ID,
|
||||
UID: item.UID,
|
||||
Description: item.Description,
|
||||
Content: item.Content,
|
||||
Status: item.Status,
|
||||
CharacterSetting: item.CharacterSetting,
|
||||
LocationScene: item.LocationScene,
|
||||
Details: item.Details,
|
||||
ModelType: item.ModelType,
|
||||
Coin: item.Coin,
|
||||
DebitAmountCoin: item.DebitAmountCoin,
|
||||
DebitIncomeCoin: item.DebitIncomeCoin,
|
||||
IsFreeTimes: item.IsFreeTimes,
|
||||
IsHide: item.IsHide,
|
||||
Remark: item.Remark,
|
||||
IsDelete: item.IsDelete,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package bannerjumpdata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/bannerjumpmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []bannerjumpmod.BannerJump
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache() (res []bannerjumpmod.BannerJump, err error) {
|
||||
t := time.Now()
|
||||
cond := bson.M{"enable": true, "startAt": bson.M{"$lte": t}, "endAt": bson.M{"$gt": t}}
|
||||
sort := bson.D{{"weight", -1}, {"createdAt", -1}}
|
||||
_, err = cachev2.Classes().CacheTime(8*time.Minute).AutoListKey(models.BannerJump+"-all").ResBind(&res).Cache(bannerjumpmod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data bannerjumpmod.BannerJump) (primitive.ObjectID, error) {
|
||||
newID, err := bannerjumpmod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.BannerJump).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := bannerjumpmod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.BannerJump).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = bannerjumpmod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.BannerJump).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package imgroupdata
|
||||
|
||||
import (
|
||||
"91porn-server/models/v/imgroupmod"
|
||||
)
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []imgroupmod.ImGroup) (res []*imgroupmod.ImGroupInfo) {
|
||||
res = make([]*imgroupmod.ImGroupInfo, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item imgroupmod.ImGroup) (res *imgroupmod.ImGroupInfo) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &imgroupmod.ImGroupInfo{
|
||||
ID: item.ID,
|
||||
GroupId: item.GroupId,
|
||||
Name: item.Name,
|
||||
Cover: item.Cover,
|
||||
Summary: item.Summary,
|
||||
MemberNum: item.MemberNum,
|
||||
FakeMemberNum: item.FakeMemberNum,
|
||||
Price: item.Price,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package imgroupdata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/imgroupmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []imgroupmod.ImGroup
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]imgroupmod.ImGroup, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.ImGroup).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = imgroupmod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res imgroupmod.ImGroup, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoInfoKey(models.ImGroup, id.Hex()).ResBind(&res).Cache(imgroupmod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []imgroupmod.ImGroup, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoListKey(models.ImGroup+"-all").ResBind(&res).Cache(imgroupmod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data imgroupmod.ImGroup) (primitive.ObjectID, error) {
|
||||
newID, err := imgroupmod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.ImGroup).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := imgroupmod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.ImGroup).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = imgroupmod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.ImGroup).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package imgroupmemberdata
|
||||
|
||||
import (
|
||||
"91porn-server/models/v/imgroupmembermod"
|
||||
)
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []imgroupmembermod.ImGroupMember) (res []*imgroupmembermod.ImGroupMemberInfo) {
|
||||
res = make([]*imgroupmembermod.ImGroupMemberInfo, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item imgroupmembermod.ImGroupMember) (res *imgroupmembermod.ImGroupMemberInfo) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &imgroupmembermod.ImGroupMemberInfo{
|
||||
ID: item.ID,
|
||||
Uid: item.Uid,
|
||||
Price: item.Price,
|
||||
CreatedAt: item.CreatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package imgroupmemberdata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/imgroupmembermod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []imgroupmembermod.ImGroupMember
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]imgroupmembermod.ImGroupMember, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.ImGroupMember).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = imgroupmembermod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res imgroupmembermod.ImGroupMember, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoInfoKey(models.ImGroupMember, id.Hex()).ResBind(&res).Cache(imgroupmembermod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []imgroupmembermod.ImGroupMember, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoListKey(models.ImGroupMember+"-all").ResBind(&res).Cache(imgroupmembermod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data imgroupmembermod.ImGroupMember) (primitive.ObjectID, error) {
|
||||
newID, err := imgroupmembermod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.ImGroupMember).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := imgroupmembermod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.ImGroupMember).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = imgroupmembermod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.ImGroupMember).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package immessagedata
|
||||
|
||||
import (
|
||||
"91porn-server/app/service/vidhelpser"
|
||||
"91porn-server/models/v/immessagemod"
|
||||
"91porn-server/models/v/vidmod"
|
||||
)
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []immessagemod.ImMessage) (res []*immessagemod.ImMessageInfo) {
|
||||
res = make([]*immessagemod.ImMessageInfo, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
// 获取用户数据
|
||||
uids := []uint64{}
|
||||
for _, item := range origin {
|
||||
uids = append(uids, item.Uid)
|
||||
}
|
||||
userMap := vidhelpser.GetSimpleUserMapNoUID(uids)
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item, userMap)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item immessagemod.ImMessage, userMap map[uint64]*vidmod.Publisher) (res *immessagemod.ImMessageInfo) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
// 组装返回数据
|
||||
res = &immessagemod.ImMessageInfo{
|
||||
ID: item.ID,
|
||||
GroupId: item.GroupId,
|
||||
Uid: item.Uid,
|
||||
Content: item.Content,
|
||||
Image: item.Image,
|
||||
CreatedAt: item.CreatedAt,
|
||||
}
|
||||
if userMap != nil {
|
||||
user, ok := userMap[item.Uid]
|
||||
if ok && user != nil {
|
||||
res.Name = user.Name
|
||||
res.Gender = user.Gender
|
||||
res.Portrait = user.Portrait
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package immessagedata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/immessagemod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []immessagemod.ImMessage
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]immessagemod.ImMessage, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.ImMessage).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = immessagemod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res immessagemod.ImMessage, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoInfoKey(models.ImMessage, id.Hex()).ResBind(&res).Cache(immessagemod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []immessagemod.ImMessage, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoListKey(models.ImMessage+"-all").ResBind(&res).Cache(immessagemod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data immessagemod.ImMessage) (primitive.ObjectID, error) {
|
||||
newID, err := immessagemod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.ImMessage).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := immessagemod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.ImMessage).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = immessagemod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.ImMessage).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
package mediabookshelfdata
|
||||
|
||||
import (
|
||||
"91porn-server/models/v/mediabookshelfmod"
|
||||
"91porn-server/models/v/mediamod"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AppData 需要组装返回的数据
|
||||
type AppData struct {
|
||||
BaseInfo *mediabookshelfmod.MediaBookshelfInfo `json:"baseInfo"` // 基础信息
|
||||
}
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []mediabookshelfmod.MediaBookshelf) (res []AppData) {
|
||||
res = make([]AppData, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item mediabookshelfmod.MediaBookshelf) (res AppData) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res.BaseInfo = &mediabookshelfmod.MediaBookshelfInfo{
|
||||
ID: item.ID,
|
||||
Name: item.Name,
|
||||
UID: item.UID,
|
||||
ReadAt: item.ReadAt,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdateTime: item.UpdateTime,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// AppSimpleData 仅返回基础数据
|
||||
type AppSimpleData *mediabookshelfmod.MediaBookshelfInfo
|
||||
|
||||
// FormatAppSimpleDataList 格式化app列表数据
|
||||
func FormatAppSimpleDataList(origin []mediabookshelfmod.MediaBookshelf, skip, limit int64, sort bson.D) (res []AppSimpleData) {
|
||||
res = make([]AppSimpleData, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var mids []primitive.ObjectID
|
||||
for i := range origin {
|
||||
mids = append(mids, origin[i].MID)
|
||||
}
|
||||
|
||||
filter := bson.M{"_id": bson.M{"$in": mids}}
|
||||
opts := options.Find().SetSkip(skip).SetLimit(limit)
|
||||
if len(sort) > 0 {
|
||||
opts = opts.SetSort(sort)
|
||||
}
|
||||
media, err := mediamod.QueryMediaByCond(filter, opts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
m := make(map[primitive.ObjectID]*mediamod.Media)
|
||||
for i := range media {
|
||||
m[media[i].ID] = media[i]
|
||||
}
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppSimpleData(item, m[item.MID])
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppSimpleData 格式化app数据
|
||||
func FormatAppSimpleData(item mediabookshelfmod.MediaBookshelf, media *mediamod.Media) (res AppSimpleData) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &mediabookshelfmod.MediaBookshelfInfo{
|
||||
ID: item.MID,
|
||||
//MID: item.MID,
|
||||
Name: media.Title,
|
||||
VerticalCover: media.VerticalCover,
|
||||
TotalEpisode: media.TotalEpisode,
|
||||
CurrentEpisode: media.CurrentEpisode,
|
||||
MediaType: media.MediaType,
|
||||
MediaSubType: int(media.MediaSubType),
|
||||
UpdateStatus: media.UpdateStatus,
|
||||
CountBrowse: media.CountBrowse,
|
||||
Permission: media.Permission,
|
||||
Price: media.Price,
|
||||
UID: item.UID,
|
||||
ReadAt: item.ReadAt,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdateTime: item.UpdateTime,
|
||||
}
|
||||
if time.Now().Add(-time.Hour*24*7).Unix() < media.ContentUpdateTime.Unix() {
|
||||
res.IsNew = true
|
||||
}
|
||||
return
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
package mediabookshelfdata
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/mediabookshelfmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
func getKey(uid uint64) string {
|
||||
return fmt.Sprintf("%s-%d", models.MediaBookshelf, uid)
|
||||
}
|
||||
|
||||
type ListRes struct {
|
||||
List []mediabookshelfmod.MediaBookshelf
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(uid uint64, cond bson.M, skip, limit int64, sort bson.D) ([]mediabookshelfmod.MediaBookshelf, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(getKey(uid)).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = mediabookshelfmod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
func GetInfoByCond(cond bson.M) (mediabookshelfmod.MediaBookshelf, error) {
|
||||
return mediabookshelfmod.GetInfoByCond(cond)
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, uid uint64, data mediabookshelfmod.MediaBookshelf) (primitive.ObjectID, error) {
|
||||
newID, err := mediabookshelfmod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(getKey(uid)).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := mediabookshelfmod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.MediaBookshelf).AutoClear(true, nil)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteDataByCond 删除数据
|
||||
func DeleteDataByCond(t *db.MongoTool, uid uint64, cond bson.M) (err error) {
|
||||
err = mediabookshelfmod.DeleteByCond(t, cond)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(getKey(uid)).AutoClear(true, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteDataByIds 删除数据
|
||||
func DeleteDataByIds(t *db.MongoTool, uid uint64, ids []primitive.ObjectID) (err error) {
|
||||
err = mediabookshelfmod.DeleteByIDS(t, uid, ids)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(getKey(uid)).AutoClear(true, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = mediabookshelfmod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.MediaBookshelf).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package mediacontentdata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/mediacontentmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []mediacontentmod.MediaContent
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]mediacontentmod.MediaContent, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.MediaContent).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = mediacontentmod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res mediacontentmod.MediaContent, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(10*time.Minute).AutoInfoKey(models.MediaContent, id.Hex()).ResBind(&res).Cache(mediacontentmod.GetInfo, id, true)
|
||||
return
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package mediadata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/mediamod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []*mediamod.Media
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]*mediamod.Media, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.Media).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.HasNext, err = mediamod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res mediamod.Media, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(5*time.Minute).AutoInfoKey(models.Media, id.Hex()).ResBind(&res).Cache(mediamod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
package mediatagdata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/mediatagmod"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []mediatagmod.MediaTag
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetTagIdsByNameFromCache 通过名字获取标签id
|
||||
func GetTagIdsByNameFromCache(name string) (ids []primitive.ObjectID, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(300*time.Second).AutoListKey(models.MediaTag).ResBind(&ids).Cache(mediatagmod.FindTagIdsByName, name)
|
||||
return
|
||||
}
|
||||
|
||||
// GetTagByNameFromCache 通过名字获取标签id
|
||||
func GetTagByNameFromCache(name string) (tag mediatagmod.MediaTag, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(300*time.Second).AutoListKey(models.MediaTag).ResBind(&tag).Cache(mediatagmod.FindOneTagByName, name)
|
||||
return tag, err
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]mediatagmod.MediaTag, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(3600*time.Second).AutoListKey(models.MediaTag).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = mediatagmod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res mediatagmod.MediaTag, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(7200*time.Second).AutoInfoKey(models.MediaTag, id.Hex()).ResBind(&res).Cache(mediatagmod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data mediatagmod.MediaTag) (primitive.ObjectID, error) {
|
||||
newID, err := mediatagmod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.MediaTag).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := mediatagmod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.MediaTag).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = mediatagmod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.MediaTag).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package mediatagdimensiondata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/mediatagdimensionmod"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []mediatagdimensionmod.MediaTagDimension
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]mediatagdimensionmod.MediaTagDimension, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(3600*time.Second).AutoListKey(models.MediaTagDimension).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = mediatagdimensionmod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res mediatagdimensionmod.MediaTagDimension, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(7200*time.Second).AutoInfoKey(models.MediaTagDimension, id.Hex()).ResBind(&res).Cache(mediatagdimensionmod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data mediatagdimensionmod.MediaTagDimension) (primitive.ObjectID, error) {
|
||||
newID, err := mediatagdimensionmod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.MediaTagDimension).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := mediatagdimensionmod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.MediaTagDimension).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = mediatagdimensionmod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.MediaTagDimension).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package nakedchatdata
|
||||
|
||||
import (
|
||||
"91porn-server/models/v/nakedchatmod"
|
||||
)
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []nakedchatmod.NakedChat) (res []*nakedchatmod.NakedChatSimple) {
|
||||
res = make([]*nakedchatmod.NakedChatSimple, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppSimpleData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppSimpleData 格式化app数据
|
||||
func FormatAppSimpleData(item nakedchatmod.NakedChat) (res *nakedchatmod.NakedChatSimple) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &nakedchatmod.NakedChatSimple{
|
||||
ID: item.ID,
|
||||
Title: item.Title,
|
||||
Cover: item.Cover,
|
||||
Price: item.Price,
|
||||
Age: item.Age,
|
||||
Weight: item.Weight,
|
||||
Height: item.Height,
|
||||
Cup: item.Cup,
|
||||
SaleNum: item.SaleNum + item.FakeSaleNum,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item nakedchatmod.NakedChat) (res *nakedchatmod.NakedChatInfo) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &nakedchatmod.NakedChatInfo{
|
||||
ID: item.ID,
|
||||
Title: item.Title,
|
||||
Cover: item.Cover,
|
||||
Price: item.Price,
|
||||
Options: item.Options,
|
||||
Images: item.Images,
|
||||
Video: item.Video,
|
||||
Contact: item.Contact,
|
||||
Age: item.Age,
|
||||
Weight: item.Weight,
|
||||
Height: item.Height,
|
||||
Cup: item.Cup,
|
||||
SaleNum: item.SaleNum + item.FakeSaleNum,
|
||||
BusinessHours: item.BusinessHours,
|
||||
Summary: item.Summary,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package nakedchatdata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/nakedchatmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []nakedchatmod.NakedChat
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]nakedchatmod.NakedChat, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.NakedChat).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = nakedchatmod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res nakedchatmod.NakedChat, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoInfoKey(models.NakedChat, id.Hex()).ResBind(&res).Cache(nakedchatmod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []nakedchatmod.NakedChat, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoListKey(models.NakedChat+"-all").ResBind(&res).Cache(nakedchatmod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data nakedchatmod.NakedChat) (primitive.ObjectID, error) {
|
||||
newID, err := nakedchatmod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.NakedChat).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := nakedchatmod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.NakedChat).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = nakedchatmod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.NakedChat).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package nakedchatorderdata
|
||||
|
||||
import (
|
||||
"91porn-server/models/v/nakedchatordermod"
|
||||
)
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []nakedchatordermod.NakedChatOrder) (res []*nakedchatordermod.NakedChatOrderInfo) {
|
||||
res = make([]*nakedchatordermod.NakedChatOrderInfo, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item nakedchatordermod.NakedChatOrder) (res *nakedchatordermod.NakedChatOrderInfo) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &nakedchatordermod.NakedChatOrderInfo{
|
||||
ID: item.ID,
|
||||
Nid: item.Nid,
|
||||
Uid: item.Uid,
|
||||
UserContact: item.UserContact,
|
||||
Num: item.Num,
|
||||
Price: item.Price,
|
||||
Amount: item.Amount,
|
||||
Remark: item.Remark,
|
||||
Status: item.Status,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package nakedchatorderdata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/nakedchatordermod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []nakedchatordermod.NakedChatOrder
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]nakedchatordermod.NakedChatOrder, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.NakedChatOrder).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = nakedchatordermod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res nakedchatordermod.NakedChatOrder, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoInfoKey(models.NakedChatOrder, id.Hex()).ResBind(&res).Cache(nakedchatordermod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []nakedchatordermod.NakedChatOrder, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoListKey(models.NakedChatOrder+"-all").ResBind(&res).Cache(nakedchatordermod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data nakedchatordermod.NakedChatOrder) (primitive.ObjectID, error) {
|
||||
newID, err := nakedchatordermod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.NakedChatOrder).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := nakedchatordermod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.NakedChatOrder).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = nakedchatordermod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.NakedChatOrder).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package quicksearchdata
|
||||
|
||||
import (
|
||||
"91porn-server/models/v/quicksearchmod"
|
||||
)
|
||||
|
||||
// AppData 需要组装返回的数据
|
||||
type AppData struct {
|
||||
BaseInfo *quicksearchmod.QuickSearchInfo `json:"baseInfo"` // 基础信息
|
||||
}
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []quicksearchmod.QuickSearch) (res []AppData) {
|
||||
res = make([]AppData, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item quicksearchmod.QuickSearch) (res AppData) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res.BaseInfo = &quicksearchmod.QuickSearchInfo{
|
||||
ID: item.ID,
|
||||
Enabled: item.Enabled,
|
||||
Title: item.Title,
|
||||
SearchKeyword: item.SearchKeyword,
|
||||
Link: item.Link,
|
||||
Type: item.Type,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// AppSimpleData 仅返回基础数据
|
||||
type AppSimpleData *quicksearchmod.QuickSearchInfo
|
||||
|
||||
// FormatAppSimpleDataList 格式化app列表数据
|
||||
func FormatAppSimpleDataList(origin []quicksearchmod.QuickSearch) (res []AppSimpleData) {
|
||||
res = make([]AppSimpleData, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppSimpleData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppSimpleData 格式化app数据
|
||||
func FormatAppSimpleData(item quicksearchmod.QuickSearch) (res AppSimpleData) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &quicksearchmod.QuickSearchInfo{
|
||||
ID: item.ID,
|
||||
Enabled: item.Enabled,
|
||||
Title: item.Title,
|
||||
SearchKeyword: item.SearchKeyword,
|
||||
Link: item.Link,
|
||||
Type: item.Type,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package quicksearchdata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/quicksearchmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []quicksearchmod.QuickSearch
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]quicksearchmod.QuickSearch, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.QuickSearch).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = quicksearchmod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res quicksearchmod.QuickSearch, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoInfoKey(models.QuickSearch, id.Hex()).ResBind(&res).Cache(quicksearchmod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M) (res []quicksearchmod.QuickSearch, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(3*time.Minute).AutoListKey(models.QuickSearch+"-all").ResBind(&res).Cache(quicksearchmod.GetAll, cond)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data quicksearchmod.QuickSearch) (primitive.ObjectID, error) {
|
||||
newID, err := quicksearchmod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.QuickSearch).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := quicksearchmod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.QuickSearch).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = quicksearchmod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.QuickSearch).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package signrecorddata
|
||||
|
||||
import (
|
||||
"91porn-server/models/v/signrecordmod"
|
||||
)
|
||||
|
||||
// AppData 需要组装返回的数据
|
||||
type AppData struct {
|
||||
BaseInfo *signrecordmod.SignRecordInfo `json:"baseInfo"` // 基础信息
|
||||
}
|
||||
|
||||
// FormatAppDataList 格式化app列表数据
|
||||
func FormatAppDataList(origin []signrecordmod.SignRecord) (res []AppData) {
|
||||
res = make([]AppData, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppData 格式化app数据
|
||||
func FormatAppData(item signrecordmod.SignRecord) (res AppData) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res.BaseInfo = &signrecordmod.SignRecordInfo{
|
||||
ID: item.ID,
|
||||
PID: item.PID,
|
||||
UID: item.UID,
|
||||
TotalDays: item.TotalDays,
|
||||
CurrentSignDays: item.CurrentSignDays,
|
||||
ForgetSignDays: item.ForgetSignDays,
|
||||
RenewalSignDays: item.RenewalSignDays,
|
||||
SignTime: item.SignTime,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdateTime: item.UpdateTime,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// AppSimpleData 仅返回基础数据
|
||||
type AppSimpleData *signrecordmod.SignRecordInfo
|
||||
|
||||
// FormatAppSimpleDataList 格式化app列表数据
|
||||
func FormatAppSimpleDataList(origin []signrecordmod.SignRecord) (res []AppSimpleData) {
|
||||
res = make([]AppSimpleData, len(origin))
|
||||
if len(origin) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
for i, item := range origin {
|
||||
res[i] = FormatAppSimpleData(item)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FormatAppSimpleData 格式化app数据
|
||||
func FormatAppSimpleData(item signrecordmod.SignRecord) (res AppSimpleData) {
|
||||
if item.ID.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// 组装返回数据
|
||||
res = &signrecordmod.SignRecordInfo{
|
||||
ID: item.ID,
|
||||
PID: item.PID,
|
||||
UID: item.UID,
|
||||
TotalDays: item.TotalDays,
|
||||
CurrentSignDays: item.CurrentSignDays,
|
||||
ForgetSignDays: item.ForgetSignDays,
|
||||
RenewalSignDays: item.RenewalSignDays,
|
||||
SignTime: item.SignTime,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdateTime: item.UpdateTime,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package signrecorddata
|
||||
|
||||
import (
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/signrecordmod"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []signrecordmod.SignRecord
|
||||
Count int64
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
// GetListFromCache 从缓存获取列表数据
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]signrecordmod.SignRecord, int64, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.SignRecord).ResBind(&data).Cache(GetListData, cond, skip, limit, sort)
|
||||
return data.List, data.Count, data.HasNext, err
|
||||
}
|
||||
|
||||
// GetListData 获取列表数据并组装适合缓存格式返回
|
||||
func GetListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
res.List, res.Count, res.HasNext, err = signrecordmod.GetList(cond, skip, limit, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res signrecordmod.SignRecord, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoInfoKey(models.SignRecord, id.Hex()).ResBind(&res).Cache(signrecordmod.GetInfo, id)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFromCache 获取所有数据
|
||||
func GetAllFromCache(cond bson.M, sort bson.D) (res []signrecordmod.SignRecord, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoListKey(models.SignRecord+"-all").ResBind(&res).Cache(signrecordmod.GetAll, cond, sort)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data signrecordmod.SignRecord) (primitive.ObjectID, error) {
|
||||
newID, err := signrecordmod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
_, err = cachev2.Classes().Table(models.SignRecord).AutoClear(true, nil)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := signrecordmod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
_, _ = cachev2.Classes().Table(models.SignRecord).AutoClear(true, &id)
|
||||
|
||||
return affect, err
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = signrecordmod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
all := "*"
|
||||
_, _ = cachev2.Classes().Table(models.SignRecord).AutoClear(true, &all)
|
||||
return
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
package sysconfdata
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/localcache"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/sysconfmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// GetIntsFromSharedCache reads integer settings from the shared cache without
|
||||
// the process-local one-minute layer, so management changes take effect at once.
|
||||
func GetIntsFromSharedCache(defaults map[sysconfmod.VCode]int) (map[sysconfmod.VCode]int, error) {
|
||||
configure, err := getAllFromSharedCache()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values := make(map[sysconfmod.VCode]int, len(defaults))
|
||||
for code, fallback := range defaults {
|
||||
values[code] = fallback
|
||||
if raw, ok := configure[string(code)]; ok {
|
||||
if parsed, parseErr := strconv.Atoi(raw); parseErr == nil {
|
||||
values[code] = parsed
|
||||
}
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
const (
|
||||
tmpLocalCacheKey = "AllSysConfTmpKey"
|
||||
// DefaultTotalWatchCount preserves the legacy free-trial behavior when the
|
||||
// shared configuration is absent or temporarily unavailable.
|
||||
DefaultTotalWatchCount uint64 = 3
|
||||
)
|
||||
|
||||
// GetAllFromCache 获取全部配置项
|
||||
func GetAllFromCache() (res sysconfmod.ConfMap, err error) {
|
||||
// 频繁访问 从本地进程内缓存中获取,对象不存在则从redis中获取
|
||||
r, _ := localcache.C.Get(tmpLocalCacheKey)
|
||||
if r != nil {
|
||||
return r.(sysconfmod.ConfMap), nil
|
||||
}
|
||||
defer func() {
|
||||
localcache.C.Set(tmpLocalCacheKey, res, 1*time.Minute)
|
||||
}()
|
||||
return getAllFromSharedCache()
|
||||
}
|
||||
|
||||
// GetTotalWatchCount returns the configured non-VIP free-trial count from the
|
||||
// existing bounded configuration cache and falls back to the legacy default.
|
||||
func GetTotalWatchCount() uint64 {
|
||||
configure, err := GetAllFromCache()
|
||||
if err != nil {
|
||||
return DefaultTotalWatchCount
|
||||
}
|
||||
return totalWatchCount(configure)
|
||||
}
|
||||
|
||||
func totalWatchCount(configure sysconfmod.ConfMap) uint64 {
|
||||
raw, ok := configure[string(sysconfmod.VCodeTotalWatchCount)]
|
||||
if !ok {
|
||||
return DefaultTotalWatchCount
|
||||
}
|
||||
value, err := strconv.ParseUint(raw, 10, 64)
|
||||
if err != nil {
|
||||
return DefaultTotalWatchCount
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func getAllFromSharedCache() (res sysconfmod.ConfMap, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(5 * time.Minute).AutoListKey(models.SysConf).ResBind(&res).Cache(sysconfmod.GetAllConfig)
|
||||
return
|
||||
}
|
||||
|
||||
// GetBoolFromSharedCache 绕过进程内缓存读取布尔配置,后台修改并清理 Redis 后可立即生效。
|
||||
func GetBoolFromSharedCache(code sysconfmod.VCode) (bool, error) {
|
||||
values, err := GetBoolsFromSharedCache(code)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return values[code], nil
|
||||
}
|
||||
|
||||
// GetBoolsFromSharedCache reads several switches from one shared-cache
|
||||
// snapshot. This keeps request paths that need related switches from fetching
|
||||
// and decoding the same configuration map repeatedly.
|
||||
func GetBoolsFromSharedCache(codes ...sysconfmod.VCode) (map[sysconfmod.VCode]bool, error) {
|
||||
configure, err := getAllFromSharedCache()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values := make(map[sysconfmod.VCode]bool, len(codes))
|
||||
for _, code := range codes {
|
||||
if _, exists := configure[string(code)]; !exists {
|
||||
continue
|
||||
}
|
||||
values[code] = configure.GetBool(code)
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func clearAllCache() error {
|
||||
localcache.C.Delete(tmpLocalCacheKey)
|
||||
_, err := cachev2.Classes().AutoListKey(models.SysConf).DeleteCurrent()
|
||||
return err
|
||||
}
|
||||
|
||||
// GetByGpCodeFromCache 获取分组配置数据
|
||||
func GetByGpCodeFromCache(code sysconfmod.GPCode) (res sysconfmod.ConfMap, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(30*time.Minute).AutoListKey(models.SysConf).ResBind(&res).Cache(sysconfmod.GetByGpCode, code)
|
||||
return
|
||||
}
|
||||
|
||||
// InsertData 插入数据
|
||||
func InsertData(t *db.MongoTool, data sysconfmod.SysConf) (primitive.ObjectID, error) {
|
||||
newID, err := sysconfmod.Insert(t, data)
|
||||
if err != nil {
|
||||
return newID, err
|
||||
}
|
||||
// 清除缓存数据
|
||||
if err = clearAllCache(); err != nil {
|
||||
return newID, err
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
// UpdateData 更新数据
|
||||
func UpdateData(t *db.MongoTool, id string, data map[string]interface{}) (int64, error) {
|
||||
objID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
affect, err := sysconfmod.UpdateByID(t, objID, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err = clearAllCache(); err != nil {
|
||||
return affect, err
|
||||
}
|
||||
return affect, nil
|
||||
}
|
||||
|
||||
// DeleteData 删除数据
|
||||
func DeleteData(t *db.MongoTool, id primitive.ObjectID) (err error) {
|
||||
err = sysconfmod.DeleteByID(t, id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
return clearAllCache()
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package sysconfdata
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"91porn-server/models/v/sysconfmod"
|
||||
)
|
||||
|
||||
func TestTotalWatchCount(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config sysconfmod.ConfMap
|
||||
want uint64
|
||||
}{
|
||||
{name: "configured", config: sysconfmod.ConfMap{string(sysconfmod.VCodeTotalWatchCount): "5"}, want: 5},
|
||||
{name: "zero is allowed", config: sysconfmod.ConfMap{string(sysconfmod.VCodeTotalWatchCount): "0"}, want: 0},
|
||||
{name: "missing", config: sysconfmod.ConfMap{}, want: DefaultTotalWatchCount},
|
||||
{name: "invalid", config: sysconfmod.ConfMap{string(sysconfmod.VCodeTotalWatchCount): "invalid"}, want: DefaultTotalWatchCount},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := totalWatchCount(tt.config); got != tt.want {
|
||||
t.Fatalf("totalWatchCount() = %d, want %d", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package viddata
|
||||
|
||||
import (
|
||||
"91porn-server/common/cachev2"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/vidmod"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
type ListRes struct {
|
||||
List []*vidmod.VideoModel
|
||||
HasNext bool
|
||||
}
|
||||
|
||||
func GetListFromCache(cond bson.M, skip, limit int64, sort bson.D) ([]*vidmod.VideoModel, bool, error) {
|
||||
var data ListRes
|
||||
_, err := cachev2.Classes().CacheTime(10*time.Minute).AutoListKey(models.VideoInfo).ResBind(&data).Cache(getListData, cond, skip, limit, sort)
|
||||
return data.List, data.HasNext, err
|
||||
}
|
||||
|
||||
// getListData 获取列表数据并组装适合缓存格式返回
|
||||
func getListData(cond bson.M, skip, limit int64, sort bson.D) (res ListRes, err error) {
|
||||
opt := options.Find().SetLimit(limit).SetSkip(skip).SetSort(sort)
|
||||
res.List, res.HasNext, err = vidmod.FindList(cond, opt)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInfoFromCache 获取数据详情
|
||||
func GetInfoFromCache(id primitive.ObjectID) (res vidmod.VideoModel, err error) {
|
||||
_, err = cachev2.Classes().CacheTime(5*time.Minute).AutoInfoKey(models.VideoInfo, id.Hex()).ResBind(&res).Cache(vidmod.GetVideoInfo, id.Hex())
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package commod
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"91porn-server/common/stderr"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
// Page 客户端传低过来的分页信息 对外暴露
|
||||
type Page struct {
|
||||
PageNumber uint64 `form:"pageNumber" json:"pageNumber" binding:"required,min=1"` // 当前页
|
||||
PageSize uint64 `form:"pageSize" json:"pageSize" binding:"required,min=1,max=100"` // 每页条数
|
||||
Sort []Sorts `form:"sort" json:"sort"`
|
||||
}
|
||||
|
||||
type Sorts struct {
|
||||
SortKey string `json:"sortKey"`
|
||||
SortVal int `json:"sortVal"`
|
||||
}
|
||||
|
||||
func (p Page) Skip() uint64 {
|
||||
return (p.PageNumber - 1) * p.PageSize
|
||||
}
|
||||
|
||||
func (p Page) Skip64() int64 {
|
||||
return int64((p.PageNumber - 1) * p.PageSize)
|
||||
}
|
||||
|
||||
func (p Page) Limit64() int64 {
|
||||
return int64(p.PageSize)
|
||||
}
|
||||
|
||||
func (p Page) Limit() uint64 {
|
||||
return p.PageSize
|
||||
}
|
||||
|
||||
// 注意:Page.Sort内元素顺序决定排序顺序
|
||||
func (p Page) GetSort() bson.D {
|
||||
sorts := make(bson.D, len(p.Sort))
|
||||
for i, v := range p.Sort {
|
||||
sorts[i] = bson.E{Key: v.SortKey, Value: v.SortVal}
|
||||
}
|
||||
return sorts
|
||||
}
|
||||
|
||||
// Sig 签名结构体
|
||||
type Sig struct {
|
||||
AccessKey string `form:"accessKey" json:"accessKey" binding:"required"`
|
||||
BucketName string `form:"bucketName" json:"bucketName" binding:"required"`
|
||||
}
|
||||
|
||||
// Resp 返回结构体
|
||||
type Resp struct {
|
||||
Code stderr.Code `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
// ListResp 分页列表 公共返回结构体
|
||||
type ListResp struct {
|
||||
Total int64 `json:"total"`
|
||||
HasNext bool `json:"hasNext"`
|
||||
List interface{} `json:"list"`
|
||||
}
|
||||
|
||||
// Page 客户端传低过来的分页信息 内部使用
|
||||
type PageBy struct {
|
||||
CheckNext bool
|
||||
Num uint64
|
||||
Size uint64
|
||||
}
|
||||
|
||||
// OrderBy 排序
|
||||
type OrderBy struct {
|
||||
Key string // 排序的字段
|
||||
Desc bool // 排序方式 是否倒序
|
||||
}
|
||||
|
||||
// StdQuery 客户端传过来的时间条件信息
|
||||
type StdQuery struct {
|
||||
Page *PageBy
|
||||
Order *[]OrderBy
|
||||
}
|
||||
|
||||
// ConvertToListQuery 分页列表 通用条件查询条件组装
|
||||
func ConvertToListQuery(s StdQuery) (opts *options.FindOptions) {
|
||||
opts = &options.FindOptions{}
|
||||
if s.Page != nil {
|
||||
skip := int64((s.Page.Num - 1) * s.Page.Size)
|
||||
limit := int64(s.Page.Size)
|
||||
if s.Page.CheckNext {
|
||||
limit++
|
||||
}
|
||||
opts.Skip = &skip
|
||||
opts.Limit = &limit
|
||||
}
|
||||
if s.Order != nil && len(*s.Order) > 0 {
|
||||
sort := bson.D{}
|
||||
for _, v := range *s.Order {
|
||||
e := bson.E{}
|
||||
if v.Desc {
|
||||
e.Key = v.Key
|
||||
e.Value = -1
|
||||
|
||||
} else {
|
||||
e.Key = v.Key
|
||||
e.Value = 1
|
||||
}
|
||||
sort = append(sort, e)
|
||||
}
|
||||
opts.Sort = sort
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// StructToMap2 对象转map,去掉无效值
|
||||
func StructToMap3(u interface{}) map[string]interface{} {
|
||||
t := reflect.TypeOf(u)
|
||||
v := reflect.ValueOf(u)
|
||||
m := make(map[string]interface{})
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
fv := v.Field(i).Type()
|
||||
vv := v.Field(i)
|
||||
k, _ := t.Field(i).Tag.Lookup("bson")
|
||||
switch fv.Kind() {
|
||||
case reflect.String:
|
||||
if vv.String() != "" {
|
||||
if k == "_id" {
|
||||
idv, _ := primitive.ObjectIDFromHex(vv.String())
|
||||
m["_id"] = idv
|
||||
|
||||
} else {
|
||||
m[k] = vv.String()
|
||||
}
|
||||
}
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
if vv.Int() != 0 {
|
||||
m[k] = vv.Interface()
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
if vv.Uint() != 0 {
|
||||
m[k] = vv.Interface()
|
||||
}
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
if vv.Interface() != nil {
|
||||
m[k] = vv.Interface()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return m
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package commod
|
||||
|
||||
const (
|
||||
LouFengCostNotify = "LouFengCostNotify:%d" //用户楼凤消费通知
|
||||
GameRechargePoliteNotify = "GameRechargePoliteNotify:%d" //用户游戏充值有礼通知
|
||||
)
|
||||
|
||||
// SystemConfigType 系统配置类型
|
||||
type SystemConfigType int
|
||||
|
||||
const (
|
||||
NudeChatSpecialArea SystemConfigType = iota // 裸聊专区
|
||||
)
|
||||
|
||||
// SystemLocationCode 系统位置编号
|
||||
type SystemLocationCode int
|
||||
|
||||
const (
|
||||
OfficialBulletin SystemLocationCode = iota // 官方公告
|
||||
)
|
||||
|
||||
// BuyType 充值购买类型
|
||||
type BuyType int
|
||||
|
||||
const (
|
||||
BuyGold BuyType = iota + 1 // 购买金币
|
||||
BuyGameCoin // 购买游戏币
|
||||
BuyFruitCoin // 购买果币
|
||||
BuyProduct // 购买商品
|
||||
//BuyNudeChatService // 购买裸聊服务
|
||||
)
|
||||
|
||||
type AdGroup string
|
||||
|
||||
const (
|
||||
AdGroupNone AdGroup = "" // 无组
|
||||
AdGroupA AdGroup = "A" // A组
|
||||
AdGroupB AdGroup = "B" // B组
|
||||
AdGroupC AdGroup = "C" // C组
|
||||
)
|
||||
|
||||
func (ag AdGroup) InABC() bool {
|
||||
return ag == AdGroupA || ag == AdGroupB || ag == AdGroupC
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package commod
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
// 扣量类型
|
||||
type DeductType int
|
||||
|
||||
const (
|
||||
NotDed DeductType = iota
|
||||
)
|
||||
|
||||
const (
|
||||
DedConsume DeductType = 1 << iota
|
||||
DedNewUser
|
||||
DedBooker
|
||||
DedRecharge
|
||||
)
|
||||
|
||||
func (d DeductType) Has(t DeductType) bool {
|
||||
return int(t)&int(d) == int(t)
|
||||
}
|
||||
|
||||
// BitSet 位集合
|
||||
func (d DeductType) BitSet() []int {
|
||||
return []int{int(math.Log2(float64(d)))}
|
||||
}
|
||||
|
||||
func (d DeductType) String() string {
|
||||
switch d {
|
||||
case DedConsume:
|
||||
return "dedConsume"
|
||||
case DedNewUser:
|
||||
return "dedNewUser"
|
||||
case DedBooker:
|
||||
return "dedBooker"
|
||||
case DedConsume | DedNewUser:
|
||||
return "dedConsumeAndNewUser"
|
||||
default:
|
||||
return "unknow"
|
||||
}
|
||||
}
|
||||
|
||||
func ToDeductType(v int) (DeductType, error) {
|
||||
all := DedConsume | DedNewUser | DedBooker
|
||||
if all.Has(DeductType(v)) {
|
||||
return DeductType(v), nil
|
||||
}
|
||||
return NotDed, errors.New(NotDed.String())
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package commod
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/pageopt"
|
||||
)
|
||||
|
||||
type DiscSeqe struct {
|
||||
DistrictCode string `json:"districtCode" bson:"districtCode"` //商区码
|
||||
PromSeqe string `json:"promSeqe" bson:"promSeqe"` //推广序列
|
||||
}
|
||||
|
||||
func (d *DiscSeqe) String() string {
|
||||
if d.PromSeqe == "" {
|
||||
return d.DistrictCode
|
||||
}
|
||||
return strings.ToUpper(strings.Join([]string{d.DistrictCode, d.PromSeqe}, "-"))
|
||||
}
|
||||
|
||||
func (p *DiscSeqe) From(s string) *DiscSeqe {
|
||||
p.Clean()
|
||||
list := strings.Split(s, "-")
|
||||
if len(list) > 0 {
|
||||
p.DistrictCode = list[0]
|
||||
}
|
||||
if len(list) > 1 {
|
||||
p.PromSeqe = list[1]
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *DiscSeqe) Clean() {
|
||||
p.DistrictCode = ""
|
||||
p.PromSeqe = ""
|
||||
}
|
||||
|
||||
type DiscDoc struct {
|
||||
//商区码和推广序列
|
||||
DiscSeqe `bson:",inline"`
|
||||
//true:是直推用户
|
||||
IsDirect bool `json:"isDirect" bson:"isDirect"`
|
||||
//商区绑定时间
|
||||
DiscBindAt time.Time `bson:"discBindAt"`
|
||||
}
|
||||
|
||||
func NewDiscDoc(discSeqe DiscSeqe, isDirect bool, discBindAt time.Time) DiscDoc {
|
||||
return DiscDoc{
|
||||
discSeqe,
|
||||
isDirect, //直推:推广链接没有推广码, 否则是分裂,
|
||||
discBindAt,
|
||||
}
|
||||
}
|
||||
|
||||
type Matcher = pageopt.Matcher
|
||||
|
||||
// IsDirectMatch
|
||||
type IsDirectMatch struct {
|
||||
IsDirect *bool
|
||||
}
|
||||
|
||||
func (b *IsDirectMatch) New() Matcher {
|
||||
return pageopt.NewAssignMatch("isDirect", b.IsDirect)
|
||||
}
|
||||
|
||||
// DistrictCodeMatch
|
||||
type DistrictCodeMatch struct {
|
||||
DistrictCode *string
|
||||
}
|
||||
|
||||
func (s *DistrictCodeMatch) New() Matcher {
|
||||
return pageopt.NewAssignMatch("districtCode", s.DistrictCode)
|
||||
}
|
||||
|
||||
// DistrictCodeInMatch
|
||||
type DistrictCodeInMatch struct {
|
||||
Codes []string
|
||||
}
|
||||
|
||||
func (s *DistrictCodeInMatch) New() Matcher {
|
||||
return pageopt.NewInMatch("districtCode", s.Codes)
|
||||
}
|
||||
|
||||
// DiscBindAtGTEAndLTMatch
|
||||
type DiscBindAtGTEAndLTMatch struct {
|
||||
GTE *time.Time
|
||||
LT *time.Time
|
||||
}
|
||||
|
||||
func (c *DiscBindAtGTEAndLTMatch) New() Matcher {
|
||||
return pageopt.NewGTEAndLTMatch("discBindAt", c.GTE, c.LT)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package commod
|
||||
|
||||
import "91porn-server/common/constant"
|
||||
|
||||
type ButtonProp struct {
|
||||
Style constant.SwitchStyle `form:"style" json:"style" bson:"style"` //开关样式
|
||||
Enable bool `form:"enable" json:"enable" bson:"enable"` //true:显示按钮
|
||||
}
|
||||
|
||||
type LdyButton struct {
|
||||
Name string `form:"name" json:"name" bson:"name"` //开关名
|
||||
Type constant.SwitchAct `form:"type" json:"type" bson:"type"` //开关类型
|
||||
ButtonProp `bson:",inline"`
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package commod
|
||||
|
||||
type ProductType int
|
||||
|
||||
const (
|
||||
VIP ProductType = 0 // product 0
|
||||
VIDEO ProductType = 1 // VIDEO视频1
|
||||
MODEL ProductType = 2 // MODEL嫩模2
|
||||
MeetingCard ProductType = 3 // 约会卡 3
|
||||
GAME ProductType = 4 // 游戏币 4
|
||||
NEWUSERCard ProductType = 5 // 新手卡 5
|
||||
PhysicalGoods ProductType = 6 // 实体商品 6
|
||||
AudioBook ProductType = 8 // 语音小说 8
|
||||
VideoDiscount ProductType = 13 // 视频折扣卡 13
|
||||
VideoFreeCard ProductType = 14 // 视频免费卡 14
|
||||
CoinMonthCard ProductType = 18 // 金币月卡 18
|
||||
Media ProductType = 19 // 动漫整本 19
|
||||
AdvanceCard ProductType = 21 // 预售卡 21
|
||||
GameAdvanceCard ProductType = 22 // 游戏预售卡 22
|
||||
WhoringCard ProductType = 24 // 白嫖卡 24
|
||||
ImGroup ProductType = 101 // 加入群 101
|
||||
NakedChat ProductType = 102 // 裸聊 102
|
||||
)
|
||||
const OTHER = 20 //OTHER 20
|
||||
|
||||
// CurrencyType 货币类型
|
||||
type CurrencyType int
|
||||
|
||||
const (
|
||||
Gold CurrencyType = iota + 1 // 金币
|
||||
GameCoin // 游戏币
|
||||
FruitCoin // 果币
|
||||
AiMateCoin // AI伴侣币
|
||||
)
|
||||
@@ -0,0 +1,65 @@
|
||||
package commod
|
||||
|
||||
type SortType int
|
||||
|
||||
// 1、最新,2、最热/推荐,3、最多播放,4、十分钟以上视频, 5、精华/精选,6、视频 7-最多收藏 8、解锁次数 9、最新热评
|
||||
const (
|
||||
New SortType = 1 // 最新上架
|
||||
MostHot SortType = 2 // 热门推荐
|
||||
MostWatch SortType = 3 // 最多观看
|
||||
MostCollect SortType = 7 // 最多收藏
|
||||
HotComment SortType = 9 // 最新热评
|
||||
)
|
||||
|
||||
var nameMap = map[SortType]string{
|
||||
New: "最新上架",
|
||||
MostHot: "热门推荐",
|
||||
MostWatch: "最多观看",
|
||||
HotComment: "最新热评",
|
||||
MostCollect: "最多收藏",
|
||||
}
|
||||
|
||||
func (s SortType) Name() string {
|
||||
name, ok := nameMap[s]
|
||||
if !ok {
|
||||
return "未知排序"
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func (s SortType) Item() SortItemData {
|
||||
item := SortItemData{
|
||||
Value: s,
|
||||
Name: "未知排序",
|
||||
}
|
||||
name, ok := nameMap[s]
|
||||
if !ok {
|
||||
return item
|
||||
}
|
||||
item.Name = name
|
||||
return item
|
||||
}
|
||||
|
||||
type SortItemData struct {
|
||||
Value SortType `json:"value"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// WebSortRules 后台支持修改的排序规则
|
||||
var WebSortRules = map[string][]SortItemData{
|
||||
"acgSort": {
|
||||
New.Item(),
|
||||
MostHot.Item(),
|
||||
MostWatch.Item(),
|
||||
MostCollect.Item(),
|
||||
HotComment.Item(),
|
||||
},
|
||||
"videoSort": {
|
||||
New.Item(),
|
||||
MostHot.Item(),
|
||||
MostWatch.Item(),
|
||||
MostCollect.Item(),
|
||||
HotComment.Item(),
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package commod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
//统计中心Model
|
||||
|
||||
type KFKTopic string
|
||||
|
||||
const (
|
||||
KFK_APPID int32 = 204 // 205:91PORN
|
||||
KFK_APP_NAME = "91PORN" // app名字
|
||||
USER_REG KFKTopic = "user_register" // 用户注册
|
||||
USER_RECH KFKTopic = "user_recharge" // 用户充值
|
||||
USER_RECH_ALL KFKTopic = "user_recharge_all" // 全部订单
|
||||
USER_ACCE KFKTopic = "user_access" // 用户访问
|
||||
USER_WOTHDRAW KFKTopic = "user_withdraw" // 用户提现
|
||||
USER_BINDING KFKTopic = "user_binding" // 用户绑定
|
||||
USER_INVITE KFKTopic = "user_invite" // 用户邀请
|
||||
ConsumeRecordJob = "consume_record" // 产品消费流水
|
||||
CardSellJob KFKTopic = "card_sell" // 会员卡特权卡销售流水
|
||||
AiSellJob = "ai_sell" // AI销售流水
|
||||
AdsTimeLongVideo = 15 // 长视频广告时间(单位: 秒)
|
||||
)
|
||||
|
||||
type AiSellMsg struct {
|
||||
AppID int32 `json:"appID" bson:"appID"` // AppID
|
||||
UID uint64 `json:"uid" bson:"uid"` // UID
|
||||
UniqID string `json:"uniqID" bson:"uniqID"` // 唯一ID,各个app内部交易ID
|
||||
Amount int64 `json:"amount" bson:"amount"` // 金币数
|
||||
TranType string `json:"tranType" bson:"tranType"` // 交易类型
|
||||
SysType string `json:"sysType" bson:"sysType"` // 系统类型
|
||||
CurrencyType string `json:"currencyType" bson:"currencyType"` // 交易类型,pay、free
|
||||
TranCreatedAt time.Time `json:"tranCreatedAt" bson:"tranCreatedAt"` // 交易完成时间
|
||||
IsRepurchase string `json:"isRepurchase" bson:"isRepurchase"` // 是否复购,yes、no
|
||||
|
||||
}
|
||||
|
||||
// UserRegisterMsg 用户注册
|
||||
type UserRegisterMsg struct {
|
||||
UserId uint64 `json:"userId"`
|
||||
AppId int32 `json:"appId"`
|
||||
PlatformId string `json:"platformId"` // 原始平台流水Id
|
||||
SysType string `json:"sysType"`
|
||||
DevType string `json:"devType"`
|
||||
Mobile string `json:"mobile"`
|
||||
Name string `json:"name"`
|
||||
IP string `json:"ip"`
|
||||
IsDirect bool `json:"isDirect"`
|
||||
DistrictCode string `json:"districtCode"` // 渠道推广 dc
|
||||
PromSeqe string `json:"promSeqe"` // 代理推广 pc
|
||||
PUC string `json:"puc" bson:"puc"` //
|
||||
PromCode string `json:"promCode"` // 用户推广序列(全名代理)
|
||||
RegisterTime time.Time `json:"registerTime"`
|
||||
}
|
||||
|
||||
// UserAccessMsg 用户访问 用户每天第一访问
|
||||
type UserAccessMsg struct {
|
||||
UserId uint64 `json:"userId"`
|
||||
PlatformId string `json:"platformId"` // 原始平台流水Id
|
||||
AppId int32 `json:"appId"`
|
||||
SysType string `json:"sysType"`
|
||||
DevType string `json:"devType"`
|
||||
IP string `json:"ip"`
|
||||
Version string `json:"version"`
|
||||
DevID string `json:"devID"`
|
||||
VisitAt time.Time `json:"visitAt"`
|
||||
|
||||
IsDirect bool `json:"isDirect,omitempty"` // true:是直推用户
|
||||
DistrictCode string `json:"districtCode,omitempty"` // 渠道码
|
||||
RegisterTime time.Time `json:"registerTime,omitempty"` //用户注册时间
|
||||
IsDeduction bool `json:"isDeduction,omitempty"` // true:CPA扣量用户
|
||||
}
|
||||
|
||||
// UserBindingMsg 用户绑定
|
||||
type UserBindingMsg struct {
|
||||
UserId uint64 `json:"userId"` // 用户ID
|
||||
AppId int32 `json:"appId"` // appID
|
||||
PlatformId string `json:"platformId"` // 原始平台流水Id
|
||||
SysType string `json:"sysType"` // 操作系统类型 安卓 IOS
|
||||
DevType string `json:"devType"` // 设备类型
|
||||
Mobile string `json:"mobile"` // 手机号
|
||||
BindingTime *time.Time `json:"bindingTime"` // 绑定时间
|
||||
}
|
||||
|
||||
type UserInviteBindMsg struct {
|
||||
UserId uint64 `json:"userId" bson:"userId" binding:"required"` // 用户ID
|
||||
AppId int32 `json:"appId" bson:"appId" binding:"required"` // appID
|
||||
ParentPromCode string `json:"parentPromCode,omitempty" bson:"promSeqe"` // 邀请人推广码
|
||||
InviteTime time.Time `json:"inviteTime,omitempty" bson:"inviteTime" binding:"required"` // 邀请码绑定时间
|
||||
}
|
||||
|
||||
const (
|
||||
StatVipCard = iota //会员卡
|
||||
StatLouFeng //楼凤
|
||||
StatValueAddSer //增值服务
|
||||
)
|
||||
|
||||
const (
|
||||
CurrencyTypeGold = iota //金币
|
||||
CurrencyTypeCash //现金
|
||||
)
|
||||
|
||||
type ConsumeRecordMsg struct {
|
||||
AppID int32 `json:"appID" bson:"appID"`
|
||||
UID uint64 `json:"uid" bson:"uid"` //
|
||||
Type int `json:"type" bson:"type"` //消费类型
|
||||
CurrencyType int `json:"currencyType" bson:"currencyType"` //货币类型 0金币 1人民币
|
||||
Money decimal.Decimal `json:"money" bson:"money"` //人民币 元
|
||||
Amount decimal.Decimal `json:"amount" bson:"amount"` //金币(角)
|
||||
Uniq string `json:"uniq" bson:"uniq"` //唯一号码
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //记录创建时间
|
||||
}
|
||||
|
||||
// 用户充值消息
|
||||
type UserRechargeMsg struct {
|
||||
UserId uint64 `json:"userId" bson:"userId" binding:"required"` // 用户ID
|
||||
AppId int32 `json:"appId" bson:"appId" binding:"required"` // appID
|
||||
PlatformId string `json:"platformId" bson:"platformId"` // 原始平台流水Id
|
||||
SysType string `json:"sysType" bson:"sysType" binding:"required"` // 操作系统类型 安卓 IOS
|
||||
DevType string `json:"devType" bson:"devType"` // 设备类型
|
||||
ChannelName string `json:"channelName" bson:"channelName"` // 支付渠道名字
|
||||
CID string `json:"cid" bson:"cid"` // 渠道id
|
||||
Type string `bson:"type" json:"type"` // 充值方式
|
||||
OrderId string `json:"orderId" bson:"orderId" binding:"required"` // 流水id
|
||||
OID string `json:"oid" bson:"oid"` //第三方支付流水id
|
||||
Money int64 `json:"money" bson:"money" binding:"required"` // 充值金额 订单金额
|
||||
PayMoney int64 `json:"payMoney" bson:"payMoney" binding:"required"` // 实际到账金额 用户实际支付金额
|
||||
Status int `json:"status" bson:"status"` // 2付款失败 3付款成功(目前只有成功才发送)
|
||||
Rate string `json:"rate"` //渠道费率
|
||||
SuccessAt time.Time `json:"successAt,omitempty" bson:"successAt"` // 成功时间
|
||||
ProductType int `json:"productType" bson:"productType"`
|
||||
ChanShareMod int `json:"chanShareMod" bson:"chanShareMod"` //渠道分成 0消费分成 1金币分成 2不分成
|
||||
/*......*/
|
||||
}
|
||||
|
||||
type CardSellMsg struct {
|
||||
AppID int32 `json:"appID" bson:"appID"` // AppID
|
||||
UID uint64 `json:"uid" bson:"uid"` // UID
|
||||
UniqID string `json:"uniqID" bson:"uniqID"` // 唯一ID,各个app内部交易ID
|
||||
Amount int64 `json:"amount" bson:"amount"` // 金币数
|
||||
TranTypeInt int64 `json:"tranTypeInt" bson:"tranTypeInt"` // 交易类型码
|
||||
TranType string `json:"tranType" bson:"tranType"` // 交易类型文字描述
|
||||
SysType string `json:"sysType" bson:"sysType"` // 系统类型
|
||||
CurrencyType int `json:"currencyType" bson:"currencyType"` // 交易类型(0 金币 1 现金)
|
||||
TranCreatedAt time.Time `json:"tranCreatedAt" bson:"tranCreatedAt"` // 交易完成时间
|
||||
Product Product `json:"product" bson:"product"` // 产品信息
|
||||
}
|
||||
|
||||
type Position struct {
|
||||
ID primitive.ObjectID `json:"id" bson:"id"` // 位置ID
|
||||
Name string `json:"name" bson:"name"` // 位置名称
|
||||
}
|
||||
|
||||
type Product struct {
|
||||
ID string `json:"id"` // ID
|
||||
Name string `json:"name"` // 产品名称
|
||||
DiscountedPrice int64 `bson:"discountedPrice" json:"discountedPrice"` // 现价 单位角(金币)
|
||||
ProductType ProductType `bson:"productType" json:"productType"` // 产品类型
|
||||
Position Position `json:"position"` // 产品位置
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package daichongmod
|
||||
|
||||
// 获取订单信息
|
||||
type GetOrderReq struct {
|
||||
TraderId int64 `form:"traderId" json:"traderId"`
|
||||
PlayerId int64 `form:"playerId" json:"playerId"`
|
||||
Proof string `form:"proof" json:"proof"` //玩家上传的图片名称
|
||||
SessionId string `form:"sessionId" json:"sessionId"` //当前会话的sessionId
|
||||
ProT int `form:"productType" json:"productType" ` //0 站群 1棋牌
|
||||
}
|
||||
|
||||
// 聊天信息请求
|
||||
type PayInfoReq struct {
|
||||
TraderId int64 `form:"traderId" json:"traderId" binding:"required"`
|
||||
PlayerId int64 `form:"playerId" json:"playerId" binding:"required"`
|
||||
SessionId string `form:"sessionId" json:"sessionId" binding:"required"` //当前会话的sessionId
|
||||
ProT int `form:"productType" json:"productType" ` //0 站群 1棋牌
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package daichongmod
|
||||
|
||||
import "time"
|
||||
|
||||
// 代充回调公用请求结构体
|
||||
type CommnReq struct {
|
||||
AppId string `json:"appId" binding:"required"` //代充平台提供的appId
|
||||
Data string `json:"data" binding:"required"` //加密字符串
|
||||
}
|
||||
|
||||
// 商人登陆 加密结构体
|
||||
type LoginSign struct {
|
||||
Uid string `json:"uid"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// 商人余额 加密结构体
|
||||
type BalanceSign struct {
|
||||
Uids string `json:"uids"`
|
||||
Time int64 `json:"time"` //时间戳
|
||||
}
|
||||
|
||||
// 上分 通知新订单生成 加密结构体
|
||||
type NewOrderSign struct {
|
||||
FromId string `json:"fromId"` //商人uid
|
||||
ToId string `json:"toId"` //用户uid
|
||||
Amount int64 `json:"amount"` //上分数量
|
||||
OrderId string `json:"orderId"` //订单号
|
||||
ProductInfo string `json:"productInfo"` //商品信息
|
||||
Time int64 `json:"time"` //本次通知发起的时间
|
||||
TransNo string `json:"transNo"` //请求订单
|
||||
ProT int `json:"productType"` //0站群 1棋牌
|
||||
SuccessAt time.Time `json:"successAt"` //回调成功时间
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package sharemod
|
||||
|
||||
import "91porn-server/models/v/vidmod"
|
||||
|
||||
// VShareReq 内容分享请求
|
||||
type VShareReq struct {
|
||||
Content string `form:"content" json:"content"`
|
||||
VideoID string `form:"videoID" json:"videoID"` // 可选;视频分享成功时用于累计真实推荐分
|
||||
EventID string `form:"eventId" json:"eventId"` // 可选;同一次真实分享事件重试时保持不变,用于推荐分幂等
|
||||
ObjType string `form:"objType" json:"objType"` // drama 表示短剧分享
|
||||
MediaID string `form:"mediaID" json:"mediaID"`
|
||||
ContentID string `form:"contentID" json:"contentID"`
|
||||
}
|
||||
|
||||
// VShareCntReq 视频分享次数
|
||||
type VShareCntReq struct {
|
||||
VideoID string `form:"videoID" json:"videoID"`
|
||||
}
|
||||
|
||||
// VShareResp 内容分享应答
|
||||
type VShareResp struct {
|
||||
QrCode []byte `json:"qrCode"`
|
||||
}
|
||||
|
||||
// VShareCntResp 分享次数应答
|
||||
type VShareCntResp struct {
|
||||
VidelID string `json:"videoID"`
|
||||
Cnt int `json:"cnt"`
|
||||
}
|
||||
|
||||
// List 分享推荐列表
|
||||
type List struct {
|
||||
Title string `json:"title"`
|
||||
Cover string `json:"cover"`
|
||||
SourceUrl string `json:"sourceUrl"`
|
||||
LandUrl string `json:"landUrl"`
|
||||
PicUrl string `json:"picUrl"`
|
||||
Tags []string `json:"tags"`
|
||||
DownloadUrl string `json:"downloadUrl"`
|
||||
List []vidmod.ShareInfo `json:"list"`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package sharemod
|
||||
|
||||
// VShareModel 分享统计
|
||||
type VShareModel struct {
|
||||
UID int64 `json:"uid" bson:"uid"`
|
||||
Title int `json:"title" bson:"title"`
|
||||
ClickCnt int64 `json:"clickCnt" bson:"clickCnt"`
|
||||
ShareTime int64 `json:"shareTime" bson:"shareTime"`
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package models
|
||||
|
||||
const (
|
||||
ESInfoVideoTable = "91porn_video_info"
|
||||
ESMediaTable = "91porn_media_info"
|
||||
ESInfoTagTable = "91porn_tag_info"
|
||||
ESInfoUserTable = "91porn_user_info"
|
||||
ESInfoLouFengTable = "91porn_loufeng_info"
|
||||
ESInfoFictionTable = "91porn_fiction_info"
|
||||
ESInfoAudioBookTable = "91porn_audiobook"
|
||||
|
||||
ESLogSearchLogTable = "91porn_search_log"
|
||||
|
||||
ESStatKeywordTable = "91porn_keyword_stat"
|
||||
)
|
||||
@@ -0,0 +1,74 @@
|
||||
package adsclicklogmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.AdsClickLog
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
|
||||
// InitIndex 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "uid", Value: 1}, {Key: "adsType", Value: 1}, {Key: "createdAt", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
type AdsClick struct {
|
||||
ID primitive.ObjectID `json:"-" bson:"_id,omitempty"`
|
||||
UID uint64 `json:"uid" bson:"uid"`
|
||||
ClickId primitive.ObjectID `json:"clickId" bson:"clickId"`
|
||||
ObjType string `json:"objType" bson:"objType"`
|
||||
AdsType int64 `json:"adsType" bson:"adsType"` // 0 默认; 1 金主楼凤广告
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"`
|
||||
}
|
||||
|
||||
func AddClick(uid uint64, clickId primitive.ObjectID, objType string, adsType int64) error {
|
||||
now := time.Now()
|
||||
_, err := coll(nil).InsertOne(AdsClick{
|
||||
UID: uid,
|
||||
ClickId: clickId,
|
||||
ObjType: objType,
|
||||
AdsType: adsType,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func GetDailyClickCount(uid uint64) (uint64, error) {
|
||||
year, month, day := time.Now().Date()
|
||||
start := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
|
||||
end := time.Date(year, month, day+1, 0, 0, 0, 0, time.Local)
|
||||
res, err := coll(nil).Distinct("clickId", bson.M{"uid": uid, "adsType": 1, "createdAt": bson.M{"$gte": start, "$lt": end}})
|
||||
return uint64(len(res)), err
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package exchlogmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/commod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.ExchLog
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
|
||||
{
|
||||
Keys: bson.D{{Key: "code", Value: 1}, {Key: "createdAt", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "userID", Value: 1}, {Key: "createdAt", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "userID", Value: 1}, {Key: "batchNum", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "channel", Value: 1}, {Key: "createdAt", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "authority", Value: 1}, {Key: "createdAt", 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 Insert(doc ExchangeLog) error {
|
||||
if _, err := coll(nil).InsertOne(doc); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err),
|
||||
log.Any("doc", doc),
|
||||
)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetExchangeLogList(filterParams FilterDoc, page commod.Page) (total int64, data []ExchangeLog, err error) {
|
||||
filter, _ := common.ToBsonM(filterParams)
|
||||
var skip = int64((page.PageNumber - 1) * page.PageSize)
|
||||
var limit = int64(page.PageSize)
|
||||
var opts = options.Find()
|
||||
opts.SetSort(bson.D{{Key: "createdAt", Value: -1}}).SetSkip(skip).SetLimit(limit)
|
||||
if err = coll(nil).Find(&data, filter, opts); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetExchangeLogList", table, "Find", err),
|
||||
log.Any("filterParams", filterParams),
|
||||
log.Any("page", page),
|
||||
)
|
||||
return
|
||||
}
|
||||
if total, err = coll(nil).Count(filter); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetExchangeLogList", table, "Count", err),
|
||||
log.Any("filterParams", filterParams),
|
||||
log.Any("page", page),
|
||||
)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 获取用户兑换日志
|
||||
func GetLogByUIDAndBatchNum(uid uint64, batchNum string) (data ExchangeLog, err error) {
|
||||
if err = coll(nil).FindOne(&data, bson.M{"userID": uid, "batchNum": batchNum}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetExchangeLogList", table, "Find", err),
|
||||
log.Any("uid", uid),
|
||||
log.Any("batchNum", batchNum),
|
||||
)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 获取用户兑换日志
|
||||
func GetLogByUIDAndAuthority(uid uint64, authority string) (data ExchangeLog, err error) {
|
||||
if err = coll(nil).FindOne(&data, bson.M{"userID": uid, "authority": authority}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetExchangeLogList", table, "Find", err),
|
||||
log.Any("uid", uid),
|
||||
log.Any("authority", authority),
|
||||
)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 获取用户兑换
|
||||
func GetLogByUIDAndCode(uid uint64, code string) (data ExchangeLog, err error) {
|
||||
if err = coll(nil).FindOne(&data, bson.M{"userID": uid, "code": code}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetLogByUIDAndCode", table, "Find", err),
|
||||
log.Any("uid", uid),
|
||||
log.Any("code", code),
|
||||
)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package exchlogmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ObjectID = primitive.ObjectID
|
||||
|
||||
// Init 初始化索引
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
|
||||
type ExchangeLog struct {
|
||||
ID ObjectID `json:"id" bson:"_id,omitempty"`
|
||||
Code string `json:"code" bson:"code"` // 兑换码
|
||||
UserID uint64 `json:"userID" bson:"userID"` // 兑换者
|
||||
BatchNum string `json:"batchNum" bson:"batchNum"` // 批次号
|
||||
Channel string `json:"channel" bson:"channel"` // 所属渠道
|
||||
Authority string `json:"authority" bson:"authority"` // 兑换权限
|
||||
Desc string `json:"desc" bson:"-"` // 说明
|
||||
Reward int `json:"reward" bson:"reward"` // 奖励值
|
||||
RewardCount int `json:"rewardCount" bson:"rewardCount"` // 奖励量
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间/兑换时间
|
||||
}
|
||||
|
||||
type FilterDoc struct {
|
||||
Code *string `bson:"code,omitempty"` // 兑换码
|
||||
UserID *uint64 `bson:"userID,omitempty"` // 兑换者
|
||||
Channel *string `bson:"channel,omitempty"` // 所属渠道
|
||||
Authority *string `bson:"authority,omitempty"` // 兑换权限
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package exchlogmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/models/commod"
|
||||
)
|
||||
|
||||
type ListReqParam struct {
|
||||
Code *string `form:"code" json:"code"` // 兑换码
|
||||
UserID *uint64 `form:"userID" json:"userID"` // 兑换者
|
||||
Channel *string `form:"channel" json:"channel"` // 所属渠道
|
||||
Authority *string `form:"authority" json:"authority"` // 兑换权限
|
||||
Page commod.Page
|
||||
}
|
||||
|
||||
type ListResp struct {
|
||||
Code string `json:"code"` // 兑换码
|
||||
UserID uint64 `json:"userID"` // 兑换者
|
||||
Channel string `json:"channel"` // 所属渠道
|
||||
Authority string `json:"authority"` // 兑换权限
|
||||
Reward int `json:"reward"` // 奖励值
|
||||
RewardCount int `json:"rewardCount"` // 奖励量
|
||||
CreatedAt time.Time `json:"createdAt"` // 创建时间/兑换时间
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package loginlgmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.LoginLog
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// initIndex 设置index
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
|
||||
{
|
||||
Keys: bson.D{{Key: "uid", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "devID", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "loginTime", Value: 1}},
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
func InsertLoginLog(l *LoginLog) error {
|
||||
if _, err := coll(nil).InsertOne(l); err != nil {
|
||||
log.Error("loginlog insert err", log.E(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func WebGetDayActivity(uids []uint64, start time.Time, end time.Time) (data []LoginLog, err error) {
|
||||
if err = coll(nil).Find(
|
||||
&data,
|
||||
bson.M{
|
||||
"loginTime": bson.M{
|
||||
"$and": []bson.M{
|
||||
bson.M{"$gte": start},
|
||||
bson.M{"$lte": end},
|
||||
},
|
||||
},
|
||||
"uid": bson.M{
|
||||
"$in": uids,
|
||||
},
|
||||
},
|
||||
); err != nil {
|
||||
log.ZapLog.Error(fmt.Sprintf("model record login WebGetDayActivity fail error:%+v:", err))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetTotalCnt 获取查询总数总数
|
||||
func getLoginLogTotalCnt(cond bson.M) (int64, error) {
|
||||
total, err := coll(nil).Count(cond)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("get total Cnt error: %+v\n", err)
|
||||
log.ZapLog.Error(e)
|
||||
return 0, err
|
||||
}
|
||||
return total, nil
|
||||
}
|
||||
|
||||
// GetSkipSize 计算跳转
|
||||
func getLoginLogSkipSize(page int, size int, cond bson.M) (int, int, int64, error) {
|
||||
total, err := getLoginLogTotalCnt(cond)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
totalpages := int(math.Ceil(float64(total) / float64(size)))
|
||||
if page > totalpages {
|
||||
page = totalpages
|
||||
}
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
return (page - 1) * size, totalpages, total, nil
|
||||
}
|
||||
|
||||
// FindLoginLog 查找登陆日志
|
||||
func FindLoginLogList(page int, size int, cond bson.M, sort bson.D) ([]*LoginLog, int, int64, error) {
|
||||
skip, totalPages, total, err := getLoginLogSkipSize(page, size, cond)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
var back []*LoginLog
|
||||
if err = coll(nil).Aggregate(
|
||||
&back,
|
||||
[]bson.M{
|
||||
bson.M{"$match": cond},
|
||||
bson.M{"$sort": sort},
|
||||
bson.M{"$skip": skip},
|
||||
bson.M{"$limit": size},
|
||||
},
|
||||
); err != nil {
|
||||
e := fmt.Sprintf("get login logs error: %+v\n", err)
|
||||
log.ZapLog.Error(e)
|
||||
return nil, totalPages, total, err
|
||||
}
|
||||
return back, totalPages, total, nil
|
||||
}
|
||||
|
||||
func DeleteBeforeLoginTime(t *db.MongoTool, tm time.Time) error {
|
||||
_, err := coll(t).DeleteMany(bson.M{"loginTime": bson.M{"$lt": tm}})
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package loginlgmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models/commod"
|
||||
)
|
||||
|
||||
// LoginLog 登陆记录
|
||||
type LoginLog struct {
|
||||
UID uint64 `json:"uid" bson:"uid"`
|
||||
IP string `json:"ip" bson:"ip"`
|
||||
SysType string `json:"sysType" bson:"sysType"` //操作系统类型 安卓 IOS
|
||||
Ver string `json:"ver" bson:"ver"` //APP版本号
|
||||
DevType string `json:"devType" bson:"devType"` //设备型号
|
||||
DevID string `json:"devID" bson:"devID"`
|
||||
BuildID string `json:"buildID" bson:"buildID"` //app构建ID(包ID)
|
||||
LoginTime time.Time `json:"loginTime" bson:"loginTime,omitempty"`
|
||||
LogoutTime time.Time `json:"logoutTime" bson:"logoutTime,omitempty"`
|
||||
Logout bool `json:"logout" bson:"logout"` //是否退出登陆
|
||||
}
|
||||
|
||||
// LogListResp 登陆日志查询列表
|
||||
type LogListResp struct {
|
||||
Logs []*LoginLog `json:"logs"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
// QueryReq 登陆日志查询请求参数
|
||||
type QueryReq struct {
|
||||
commod.Page
|
||||
UID uint64 `form:"uid" json:"uid"`
|
||||
Start time.Time `form:"start" json:"start"`
|
||||
End time.Time `form:"end" json:"end"`
|
||||
Sort string `form:"sort" json:"sort"`
|
||||
Desc int `form:"desc" json:"desc"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package lotterylgmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/timeutil/timerange"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
const table = models.LotteryLog
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// initIndexAds 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "uid", Value: 1}, {Key: "createdAt", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "code", 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))
|
||||
}
|
||||
}
|
||||
|
||||
// InsertLog 记录一个抽奖号行为
|
||||
func InsertLog(uid uint64, code int, gateName string) error {
|
||||
ll := LotteryLog{
|
||||
UID: uid,
|
||||
Code: code,
|
||||
GateName: gateName,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
if _, err := coll(nil).InsertOne(ll); err != nil {
|
||||
log.Error("InsertClickLog error", log.Any("ll", ll), log.E(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UserTodayChances 获取用户当日抽奖号数量
|
||||
func UserTodayChances(uid uint64) (int, error) {
|
||||
sumDate := timerange.LocDayRange(time.Now()).Head
|
||||
ll := []LotteryLog{}
|
||||
cond := bson.M{"uid": uid, "createdAt": bson.M{"$gte": sumDate}}
|
||||
if err := coll(nil).Find(&ll, cond); err != nil {
|
||||
log.Error("UserTodayChances error", log.Any("uid", uid), log.E(err))
|
||||
return 0, err
|
||||
}
|
||||
return len(ll), nil
|
||||
}
|
||||
|
||||
// LottnumList 获取摇号列表
|
||||
func LottnumList(page, size uint64, start *time.Time, end *time.Time, uid *uint64, code *int) ([]LotteryLog, int64, error) {
|
||||
back := []LotteryLog{}
|
||||
cond := bson.M{}
|
||||
if uid != nil {
|
||||
cond["uid"] = *uid
|
||||
}
|
||||
if code != nil {
|
||||
cond["code"] = *code
|
||||
}
|
||||
if start != nil && end != nil {
|
||||
cond["createdAt"] = bson.M{"$gte": *start, "$lt": *end}
|
||||
}
|
||||
sort := bson.D{{Key: "createdAt", Value: -1}}
|
||||
skip := (page - 1) * size
|
||||
opts := options.FindOptions{}
|
||||
opts.SetSort(sort).SetSkip(int64(skip)).SetLimit(int64(size))
|
||||
if err := coll(nil).Find(&back, bson.M(cond), &opts); err != nil {
|
||||
log.Error("LottnumList error", log.Any("page", page), log.Any("size", size), log.Any("cond", cond), log.E(err))
|
||||
return back, 0, err
|
||||
}
|
||||
total, _ := coll(nil).Count(cond)
|
||||
return back, total, nil
|
||||
}
|
||||
|
||||
// UserTodayNum 获取用户当日抽奖号
|
||||
func UserTodayNum(uid uint64) ([]LotteryLog, error) {
|
||||
sumDate := timerange.LocDayRange(time.Now()).Head
|
||||
ll := []LotteryLog{}
|
||||
cond := bson.M{"uid": uid, "createdAt": bson.M{"$gte": sumDate}}
|
||||
if err := coll(nil).Find(&ll, cond); err != nil {
|
||||
log.Error("UserTodayChances error", log.Any("uid", uid), log.E(err))
|
||||
return ll, err
|
||||
}
|
||||
return ll, nil
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package lotterylgmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
)
|
||||
|
||||
// LotteryLog 活动摇号日志
|
||||
type LotteryLog struct {
|
||||
UID uint64 `json:"uid" bson:"uid"`
|
||||
Code int `json:"code" bson:"code"`
|
||||
GateName string `json:"gateName" bson:"gateName"`
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package lotterylgmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/models/commod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// AdsClickResp 广告点击日志应答
|
||||
type AdsClickResp struct {
|
||||
Logs int `json:"logs"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
// AdsCountResp 广告点击统计应答
|
||||
type AdsCountResp struct {
|
||||
ID string `json:"id"`
|
||||
TodayCnt int64 `json:"todayCnt"`
|
||||
YesterdayCnt int64 `json:"yesterdayCnt"`
|
||||
WeekCnt int64 `json:"weekCnt"`
|
||||
MonthCnt int64 `json:"monthCnt"`
|
||||
TotalCnt int64 `json:"totalCnt"`
|
||||
}
|
||||
|
||||
type AdsClickReq struct {
|
||||
UID uint64 `form:"uid" json:"uid"`
|
||||
Start time.Time `form:"start" json:"start"`
|
||||
End time.Time `form:"end" json:"end"`
|
||||
Sort string `form:"sort" json:"sort"`
|
||||
Desc int `form:"desc" json:"desc"`
|
||||
commod.Page
|
||||
}
|
||||
|
||||
// AdsClickInfo
|
||||
type AdsClickInfo struct {
|
||||
AID primitive.ObjectID `json:"aid"` //广告id
|
||||
TodayCount int64 `json:"todayCount"` //今日点击数
|
||||
YesterdayCount int64 `json:"yesterdayCount"` //昨日点击数
|
||||
WeekCount int64 `json:"weekCount"` //本周点击数
|
||||
MonthCount int64 `json:"monthCount"` //本月点击数
|
||||
TotalCount int64 `json:"totalCount"` //总点击数
|
||||
}
|
||||
|
||||
// AdsStatisticResp 广告点击统计应答
|
||||
type AdsStatisticResp struct {
|
||||
Logs []AdsClickInfo `json:"logs"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package operatorlgmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
|
||||
"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.WebOperatorLog
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// initIndexAds 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "createdAt", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "manager", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "uri", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "position", Value: 1}},
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
// RecordOperation 记录操作日志
|
||||
func RecordOperation(manager string, position string, operator string, content string, uri string) error {
|
||||
record := WebOperatorLog{
|
||||
Manager: manager,
|
||||
Position: position,
|
||||
Operator: operator,
|
||||
Content: content,
|
||||
URI: uri,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
if _, err := coll(nil).InsertOne(&record); err != nil {
|
||||
log.Error("RecordOperation error", log.Any("manager", manager), log.Any("position", position),
|
||||
log.Any("operator", operator), log.Any("content", content), log.Any("url", uri), log.E(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func backOperatorParam(param OperatorListReq) map[string]interface{} {
|
||||
m := make(map[string]interface{})
|
||||
if len(param.Manager) != 0 {
|
||||
m["manager"] = param.Manager
|
||||
}
|
||||
if len(param.Position) != 0 {
|
||||
m["position"] = param.Position
|
||||
}
|
||||
if len(param.URI) != 0 {
|
||||
m["uri"] = param.URI
|
||||
}
|
||||
if param.Content != "" {
|
||||
param.Content = strings.Trim(param.Content, " ")
|
||||
m["content"] = bson.M{"$regex": primitive.Regex{
|
||||
Pattern: param.Content,
|
||||
Options: "i",
|
||||
}}
|
||||
}
|
||||
if !param.End.IsZero() {
|
||||
i := make(map[string]time.Time)
|
||||
i["$gte"] = param.Start
|
||||
i["$lt"] = param.End
|
||||
m["createdAt"] = i
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// getTotalCnt 获取后台操作日志总数
|
||||
func getTotalCnt(cond bson.M) (int64, error) {
|
||||
total, err := coll(nil).Count(cond)
|
||||
if err != nil {
|
||||
log.Error("getTotalCnt", log.Any("cond", cond), log.E(err))
|
||||
return 0, err
|
||||
}
|
||||
return total, nil
|
||||
}
|
||||
|
||||
// getSkipSize 计算跳转
|
||||
func getSkipSize(page, size uint64, cond bson.M) (uint64, uint64, int64, error) {
|
||||
total, err := getTotalCnt(cond)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// GetOperatorLog 获取操作日志
|
||||
func GetOperatorLog(req OperatorListReq) ([]*WebOperatorLog, int64, error) {
|
||||
cond := backOperatorParam(req)
|
||||
sort := bson.D{{Key: "createdAt", Value: -1}}
|
||||
skip, _, total, err := getSkipSize(req.PageNumber, req.PageSize, bson.M(cond))
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
opts := options.FindOptions{}
|
||||
opts.SetSort(sort).SetSkip(int64(skip)).SetLimit(int64(req.PageSize))
|
||||
var back []*WebOperatorLog
|
||||
if err = coll(nil).Find(&back, bson.M(cond), &opts); err != nil {
|
||||
log.Error("GetOperatorLog error", log.Any("req", req), log.E(err))
|
||||
}
|
||||
return back, total, err
|
||||
}
|
||||
|
||||
// EditRemarks 更新备注
|
||||
func EditRemarks(id primitive.ObjectID, remarks string) error {
|
||||
cond := bson.M{"_id": id}
|
||||
update := bson.M{"$set": bson.M{"remarks": remarks}}
|
||||
if _, err := coll(nil).UpdateOne(cond, update); err != nil {
|
||||
log.Error("EditRemarks error", log.Any("id", id), log.Any("remarks", remarks), log.E(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package operatorlgmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// WebOperatorLog 后台操作日志
|
||||
type WebOperatorLog struct {
|
||||
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
|
||||
Manager string `json:"manager" bson:"manager"` //管理员账号
|
||||
Position string `json:"position" bson:"position"` //操作位置
|
||||
Operator string `json:"operator" bson:"operator"` //操作动作
|
||||
Content string `json:"content" bson:"content"` //操作内容
|
||||
URI string `json:"uri" bson:"uri"` //操作uri
|
||||
Remarks string `json:"remarks" bson:"remarks"` //备注
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
}
|
||||
|
||||
// Init 初始化索引
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package operatorlgmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/models/commod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// OperatorListReq 操作日志查询
|
||||
type OperatorListReq struct {
|
||||
Manager string `form:"manager" json:"manager"`
|
||||
Position string `form:"position" json:"position"`
|
||||
Content string `form:"content" json:"content" binding:"omitempty,min=2,max=100"`
|
||||
URI string `form:"uri" json:"uri"`
|
||||
Start time.Time `form:"start" json:"start"`
|
||||
End time.Time `form:"end" json:"end"`
|
||||
commod.Page
|
||||
}
|
||||
|
||||
// OperatorListResp 操作日志查询应答
|
||||
type OperatorListResp struct {
|
||||
Infos []*WebOperatorLog `json:"infos"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
// OperatorModifyReq 操作日志修改
|
||||
type OperatorModifyReq struct {
|
||||
ID primitive.ObjectID `json:"id"`
|
||||
Remarks string `json:"remarks"`
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package payvidlgmod
|
||||
|
||||
// Pay4VidLogQueryReq Pay4VidLogQueryReq
|
||||
type Pay4VidLogQueryReq struct {
|
||||
PublisherID *uint64 `json:"publisherID,omitempty" bson:"publisherID"` //上传者ID
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package payvidlgmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/pageopt"
|
||||
"91porn-server/common/ysinterface/disc"
|
||||
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type DistrictStatKey struct {
|
||||
DiscSeqe `bson:",inline"` //商区码
|
||||
SysType string `bson:"sysType"` //系统类型 iOS Android
|
||||
}
|
||||
|
||||
func (d DistrictStatKey) GetDiscCode() string {
|
||||
return d.DistrictCode
|
||||
}
|
||||
|
||||
func (d DistrictStatKey) GetPromSeqe() string {
|
||||
return d.PromSeqe
|
||||
}
|
||||
|
||||
func (d DistrictStatKey) GetSysType() string {
|
||||
return d.SysType
|
||||
}
|
||||
|
||||
func (d DistrictStatKey) String() string {
|
||||
if d.DiscSeqe.String() == "" {
|
||||
return ""
|
||||
}
|
||||
return strings.ToUpper(strings.Join([]string{d.DiscSeqe.String(), d.SysType}, "-"))
|
||||
}
|
||||
|
||||
type DistrictStater = disc.DistrictStater
|
||||
|
||||
// DiscSeqeTransCount
|
||||
func DiscSeqeBuyVidCount(start, end time.Time, mats ...Matcher) (map[DistrictStater]int64, error) {
|
||||
mats = append(mats, (&CreatedAtGTEAndLTMatch{GTE: &start, LT: &end}).New())
|
||||
filter := pageopt.MergeM(mats)
|
||||
list := []DistrictStatKey{}
|
||||
opt := (&options.FindOptions{}).SetProjection(M{
|
||||
"districtCode": 1,
|
||||
"promSeqe": 1,
|
||||
"sysType": 1,
|
||||
})
|
||||
if err := coll(nil).Find(&list, filter, opt); err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DiscSeqeTransCount", table, "Find", err))
|
||||
return nil, err
|
||||
}
|
||||
m := make(map[DistrictStater]int64)
|
||||
for _, v := range list {
|
||||
if v.String() != "" {
|
||||
m[v] += 1
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// DiscSeqeBuyVidCoins
|
||||
func DiscSeqeBuyVidCoins(start, end time.Time, mats ...Matcher) (map[DistrictStater]int64, error) {
|
||||
mats = append(mats, (&CreatedAtGTEAndLTMatch{GTE: &start, LT: &end}).New())
|
||||
filter := pageopt.MergeM(mats)
|
||||
list := []struct {
|
||||
DistrictStatKey `bson:",inline"` //商区码
|
||||
Coins int64 `bson:"coins"`
|
||||
}{}
|
||||
opt := (&options.FindOptions{}).SetProjection(M{
|
||||
"districtCode": 1,
|
||||
"promSeqe": 1,
|
||||
"sysType": 1,
|
||||
"coins": 1,
|
||||
})
|
||||
if err := coll(nil).Find(&list, filter, opt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := make(map[DistrictStater]int64, len(list))
|
||||
for _, v := range list {
|
||||
if v.String() != "" {
|
||||
m[v.DistrictStatKey] += v.Coins
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// DiscSeqeTaxAmount
|
||||
func DiscSeqeTaxAmount(start, end time.Time, mats ...Matcher) (map[DistrictStater]float64, error) {
|
||||
mats = append(mats, (&CreatedAtGTEAndLTMatch{GTE: &start, LT: &end}).New())
|
||||
filter := pageopt.MergeM(mats)
|
||||
list := []struct {
|
||||
DistrictStatKey `bson:",inline"` //商区码
|
||||
TaxAmount float64 `bson:"taxAmount"` //税额
|
||||
}{}
|
||||
opt := (&options.FindOptions{}).SetProjection(M{
|
||||
"districtCode": 1,
|
||||
"promSeqe": 1,
|
||||
"sysType": 1,
|
||||
"taxAmount": 1,
|
||||
})
|
||||
if err := coll(nil).Find(&list, filter, opt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := make(map[DistrictStater]float64, len(list))
|
||||
for _, v := range list {
|
||||
if v.String() != "" {
|
||||
m[v.DistrictStatKey] += v.TaxAmount
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package payvidlgmod
|
||||
|
||||
import (
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/pageopt"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type Matcher = pageopt.Matcher
|
||||
|
||||
// DistrictCodeMatch
|
||||
type DistrictCodeMatch struct {
|
||||
DistrictCode *string
|
||||
}
|
||||
|
||||
func (s *DistrictCodeMatch) New() Matcher {
|
||||
return pageopt.NewAssignMatch("districtCode", s.DistrictCode)
|
||||
}
|
||||
|
||||
// IsDirectMatch
|
||||
type IsDirectMatch struct {
|
||||
IsDirect *bool
|
||||
}
|
||||
|
||||
func (b *IsDirectMatch) New() Matcher {
|
||||
return pageopt.NewAssignMatch("isDirect", b.IsDirect)
|
||||
}
|
||||
|
||||
// PromSeqeMatch
|
||||
type PromSeqeMatch struct {
|
||||
Seqe *string
|
||||
}
|
||||
|
||||
func (d *PromSeqeMatch) New() Matcher {
|
||||
return pageopt.NewAssignMatch("promSeqe", d.Seqe)
|
||||
}
|
||||
|
||||
// SysTypeMatch
|
||||
type SysTypeMatch struct {
|
||||
SysType *string
|
||||
}
|
||||
|
||||
func (d *SysTypeMatch) New() Matcher {
|
||||
return pageopt.NewAssignMatch("sysType", d.SysType)
|
||||
}
|
||||
|
||||
// CreatedAtGTEAndLTMatch
|
||||
type CreatedAtGTEAndLTMatch = pageopt.CreatedAtGTEAndLTMatch
|
||||
|
||||
type Sort = bson.D
|
||||
|
||||
var Sort_CreatedAt_n1 = Sort{{Key: "createdAt", Value: -1}}
|
||||
|
||||
func List(sort Sort, skip, limit *int64, matchers ...Matcher) ([]Pay4VidLog, error) {
|
||||
filter := pageopt.MergeM(matchers)
|
||||
opt := (&options.FindOptions{})
|
||||
if len(sort) != 0 {
|
||||
opt.SetSort(sort)
|
||||
}
|
||||
if skip != nil {
|
||||
opt.SetSkip(*skip)
|
||||
}
|
||||
if limit != nil {
|
||||
opt.SetLimit(*limit)
|
||||
}
|
||||
list := []Pay4VidLog{}
|
||||
if err := coll(nil).Find(&list, filter, opt); err != nil {
|
||||
log.Error("payvidlgmod List error", log.E(err))
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func Count(matchers ...Matcher) (int64, error) {
|
||||
filter := pageopt.MergeM(matchers)
|
||||
count, err := coll(nil).Count(filter)
|
||||
if err != nil {
|
||||
log.Error("payvidlgmod Count error", log.E(err))
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
@@ -0,0 +1,602 @@
|
||||
package payvidlgmod
|
||||
|
||||
import (
|
||||
"91porn-server/models/commod"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/pageopt"
|
||||
"91porn-server/common/timeutil"
|
||||
"91porn-server/models"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"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"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.PayVideoLog
|
||||
|
||||
// initIndex 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "uid", Value: 1}, {Key: "videoID", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "createdAt", Value: -1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "uniq", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "deductType", Value: 1}, {Key: "createdAt", Value: -1}},
|
||||
Options: options.Index().SetSparse(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "videoID", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "publisherID", 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)
|
||||
}
|
||||
|
||||
// InsertVideoPayRecord 插入一条购买记录
|
||||
func InsertVideoPayRecord(t *db.MongoTool, p Pay4VidLog) error {
|
||||
p.Uniq = Unique(p.UID, p.VideoID)
|
||||
p.CreatedAt = time.Now()
|
||||
res, err := coll(t).InsertOne(&p)
|
||||
if err != nil {
|
||||
log.Error("InsertVideoPayRecord error", log.Any("p", p), log.E(err))
|
||||
return err
|
||||
}
|
||||
p.ID = res.InsertedID.(ObjectID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsPay4Video 用户是否购买了视频
|
||||
func IsPay4Video(uid uint64, videoID ObjectID) (bool, error) {
|
||||
cnt, err := coll(nil).Count(bson.M{"uid": uid, "videoID": videoID})
|
||||
if err != nil {
|
||||
log.Error("IsPay4Video error", log.Any("uid", uid), log.Any("videoID", videoID), log.E(err))
|
||||
return false, err
|
||||
}
|
||||
return cnt != 0, nil
|
||||
}
|
||||
|
||||
func FindManyPay4VidLogByUID(uid uint64, newsType string) ([]*Pay4VidLog, error) {
|
||||
vl := make([]*Pay4VidLog, 0)
|
||||
err := coll(nil).Find(&vl, bson.M{"uid": uid, "newsType": newsType})
|
||||
if err != nil {
|
||||
log.Error("FindManyPay4VidLogByUID error", log.Any("uid", uid), log.Any("err", err.Error()))
|
||||
return nil, err
|
||||
}
|
||||
return vl, nil
|
||||
}
|
||||
|
||||
// IsPay4Videos 用户是否购买了视频
|
||||
func IsPay4Videos(uid uint64, videoIDs []ObjectID) (map[ObjectID]bool, error) {
|
||||
if videoIDs == nil {
|
||||
videoIDs = []ObjectID{}
|
||||
}
|
||||
m := make(map[ObjectID]bool)
|
||||
var infos []Pay4VidLog
|
||||
query := bson.M{"uid": uid, "videoID": bson.M{"$in": videoIDs}}
|
||||
if err := coll(nil).Find(&infos, query); err != nil {
|
||||
log.Error("IsPay4Videos error", log.Any("uid", uid), log.Any("videoIDs", videoIDs), log.E(err))
|
||||
return m, err
|
||||
}
|
||||
for _, i := range infos {
|
||||
m[i.VideoID] = true
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// 判断当前视频是否有人购买过
|
||||
func IsVidIfBePay(id primitive.ObjectID) bool {
|
||||
var pay *Pay4VidLog
|
||||
if err := coll(nil).FindOne(&pay, bson.M{"videoID": id}); err != nil {
|
||||
log.Error("IsVidIfBePay error", log.Any("videoID", id), log.E(err))
|
||||
return false
|
||||
}
|
||||
return pay != nil
|
||||
}
|
||||
|
||||
// DelVideoPayRecord 删除一条购买记录
|
||||
func DelVideoPayRecord(videoID primitive.ObjectID, uid uint64) error {
|
||||
if _, err := coll(nil).DeleteOne(bson.M{"videoID": videoID, "uid": uid}); err != nil {
|
||||
log.Error("DelVideoPayRecord DeleteOne error", log.Any("videoID", videoID), log.Any("uid", uid))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 从给定的hash列表中获取购买状态映射:uniq->Statue
|
||||
// uniq通过Unique()获取
|
||||
func PayStatueMap(uniqList []string) (map[string]bool, error) {
|
||||
filter := bson.M{
|
||||
"uniq": bson.M{"$in": uniqList},
|
||||
}
|
||||
payLogList := make([]Pay4VidLog, 0, len(uniqList))
|
||||
if err := coll(nil).Find(&payLogList, filter); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := make(map[string]bool, len(payLogList))
|
||||
//初始化
|
||||
for _, uniq := range uniqList {
|
||||
m[uniq] = false
|
||||
}
|
||||
//已经收藏的
|
||||
for _, v := range payLogList {
|
||||
uniq := v.Uniq
|
||||
m[uniq] = true
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func GetUIDListByPayTime(start time.Time, end time.Time) ([]uint64, error) {
|
||||
filter := bson.M{
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
}
|
||||
list := make([]struct {
|
||||
UID uint64 `bson:"uid"`
|
||||
}, 0)
|
||||
if err := coll(nil).Find(&list, filter); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uidList := make([]uint64, len(list))
|
||||
for i, v := range list {
|
||||
uidList[i] = v.UID
|
||||
}
|
||||
return uidList, nil
|
||||
}
|
||||
|
||||
func GetPayMoneyByTime(start time.Time, end time.Time) (int64, error) {
|
||||
filter := bson.M{
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
}
|
||||
logs := make([]Pay4VidLog, 0)
|
||||
if err := coll(nil).Find(&logs, filter); err != nil {
|
||||
return 0, fmt.Errorf("table:%s GetPayMoneyByTime err: %s", table, err.Error())
|
||||
}
|
||||
total := int64(0)
|
||||
for _, v := range logs {
|
||||
total += v.PayMoney
|
||||
}
|
||||
return total, nil
|
||||
}
|
||||
|
||||
// FindManyVideoPayRecord 查询所有
|
||||
func FindThreeMonthVideoPayRecord(publisherID uint64, pageNumber, pageSize uint64) (total int64, totalAmount int64, data []*Pay4VidLog, hasNext bool, err error) {
|
||||
data = make([]*Pay4VidLog, 0)
|
||||
startTime := timeutil.NearMonth(time.Now(), 2)
|
||||
f := bson.M{"publisherID": publisherID, "createdAt": bson.M{"$gte": startTime}}
|
||||
skip := int64(pageSize * (pageNumber - 1))
|
||||
limit := int64(pageSize + 1)
|
||||
opts := options.FindOptions{
|
||||
Skip: &skip,
|
||||
Limit: &limit,
|
||||
Sort: bson.D{{Key: "createdAt", Value: -1}},
|
||||
}
|
||||
if err = coll(nil).Find(&data, f, &opts); err != nil {
|
||||
log.Error("FindManyVideoPayRecord error", log.Any("filter", f), log.E(err))
|
||||
}
|
||||
type Res struct {
|
||||
TotalAmount float64 `json:"totalAmount" bson:"totalAmount"`
|
||||
}
|
||||
totalIncome := []bson.M{
|
||||
{"$match": f},
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": nil,
|
||||
"totalAmount": bson.M{
|
||||
"$sum": "$publisherIncome",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
ress := make([]Res, 0)
|
||||
if err = coll(nil).Aggregate(&ress, totalIncome); err != nil {
|
||||
log.Error("FindManyVideoPayRecord error", log.Any("filter", f), log.E(err))
|
||||
}
|
||||
if len(ress) > 0 {
|
||||
totalAmount = int64(math.Floor(ress[0].TotalAmount))
|
||||
}
|
||||
total, err = coll(nil).Count(f)
|
||||
if err != nil {
|
||||
log.Error("FindManyVideoPayRecord Count error", log.Any("filter", f), log.E(err))
|
||||
}
|
||||
if len(data) > int(pageSize) {
|
||||
hasNext = true
|
||||
data = data[:pageSize]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetWorksIncomeList 查询收益列表
|
||||
func GetWorksIncomeList(publisherID uint64, page commod.Page) (data []*Pay4VidLog, hasNext bool, err error) {
|
||||
data = make([]*Pay4VidLog, 0)
|
||||
opt := options.Find().
|
||||
SetLimit(page.Limit64() + 1).
|
||||
SetSkip(page.Skip64()).
|
||||
SetSort(bson.D{{"createdAt", -1}})
|
||||
|
||||
filter := bson.M{
|
||||
"publisherID": publisherID,
|
||||
}
|
||||
|
||||
if err = coll(nil).Find(&data, filter, opt); err != nil {
|
||||
log.Error("FindManyVideoPayRecord error", log.Any("filter", filter), log.E(err))
|
||||
return nil, false, err
|
||||
}
|
||||
hasNext = len(data) > int(page.Limit64())
|
||||
if hasNext {
|
||||
data = data[:page.Limit64()]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// PayCoinByCreatedTime 金币
|
||||
func PayCoinByCreatedTime(start time.Time, end time.Time) (int64, error) {
|
||||
pipeline := []bson.M{
|
||||
{
|
||||
"$match": bson.M{
|
||||
// createdAt ∈ [startTime, endTime)
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": nil,
|
||||
"totalAmount": bson.M{"$sum": "$payMoney"},
|
||||
},
|
||||
},
|
||||
}
|
||||
var ret struct {
|
||||
TotalAmount int64 `bson:"totalAmount"`
|
||||
}
|
||||
if err := coll(nil).AggregateDecode(&ret, pipeline); err != nil {
|
||||
return 0, fmt.Errorf("table:%s PayCoinByCreatedTime err: %s", table, err.Error())
|
||||
}
|
||||
return ret.TotalAmount, nil
|
||||
}
|
||||
|
||||
// PayCoinMapByTime vid->金币 map
|
||||
func PayCoinMapByTime(start time.Time, end time.Time) (map[ObjectID]int64, error) {
|
||||
pipeline := []bson.M{
|
||||
{
|
||||
"$match": bson.M{
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": "$videoID",
|
||||
"income": bson.M{
|
||||
"$sum": "$payMoney",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var docList []struct {
|
||||
VID ObjectID `bson:"_id"`
|
||||
Income int64 `bson:"income"`
|
||||
}
|
||||
if err := coll(nil).Aggregate(&docList, pipeline); err != nil {
|
||||
return nil, fmt.Errorf("table:%s PayCoinMapByTime err: %s", table, err.Error())
|
||||
}
|
||||
ret := make(map[ObjectID]int64)
|
||||
for _, doc := range docList {
|
||||
ret[doc.VID] = doc.Income
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func VideoCoinIncomeGross(start, end time.Time) (int64, error) {
|
||||
matchStage := bson.M{
|
||||
"$match": bson.M{
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
},
|
||||
}
|
||||
groupStage := bson.M{
|
||||
"$group": bson.M{
|
||||
"_id": nil,
|
||||
"gross": bson.M{
|
||||
"$sum": "$payMoney",
|
||||
},
|
||||
},
|
||||
}
|
||||
var gross struct {
|
||||
Gross int64 `bson:"gross"`
|
||||
}
|
||||
pipeline := []bson.M{matchStage, groupStage}
|
||||
// opts := options.Aggregate()
|
||||
if err := coll(nil).AggregateDecode(&gross, pipeline); err != nil {
|
||||
log.Error("VideoCoinIncomeGross err: " + err.Error())
|
||||
return 0, errors.Wrapf(err, "table:%s VideoCoinIncomeGross", table)
|
||||
}
|
||||
return gross.Gross, nil
|
||||
}
|
||||
|
||||
// VideoCoinIncomeAggregateByVideoIDs 根据视频ID统计视频的售卖总数以及总金币数
|
||||
func VideoCoinIncomeAggregateByVideoIDs(ids []primitive.ObjectID) (list []VideoCoinIncome, err error) {
|
||||
if len(ids) == 0 {
|
||||
return
|
||||
}
|
||||
matchStage := bson.M{
|
||||
"$match": bson.M{
|
||||
"videoID": bson.M{"$in": ids},
|
||||
},
|
||||
}
|
||||
groupStage := bson.M{
|
||||
"$group": bson.M{
|
||||
"_id": "$videoID",
|
||||
"total": bson.M{
|
||||
"$sum": "$payMoney",
|
||||
},
|
||||
"count": bson.M{
|
||||
"$sum": 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
pipeline := []bson.M{matchStage, groupStage}
|
||||
opts := options.Aggregate().SetMaxTime(10 * time.Second)
|
||||
if err := coll(nil).Aggregate(&list, pipeline, opts); err != nil {
|
||||
return nil, errors.Wrapf(err, "table:%s VideoCoinIncomeAggregateByVideoIDs", table)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// VideoCoinIncomeAggregate 聚合统计在给定时间段内视频收入排名前N的视频
|
||||
func VideoCoinIncomeAggregateTopN(topN int, start, end time.Time) (list []VideoCoinIncome, err error) {
|
||||
matchStage := bson.M{
|
||||
"$match": bson.M{
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
},
|
||||
}
|
||||
groupStage := bson.M{
|
||||
"$group": bson.M{
|
||||
"_id": "$videoID",
|
||||
"total": bson.M{
|
||||
"$sum": "$payMoney",
|
||||
},
|
||||
"count": bson.M{
|
||||
"$sum": 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
sortStage := bson.M{
|
||||
"$sort": bson.M{
|
||||
"total": -1,
|
||||
"count": -1,
|
||||
},
|
||||
}
|
||||
limitStage := bson.M{
|
||||
"$limit": topN,
|
||||
}
|
||||
pipeline := []bson.M{matchStage, groupStage, sortStage, limitStage}
|
||||
opts := options.Aggregate().SetMaxTime(10 * time.Second)
|
||||
if err := coll(nil).Aggregate(&list, pipeline, opts); err != nil {
|
||||
return nil, errors.Wrapf(err, "table:%s VideoCoinIncomeAggregateTopN", table)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// PayCountMapByTime vid->金币 map
|
||||
func PayCountMapByTime(start time.Time, end time.Time) (map[ObjectID]int64, error) {
|
||||
pipeline := []bson.M{
|
||||
{
|
||||
"$match": bson.M{
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": "$videoID",
|
||||
"count": bson.M{
|
||||
"$sum": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var docList []struct {
|
||||
VID ObjectID `bson:"_id"`
|
||||
Count int64 `bson:"count"`
|
||||
}
|
||||
if err := coll(nil).Aggregate(&docList, pipeline); err != nil {
|
||||
return nil, fmt.Errorf("table:%s PayCoinMapByTime err: %s", table, err.Error())
|
||||
}
|
||||
ret := make(map[ObjectID]int64)
|
||||
for _, doc := range docList {
|
||||
ret[doc.VID] = doc.Count
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// TaxAmountMapByTime vid->TaxAmount map
|
||||
func TaxAmountMapByTime(start time.Time, end time.Time) (map[ObjectID]float64, error) {
|
||||
pipeline := []bson.M{
|
||||
{
|
||||
"$match": bson.M{
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": "$videoID",
|
||||
"taxAmount": bson.M{
|
||||
"$sum": "$taxAmount",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var docList []struct {
|
||||
VID ObjectID `bson:"_id"`
|
||||
TaxAmount float64 `bson:"taxAmount"`
|
||||
}
|
||||
if err := coll(nil).Aggregate(&docList, pipeline); err != nil {
|
||||
return nil, fmt.Errorf("table:%s PayCoinMapByTime err: %s", table, err.Error())
|
||||
}
|
||||
ret := make(map[ObjectID]float64)
|
||||
for _, doc := range docList {
|
||||
ret[doc.VID] += doc.TaxAmount
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func PublisherIncomeMapByTime(start time.Time, end time.Time) (map[uint64]int64, error) {
|
||||
pipeline := []bson.M{
|
||||
{
|
||||
"$match": bson.M{
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": "$publisherID",
|
||||
"income": bson.M{
|
||||
"$sum": "$payMoney",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var docList []struct {
|
||||
PublisherID uint64 `bson:"_id"`
|
||||
Income int64 `bson:"income"`
|
||||
}
|
||||
if err := coll(nil).Aggregate(&docList, pipeline); err != nil {
|
||||
return nil, fmt.Errorf("table:%s PublisherIncomeMapByTime err: %s", table, err.Error())
|
||||
}
|
||||
ret := make(map[uint64]int64)
|
||||
for _, doc := range docList {
|
||||
ret[doc.PublisherID] = doc.Income
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// TaxAmountByTime
|
||||
func TaxAmountByTime(start, end time.Time, mats ...Matcher) (float64, error) {
|
||||
mats = append(mats, (&CreatedAtGTEAndLTMatch{GTE: &start, LT: &end}).New())
|
||||
filter := pageopt.MergeM(mats)
|
||||
var list []struct {
|
||||
TaxAmount float64 `bson:"taxAmount"` //税额
|
||||
}
|
||||
opt := (&options.FindOptions{}).SetProjection(M{
|
||||
"taxAmount": 1,
|
||||
})
|
||||
if err := coll(nil).Find(&list, filter, opt); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var taxAmount float64
|
||||
for _, v := range list {
|
||||
taxAmount += v.TaxAmount
|
||||
}
|
||||
return taxAmount, nil
|
||||
}
|
||||
|
||||
func FindByUID(uid uint64, newsType string, pageNumber int64, pageSize int64) (data []*Pay4VidLog, hasNext bool, err error) {
|
||||
data = make([]*Pay4VidLog, 0)
|
||||
opt := options.Find().
|
||||
SetLimit(pageSize + 1).
|
||||
SetSkip((pageNumber - 1) * pageSize).
|
||||
SetSort(bson.D{{"createdAt", -1}})
|
||||
|
||||
filter := bson.M{
|
||||
"uid": uid,
|
||||
"newsType": newsType,
|
||||
}
|
||||
err = coll(nil).Find(&data, filter, opt)
|
||||
if err != nil {
|
||||
log.Error("FindByUID error", log.Any("uid", uid), log.Any("err", err.Error()))
|
||||
return nil, false, err
|
||||
}
|
||||
if len(data) > int(pageSize) {
|
||||
hasNext = true
|
||||
data = data[:pageSize]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func PublisherVideoDeductionRange(uid uint64, start, end time.Time) ([]PublisherDeductionStat, error) {
|
||||
pipeline := []bson.M{
|
||||
{
|
||||
"$match": bson.M{
|
||||
// createdAt ∈ [startTime, endTime)
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
"publisherID": uid,
|
||||
},
|
||||
},
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": "$isVideoDeduction",
|
||||
"totalAmount": bson.M{"$sum": "$coins"},
|
||||
"videoCount": bson.M{"$sum": 1},
|
||||
},
|
||||
},
|
||||
}
|
||||
docList := []PublisherDeductionStat{}
|
||||
return docList, coll(nil).Aggregate(&docList, pipeline)
|
||||
}
|
||||
|
||||
func GetPayVidLogsByTime(start time.Time, end time.Time) ([]Pay4VidLogShort, error) {
|
||||
filter := bson.M{
|
||||
"createdAt": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
}
|
||||
logs := make([]Pay4VidLogShort, 0)
|
||||
if err := coll(nil).Find(&logs, filter); err != nil {
|
||||
return logs, fmt.Errorf("table:%s GetPayMoneyByTime err: %s", table, err.Error())
|
||||
}
|
||||
return logs, nil
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package payvidlgmod
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models/commod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type (
|
||||
ObjectID = primitive.ObjectID
|
||||
|
||||
M = bson.M
|
||||
|
||||
DiscSeqe = commod.DiscSeqe
|
||||
|
||||
DiscDoc = commod.DiscDoc
|
||||
)
|
||||
|
||||
// Pay4VidLog 购买影片记录
|
||||
type Pay4VidLog struct {
|
||||
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // ID
|
||||
UID uint64 `json:"uid" bson:"uid"` // 用户ID
|
||||
Title string `json:"title" bson:"title,required"` // 视频标题
|
||||
NewsType string `json:"newsType" bson:"newsType"` // 类型
|
||||
VideoID primitive.ObjectID `json:"videoID" bson:"videoID"` // 视频id
|
||||
PlayTime uint `json:"playTime" bson:"playTime"` // 影片长度
|
||||
Coins int64 `json:"coins" bson:"coins"` // 定价
|
||||
Tax int64 `json:"tax" bson:"tax"` // 税率
|
||||
TaxAmount float64 `json:"taxAmount" bson:"taxAmount"` // 系统收取的税额 税率*定价
|
||||
PayMoney int64 `json:"payMoney" bson:"payMoney"` // 金币
|
||||
PublisherIncome float64 `json:"publisherIncome" bson:"publisherIncome"` // 上传者实际收益 定价-系统收取的税额
|
||||
PublisherID uint64 `json:"publisherID" bson:"publisherID"` // 上传者ID
|
||||
Uniq string `json:"uniq" bson:"uniq"` // UID.VideoID
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
|
||||
SysType string `json:"sysType" bson:"sysType"` // 系统类型
|
||||
IsVideoDeduction bool `json:"isVideoDeduction" bson:"isVideoDeduction"` // 是否扣量
|
||||
DiscDoc `bson:",inline"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
|
||||
func Unique(uid uint64, videoID primitive.ObjectID) string {
|
||||
list := []string{
|
||||
strconv.FormatInt(int64(uid), 10),
|
||||
videoID.Hex(),
|
||||
}
|
||||
s := strings.Join(list, ".")
|
||||
return s
|
||||
}
|
||||
|
||||
type VideoCoinIncome struct {
|
||||
VID ObjectID `bson:"_id" json:"videoID"` //video id
|
||||
Total int64 `bson:"total" json:"total"` //视频总金币
|
||||
Count int64 `bson:"count" json:"count"` //视频购买总次数
|
||||
}
|
||||
|
||||
type PublisherDeductionStat struct {
|
||||
IsVideoDeduction bool `bson:"_id"` // 是否扣量
|
||||
TotalAmount int64 `bson:"totalAmount"` // 视频总售卖(金币)
|
||||
VideoCount int64 `bson:"videoCount"` // 总计视频数
|
||||
}
|
||||
|
||||
// Pay4VidLogShort 购买影片短结构
|
||||
type Pay4VidLogShort struct {
|
||||
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
|
||||
VideoID primitive.ObjectID `json:"videoID" bson:"videoID"`
|
||||
PayMoney int64 `json:"payMoney" bson:"payMoney"` //金币
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package playlgmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
// PlayLog 观看记录
|
||||
type PlayLog struct {
|
||||
UID uint64 `json:"uid" bson:"uid"`
|
||||
VideoID primitive.ObjectID `json:"videoID" bson:"videoID"`
|
||||
Longer int `json:"longer" bson:"longer"` //播放时长 单位:秒
|
||||
Progress int `json:"progress" bson:"progress"`
|
||||
Via int `json:"via" bson:"via"`
|
||||
PlayWay int `json:"playWay" bson:"playWay"` //0,免费 1付费 2.试看
|
||||
TagID primitive.ObjectID `json:"tagID" bson:"tagID,omitempty"`
|
||||
Publisher uint64 `json:"publisher" bson:"publisher,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
}
|
||||
|
||||
type GroupKey struct {
|
||||
VideoID primitive.ObjectID `bson:"videoID"`
|
||||
TagID primitive.ObjectID `bson:"tagID"`
|
||||
}
|
||||
|
||||
type TagPlayCount struct {
|
||||
GroupID GroupKey `bson:"_id"`
|
||||
PlayCount int64 `bson:"playCount"`
|
||||
}
|
||||
|
||||
type TagPlayInfo struct {
|
||||
VideoID primitive.ObjectID
|
||||
TagID primitive.ObjectID
|
||||
PlayCount int64
|
||||
}
|
||||
|
||||
// TagIDCount 观看过的tagID统计
|
||||
type TagIDCount struct {
|
||||
TagID primitive.ObjectID `bson:"_id"`
|
||||
Count int `bson:"count"`
|
||||
}
|
||||
|
||||
// UIDCount 用户观看次数
|
||||
type UIDCount struct {
|
||||
UID uint64 `bson:"_id"`
|
||||
Count int `bson:"count"`
|
||||
}
|
||||
|
||||
// VidCount 视频观看次数
|
||||
type VidCount struct {
|
||||
//视频id
|
||||
VideoID primitive.ObjectID `json:"videoID" bson:"_id"`
|
||||
//次数
|
||||
Count int `bson:"count"`
|
||||
}
|
||||
|
||||
// PublisherCount 博主被观看次数
|
||||
type PublisherCount struct {
|
||||
//上传者id
|
||||
Publisher uint64 `json:"publisher" bson:"_id,omitempty"`
|
||||
//次数
|
||||
Count int `bson:"count"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package playlgmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/models/commod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// WatchReq 观看日志查询请求参数
|
||||
type WatchReq struct {
|
||||
PlayWay int `form:"playWay" json:"playWay"`
|
||||
UID uint64 `form:"uid" json:"uid"`
|
||||
Start time.Time `form:"start" json:"start"`
|
||||
End time.Time `form:"end" json:"end"`
|
||||
commod.Page
|
||||
}
|
||||
|
||||
// LogInfo 返回数据
|
||||
type LogInfo struct {
|
||||
UID uint64 `json:"uid"`
|
||||
VideoID primitive.ObjectID `json:"videoID"`
|
||||
Title string `json:"title"`
|
||||
PlayTime uint `json:"playTime"`
|
||||
Longer int `json:"longer" `
|
||||
Progress int `json:"progress"`
|
||||
Via int `json:"via"`
|
||||
PlayWay int `json:"playWay"` //0,免费 1付费 2.试看
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
// WatchResp 观看日志查询请求应答
|
||||
type WatchResp struct {
|
||||
Logs []*LogInfo `json:"logs"`
|
||||
Total uint64 `json:"total"`
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package pullgmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.PullLog
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// initIndex 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "createdAt", Value: -1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "newUpdatedAt", Value: -1}},
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
// InsertPullLog InsertPullLog
|
||||
func InsertPullLog(p PullLog) error {
|
||||
_, err := coll(nil).InsertOne(&p)
|
||||
return err
|
||||
}
|
||||
|
||||
// FindPullRecord 查询
|
||||
func FindPullRecord(vidType, newUpdateAt string) (pr *PullLog, err error) {
|
||||
opts := options.FindOne().SetSort(bson.D{{Key: "createdAt", Value: -1}})
|
||||
cond := bson.M{}
|
||||
if vidType != "" {
|
||||
cond["vidType"] = vidType
|
||||
}
|
||||
if newUpdateAt != "" {
|
||||
cond["newUpdatedAt"] = newUpdateAt
|
||||
}
|
||||
if err = coll(nil).FindOne(&pr, cond, opts); err != nil {
|
||||
log.Error("FindPullRecord error", log.E(err))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package pullgmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
)
|
||||
|
||||
// PullLog 从aws同步视频记录
|
||||
type PullLog struct {
|
||||
LastID string `json:"lastId" bson:"lastId"`
|
||||
Count int `json:"count" bson:"count"`
|
||||
FailCount int `json:"failCount" bson:"failCount"`
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
FailIDs []string `json:"failIDs" bson:"failIDs,omitempty"`
|
||||
VidType string `json:"vidType" bson:"vidType"`
|
||||
NewUpdatedAt string `json:"newUpdatedAt" bson:"newUpdatedAt"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package registermod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.NewRegister
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// initIndex 设置index
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
|
||||
{
|
||||
Keys: bson.D{{Key: "uid", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "ip", 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 InsertRegisterLog(l *NewRegisterLog) error {
|
||||
if _, err := coll(nil).InsertOne(l); err != nil {
|
||||
log.Error("loginlog insert err", log.E(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DeleteBeforeCreatedAt(t *db.MongoTool, tm time.Time) error {
|
||||
_, err := coll(t).DeleteMany(bson.M{"createdAt": bson.M{"$lt": tm}})
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package registermod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
)
|
||||
|
||||
// 新注册用户Log 接口调用记录
|
||||
type NewRegisterLog struct {
|
||||
UID uint64 `json:"uid" bson:"uid"`
|
||||
IP string `json:"ip" bson:"ip"`
|
||||
Query []QueryStat `json:"query" bson:"query"` //接口调用次数记录表
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
}
|
||||
|
||||
type QueryStat struct {
|
||||
QueryUrl string `json:"key" bson:"key"`
|
||||
Count int64 `json:"count" bson:"count"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package searchlogmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/constant"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/commod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.SearchLog
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// InitIndex 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "createdAt", Value: -1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "uid", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "realm", Value: 1}}, //不会新建 realm 索引
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "realm", Value: 1}, {Key: "keyword", Value: 1}}, //不会新建 realm 索引
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
// FindHotSearch 根据搜索量获取热搜排行榜
|
||||
func FindHotSearch(realm constant.RealmType, page commod.Page) ([]SearchCount, error) {
|
||||
p := []M{
|
||||
{
|
||||
"$match": M{"realm": realm},
|
||||
},
|
||||
{
|
||||
"$group": M{"_id": "$keyword", "count": M{"$sum": 1}},
|
||||
},
|
||||
{
|
||||
"$match": M{"_id": M{"$ne": ""}},
|
||||
},
|
||||
{
|
||||
"$sort": bson.D{{Key: "count", Value: -1}},
|
||||
},
|
||||
{
|
||||
"$skip": (page.PageNumber - 1) * page.PageSize,
|
||||
},
|
||||
{
|
||||
"$limit": page.PageSize,
|
||||
},
|
||||
}
|
||||
data := make([]SearchCount, 0, page.PageSize)
|
||||
if err := coll(nil).Aggregate(&data, p); err != nil {
|
||||
log.ZapLog.Error(fmt.Sprintf("models record SearchLog FindSearchCountVid fail error:%+v:", err))
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// InsertMany InsertMany
|
||||
func InsertMany(uid uint64, realm constant.RealmType, keyWords []string) error {
|
||||
now := time.Now()
|
||||
searchLogDoc := make([]SearchLogDoc, 0, len(keyWords))
|
||||
for _, keyword := range keyWords {
|
||||
if keyword == "" {
|
||||
continue
|
||||
}
|
||||
searchLogDoc = append(searchLogDoc, SearchLogDoc{
|
||||
Realm: realm,
|
||||
UID: uid,
|
||||
Keyword: keyword,
|
||||
CreatedAt: now,
|
||||
})
|
||||
}
|
||||
if len(searchLogDoc) == 0 {
|
||||
return nil
|
||||
}
|
||||
if _, err := coll(nil).InsertMany(&searchLogDoc); err != nil {
|
||||
log.ZapLog.Error("SearchLog InsertMany error", log.E(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetKeywordCountMapByTime(start time.Time, end time.Time, realm constant.RealmType) (map[string]int64, error) {
|
||||
pipeline := []M{
|
||||
{
|
||||
"$match": M{
|
||||
"createdAt": M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
"realm": realm,
|
||||
},
|
||||
},
|
||||
{
|
||||
"$sortByCount": "$keyword",
|
||||
},
|
||||
}
|
||||
list := []struct {
|
||||
Keyword string `bson:"_id"`
|
||||
Count int64 `bson:"count"`
|
||||
}{}
|
||||
if err := coll(nil).Aggregate(&list, pipeline); err != nil {
|
||||
return nil, fmt.Errorf("GetKeywordCountMapByTime err: %s", err.Error())
|
||||
}
|
||||
m := make(map[string]int64, len(list))
|
||||
for _, v := range list {
|
||||
m[v.Keyword] = v.Count
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// 根据时间段获取搜索日志
|
||||
func GetSearchLogByTimeRange(start time.Time, end time.Time) (data []SearchLog, err error) {
|
||||
var query = bson.M{
|
||||
"createdAt": bson.M{"$gte": start, "$lt": end},
|
||||
}
|
||||
if err = coll(nil).Find(&data, query); err != nil {
|
||||
log.Error("models SearchLog model GetSearchLogByTimeRange error", log.E(err))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func DeleteBeforeCreatedAt(t *db.MongoTool, tm time.Time) error {
|
||||
_, err := coll(t).DeleteMany(bson.M{"createdAt": bson.M{"$lt": tm}})
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package searchlogmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/constant"
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type (
|
||||
SearchLogDoc = SearchLog
|
||||
|
||||
ObjectID = primitive.ObjectID
|
||||
|
||||
M = bson.M
|
||||
)
|
||||
|
||||
// SearchLog 搜索记录
|
||||
type SearchLog struct {
|
||||
ID ObjectID `json:"id" bson:"_id,omitempty"`
|
||||
Realm constant.RealmType `json:"realm" bson:"realm"` //搜索区域 综合:complex 视频:video 用户:user 话题:tag 地点:site
|
||||
UID uint64 `json:"uid" bson:"uid"` //搜索人ID
|
||||
Keyword string `json:"keyword" bson:"keyword"` //搜索的关键字
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //搜索的时间
|
||||
}
|
||||
|
||||
// SearchLog 搜索记录
|
||||
type ESSearchLogSource struct {
|
||||
ID ObjectID `json:"id"`
|
||||
Realm constant.RealmType `json:"realm"` //搜索区域 综合:complex 视频:video 用户:user 话题:tag 地点:site
|
||||
UID uint64 `json:"uid"` //搜索人ID
|
||||
Keyword string `json:"keyword"` //搜索的关键字
|
||||
CreatedAt time.Time `json:"createdAt"` //搜索的时间
|
||||
}
|
||||
|
||||
// SearchCount 热搜视频统计最高多搜索次数的视频
|
||||
type SearchCount struct {
|
||||
KeyWord string `json:"keyWord" bson:"_id"` //关键字
|
||||
Count int `json:"count" bson:"count"` //关键字搜索次数
|
||||
}
|
||||
|
||||
// SearchResp SearchResp
|
||||
type SearchResp struct {
|
||||
TagName string `json:"id" bson:"_id,omitempty"`
|
||||
Count int `json:"count" bson:"count,omitempty"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package synccdnmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.SyncCdnLog
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// initIndex 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
// InsertSyncCdnLog InsertSyncCdnLog
|
||||
func InsertSyncCdnLog(p SyncCdnLog) error {
|
||||
_, err := coll(nil).InsertOne(&p)
|
||||
return err
|
||||
}
|
||||
|
||||
// FindSyncRecord 查询
|
||||
func FindSyncRecord() (pr []SyncCdnLog, err error) {
|
||||
pr = []SyncCdnLog{}
|
||||
cond := []bson.M{
|
||||
bson.M{
|
||||
"$sort": bson.M{"createdAt": -1},
|
||||
},
|
||||
bson.M{
|
||||
"$limit": 1}}
|
||||
if err = coll(nil).Aggregate(&pr, cond); err != nil {
|
||||
log.Error("FindSyncRecord error", log.E(err))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package synccdnmod
|
||||
|
||||
import (
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/stderr"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
AccessKey = "4qQTNUrg9MloxqtykJbkf9BTeJ3liBo5fS7Qg6Nu"
|
||||
SecretKey = "axcamr082kQaJx87ebqkGHNPy-9EBeoTT2XbU6A2"
|
||||
//AccessKey = "MY_ACCESS_KEY"
|
||||
//SecretKey = "MY_SECRET_KEY"
|
||||
URl = "http://rs.qiniu.com/move/bmV3ZG9jczpmaW5kX21hbi50eHQ=/bmV3ZG9jczpmaW5kLm1hbi50eHQ="
|
||||
|
||||
Host string = "http://fusion.qiniuapi.com" //域名
|
||||
FetchUrl string = "/v2/tune/prefetch" //预取接口
|
||||
PreFetchUrl string = "/v2/tune/prefetch/list" //预期查询接口地址
|
||||
|
||||
)
|
||||
|
||||
// SyncHttpResp 返回结构体
|
||||
type SyncHttpResp struct {
|
||||
Code stderr.Code `json:"code"`
|
||||
Error string `json:"error"`
|
||||
RequestId string `json:"requestId"`
|
||||
InvalidUrls []string `json:"invalidUrls"`
|
||||
QuotaDay int `json:"quotaDay"`
|
||||
SurplusDay int `json:"surplusDay"`
|
||||
}
|
||||
|
||||
type SyncCdnLog struct {
|
||||
RequestIds []string `json:"requestIds" bson:"requestIds"`
|
||||
LastID string `json:"lastId" bson:"lastId"`
|
||||
Count int `json:"count" bson:"count"`
|
||||
FailCount int `json:"failCount" bson:"failCount"`
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
FailIDs []string `json:"failIDs" bson:"failIDs,omitempty"`
|
||||
}
|
||||
|
||||
// SyncReq 前端参数传递
|
||||
type SyncReq struct {
|
||||
Token string `json:"token" binding:"required"`
|
||||
Cdn string `json:"cdn"`
|
||||
FilePath string `json:"filePath"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package userdailytasklogmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/dailytaskmod"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.UserDailyTaskLog
|
||||
|
||||
// InitIndex 设置index
|
||||
func initIndex() {
|
||||
coll := coll(nil)
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "uid", Value: 1}, {Key: "type", Value: 1}, {Key: "date", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
}
|
||||
if _, err := coll.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)
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
|
||||
type UserDailyTask struct {
|
||||
ID primitive.ObjectID `json:"_id" bson:"_id"`
|
||||
UID uint64 `json:"uid" bson:"uid"`
|
||||
Type int `json:"type" bson:"type"` // 0 每日广告点击; 1 每日任务
|
||||
Date string `json:"date" bson:"date"` // 日期. 格式 2006-01-02
|
||||
FinishCount uint64 `json:"finishCount" bson:"finishCount"` // 当日完成次数
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"`
|
||||
}
|
||||
|
||||
func CompleteDailyTask(uid uint64, taskType int64, completeTime uint64) error {
|
||||
_, err := coll(nil).UpsertOne(bson.M{"uid": uid, "type": taskType, "date": time.Now().Format("2006-01-02")}, bson.M{"$inc": bson.M{"finishCount": completeTime}})
|
||||
return err
|
||||
}
|
||||
|
||||
func GetUserFinishCount(uid uint64, taskType dailytaskmod.DailyTaskTypeEnum) (uint64, error) {
|
||||
var udk UserDailyTask
|
||||
if err := coll(nil).FindOne(&udk, bson.M{"uid": uid, "type": taskType, "date": time.Now().Format("2006-01-02")}); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if udk.ID.IsZero() {
|
||||
return 0, nil
|
||||
}
|
||||
return udk.FinishCount, nil
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package visitlogmod
|
||||
|
||||
import (
|
||||
"91porn-server/common/pageopt"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type VisitLogSlice []VisitLog
|
||||
|
||||
func (v VisitLogSlice) ToUIDs() []uint64 {
|
||||
uids := make([]uint64, len(v))
|
||||
for i, l := range v {
|
||||
uids[i] = l.UID
|
||||
}
|
||||
return uids
|
||||
}
|
||||
|
||||
type Matcher = pageopt.Matcher
|
||||
|
||||
// CreatedAtGTEAndLTMatch
|
||||
type CreatedAtGTEAndLTMatch = pageopt.CreatedAtGTEAndLTMatch
|
||||
|
||||
func List(sort bson.D, skip, limit *int64, mats ...Matcher) (VisitLogSlice, error) {
|
||||
opt := (&options.FindOptions{})
|
||||
if len(sort) != 0 {
|
||||
opt.SetSort(sort)
|
||||
}
|
||||
if skip != nil {
|
||||
opt.SetSkip(*skip)
|
||||
}
|
||||
if limit != nil {
|
||||
opt.SetLimit(*limit)
|
||||
}
|
||||
filter := pageopt.MergeM(mats)
|
||||
list := VisitLogSlice{}
|
||||
return list, coll(nil).Find(&list, filter, opt)
|
||||
}
|
||||
|
||||
func Count(matchs ...pageopt.Matcher) (int64, error) {
|
||||
filter := pageopt.MergeM(matchs)
|
||||
return coll(nil).Count(filter)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package visitlogmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// 以天为单位,统计用户的首次访问的日志
|
||||
type VisitLog struct {
|
||||
ID *primitive.ObjectID `json:"id" bson:"_id,omitempty"` //记录Id
|
||||
SumDate time.Time `json:"sumDate" bson:"sumDate"` //每日零点
|
||||
UID uint64 `json:"uid" bson:"uid"` //用户ID
|
||||
IP string `json:"ip" bson:"ip"` //IP
|
||||
SysType string `json:"sysType" bson:"sysType"` //操作系统类型 安卓 IOS
|
||||
Ver string `json:"ver" bson:"ver"` //APP版本号
|
||||
DevType string `json:"devType" bson:"devType"` //设备型号
|
||||
DevID string `json:"devID" bson:"devID"` //设备ID
|
||||
BuildID string `json:"buildID" bson:"buildID"` //app构建ID(包ID)
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //创建时间
|
||||
|
||||
IsDirect bool `json:"isDirect" bson:"isDirect"` // true:是直推用户
|
||||
DistrictCode string `json:"districtCode" bson:"districtCode"` // 渠道码
|
||||
RegisterTime time.Time `json:"registerTime" bson:"registerTime"` //用户注册时间
|
||||
IsDeduction bool `json:"isDeduction" bson:"isDeduction"` // true:CPA扣量用户
|
||||
}
|
||||
|
||||
type FilterDoc struct {
|
||||
SumDate time.Time `bson:"sumDate"` //每日零点
|
||||
UID uint64 `bson:"uid"` //用户ID
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package visitlogmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/pageopt"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/v/usermod"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.VisitLog
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// InitIndex 设置index
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
|
||||
{
|
||||
Keys: bson.D{{Key: "uid", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: -1}, {Key: "uid", 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 DataClean(deleteAt time.Time) (int64, error) {
|
||||
res, err := coll(nil).DeleteMany(bson.M{"createdAt": bson.M{"$lt": deleteAt}})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return res.DeletedCount, nil
|
||||
}
|
||||
|
||||
func UpsertUserVisit(l *VisitLog) (*mongo.UpdateResult, error) {
|
||||
l.CreatedAt = time.Now()
|
||||
b, _ := bson.Marshal(l)
|
||||
m := bson.M{}
|
||||
_ = bson.Unmarshal(b, &m)
|
||||
return coll(nil).UpsertOne(bson.M{"sumDate": l.SumDate, "uid": l.UID}, bson.M{"$setOnInsert": m})
|
||||
}
|
||||
|
||||
func UIDListByCreatedTime(start time.Time, end time.Time, mats ...Matcher) ([]uint64, error) {
|
||||
list := []struct {
|
||||
UID uint64 `bson:"uid"` //用户ID
|
||||
}{}
|
||||
mats = append(mats, (&CreatedAtGTEAndLTMatch{GTE: &start, LT: &end}).New())
|
||||
filter := pageopt.MergeM(mats)
|
||||
opt := (&options.FindOptions{}).SetProjection(bson.M{
|
||||
"uid": 1,
|
||||
})
|
||||
if err := coll(nil).Find(&list, filter, opt); err != nil {
|
||||
log.Error("UIDListByCreatedTime failed", log.Any("filter", filter), log.E(err))
|
||||
return nil, err
|
||||
}
|
||||
uids := make([]uint64, len(list))
|
||||
for i, v := range list {
|
||||
uids[i] = v.UID
|
||||
}
|
||||
return uids, nil
|
||||
}
|
||||
|
||||
func GetSumDateCountMap(uidList []uint64) (map[uint64]int64, error) {
|
||||
if len(uidList) == 0 {
|
||||
return make(map[uint64]int64), nil
|
||||
}
|
||||
pipeLine := []bson.M{
|
||||
{
|
||||
"$match": bson.M{
|
||||
"uid": bson.M{
|
||||
"$in": uidList,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": "$uid",
|
||||
"count": bson.M{
|
||||
"$sum": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
list := make([]struct {
|
||||
UID uint64 `bson:"_id"`
|
||||
Count int64 `bson:"count"`
|
||||
}, 0, len(uidList))
|
||||
if err := coll(nil).Aggregate(&list, pipeLine); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
countMap := make(map[uint64]int64, len(list))
|
||||
for _, v := range list {
|
||||
countMap[v.UID] = v.Count
|
||||
}
|
||||
return countMap, nil
|
||||
}
|
||||
|
||||
// RetainUserListByTime 存留user
|
||||
func RetainUserListByTime(createUserStart, createUserEnd, visitStart, visitEnd time.Time, mats ...usermod.Matcher) ([]usermod.User, error) {
|
||||
visitFilter := (&CreatedAtGTEAndLTMatch{GTE: &visitStart, LT: &visitEnd}).New().Filter()
|
||||
visitList := make([]struct {
|
||||
UID uint64 `bson:"uid"`
|
||||
}, 0)
|
||||
visitOpt := (&options.FindOptions{}).SetProjection(bson.M{
|
||||
"uid": 1,
|
||||
})
|
||||
if err := coll(nil).Find(&visitList, visitFilter, visitOpt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
visitUIDList := make([]uint64, len(visitList))
|
||||
for i, v := range visitList {
|
||||
visitUIDList[i] = v.UID
|
||||
}
|
||||
return usermod.UserListByCreateTimeAndUIDS(createUserStart, createUserEnd, visitUIDList, mats...)
|
||||
}
|
||||
|
||||
// RetainUIDListByTime 存留UID
|
||||
func RetainUIDListByTime(createStart, createEnd, visitStart, visitEnd time.Time, mats ...usermod.Matcher) ([]uint64, error) {
|
||||
visitList := make([]struct {
|
||||
UID uint64 `bson:"uid"`
|
||||
}, 0)
|
||||
visitFilter := (&CreatedAtGTEAndLTMatch{GTE: &visitStart, LT: &visitEnd}).New().Filter()
|
||||
visitOpt := (&options.FindOptions{}).SetProjection(bson.M{
|
||||
"uid": 1,
|
||||
})
|
||||
if err := coll(nil).Find(&visitList, visitFilter, visitOpt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
visitUIDList := make([]uint64, len(visitList))
|
||||
for i, v := range visitList {
|
||||
visitUIDList[i] = v.UID
|
||||
}
|
||||
return usermod.UIDListByCreateTimeAndUIDS(createStart, createEnd, visitUIDList, mats...)
|
||||
}
|
||||
|
||||
// AccessSyncById 每日访问数据同步
|
||||
func AccessSyncById(Id string, size int64) (data []VisitLog, err error) {
|
||||
id, err := primitive.ObjectIDFromHex(Id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
endTime := time.Now().Add(-time.Minute * 5)
|
||||
visitFilter := bson.M{"_id": bson.M{"$gt": id}, "createdAt": bson.M{"$lt": endTime}}
|
||||
visitOpt := (&options.FindOptions{}).SetLimit(size).SetSort(bson.M{"_id": 1})
|
||||
err = coll(nil).Find(&data, visitFilter, visitOpt)
|
||||
return
|
||||
}
|
||||
|
||||
func AccessSyncByTime(visitTime time.Time, size int64) (data []VisitLog, err error) {
|
||||
endTime := time.Now().Add(-time.Minute * 5)
|
||||
visitFilter := bson.M{"createdAt": bson.M{"$gt": visitTime, "$lt": endTime}}
|
||||
visitOpt := (&options.FindOptions{}).SetLimit(size).SetSort(bson.M{"createdAt": 1})
|
||||
err = coll(nil).Find(&data, visitFilter, visitOpt)
|
||||
return
|
||||
}
|
||||
|
||||
func GetInfoByCond(cond bson.M, opts ...*options.FindOneOptions) (VisitLog, error) {
|
||||
v := VisitLog{}
|
||||
if err := coll(nil).FindOne(&v, cond, opts...); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetInfo", table, "FindOne", err),
|
||||
log.Any("cond", cond),
|
||||
)
|
||||
return v, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package welfarelgmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.WelfareLog
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// initIndex 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "uid", Value: -1}, {Key: "fareType", Value: -1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
}, {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
// InsertWelFareLog InsertWelFareLog
|
||||
func InsertWelFareLog(p WelfareLog) error {
|
||||
_, err := coll(nil).InsertOne(&p)
|
||||
return err
|
||||
}
|
||||
|
||||
// FindWelFareByUid 查询
|
||||
func FindWelFareByUid(uid uint64) (pr *WelfareLog, err error) {
|
||||
if err = coll(nil).FindOne(&pr, bson.M{"uid": uid}); err != nil {
|
||||
log.Error("FindWelFareByUid error", log.E(err))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package welfarelgmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type WelFareType int64
|
||||
|
||||
const (
|
||||
Fare_Vip WelFareType = iota //vip
|
||||
Fare_Coin //金币
|
||||
)
|
||||
|
||||
// 福利添加记录
|
||||
type WelfareLog struct {
|
||||
Id primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`
|
||||
Uid uint64 `json:"uid" bson:"uid"`
|
||||
FareType WelFareType `json:"fareType" bson:"fareType"`
|
||||
FareNum int64 `json:"fareNum" bson:"fareNum"`
|
||||
DailyDate time.Time `json:"dailyDate" bson:"dailyDate"`
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package dailyretentionmod
|
||||
|
||||
import (
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"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.DailyRetention
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{
|
||||
{Key: "date", Value: -1},
|
||||
},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{
|
||||
{Key: "createdAt", Value: -1},
|
||||
},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{
|
||||
{Key: "adGroup", Value: 1},
|
||||
{Key: "date", Value: -1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
// Init 初始化索引
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
|
||||
// QueryAllList 分页查询文档
|
||||
func QueryAllList(filter primitive.M, opts ...*options.FindOptions) (out []*DailyRetention, err error) {
|
||||
if err = coll(nil).Find(&out, filter, opts...); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllList", table, "Find", err),
|
||||
log.Any("filter", filter),
|
||||
log.Any("opts", opts),
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// QueryOne
|
||||
func QueryOne(filter bson.M) (*DailyRetention, error) {
|
||||
v := DailyRetention{}
|
||||
if err := coll(nil).FindOne(&v, filter); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryOne", table, "FindOne", err),
|
||||
log.Any("filter", filter),
|
||||
)
|
||||
return &v, err
|
||||
}
|
||||
|
||||
if v.Id.IsZero() {
|
||||
return nil, errors.New("record not found")
|
||||
}
|
||||
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
// UpsertOne
|
||||
func UpsertOne(filter bson.M, updateData bson.M) (err error) {
|
||||
if _, err = coll(nil).UpsertOne(filter, updateData); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpsertOne", table, "UpdateOne", err),
|
||||
log.Any("filter", filter),
|
||||
log.Any("updateData", updateData),
|
||||
)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func BulkWrite(models []mongo.WriteModel, opts ...*options.BulkWriteOptions) (err error) {
|
||||
if len(models) == 0 {
|
||||
return nil
|
||||
}
|
||||
if _, err = coll(nil).Bulk(models, opts...); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "BulkWrite", table, "BulkWrite", err),
|
||||
log.Any("modelsCount", len(models)),
|
||||
)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Distinct(filter bson.M, fieldName string, opts ...*options.DistinctOptions) (out []*DailyRetention, err error) {
|
||||
raw, err := coll(nil).Distinct(fieldName, filter, opts...)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Distinct", table, "UpdateOne", err),
|
||||
log.Any("fieldName", fieldName),
|
||||
log.Any("filter", filter),
|
||||
)
|
||||
return
|
||||
}
|
||||
out = make([]*DailyRetention, len(raw))
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package dailyretentionmod
|
||||
|
||||
import (
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models/commod"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const (
|
||||
MaxRetentionDays = 30 // 最大留存天数
|
||||
)
|
||||
|
||||
// DailyRetention 每日用户留存统计
|
||||
// @table:daily_retention
|
||||
// @model:DailyRetentionModel
|
||||
type DailyRetention struct {
|
||||
Id primitive.ObjectID `json:"id" bson:"_id"` // 自增ID
|
||||
Date time.Time `json:"date" bson:"date" index:"date_idx, date_adgroup_idx:unique"` // 日期,当日0点
|
||||
AdGroup commod.AdGroup `json:"adGroup" bson:"adGroup" index:"adgroup_idx, date_adgroup_idx:unique"` // 广告组
|
||||
NewUsers int64 `json:"newUsers" bson:"newUsers"` // 当天新增用户
|
||||
UserRetained map[int]int64 `json:"userRetained" bson:"userRetained"` // key = 第几天, value = 日活留存人数
|
||||
UserRates map[int]float64 `json:"userRates" bson:"userRates"` // key = 第几天, value = 日活留存率
|
||||
AdClickAcc map[int]int64 `json:"adClickAcc" bson:"adClickAcc"` // key = 第几天, value = 广告点击累计
|
||||
TotalClickAcc map[int]int64 `json:"totalClickAcc" bson:"totalClickAcc"` // key = 第几天, value = 总点击累计
|
||||
PayCountAcc map[int]int64 `json:"payCountAcc" bson:"payCountAcc"` // key = 第几天, value = 充值次数累计
|
||||
PayTotalAcc map[int]int64 `json:"payTotalAcc" bson:"payTotalAcc"` // key = 第几天, value = 充值总金额累计
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt" index:"-created_at_idx"` // 创建时间
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package hotstatmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/timeutil/timerange"
|
||||
"91porn-server/models"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.NewsHot
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// InitIndex 设置index
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: 1}, {Key: "videoID", Value: 1}},
|
||||
Options: options.Index(),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: 1}, {Key: "todayHot", Value: -1}},
|
||||
Options: options.Index(),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: 1}, {Key: "weekHot", Value: -1}},
|
||||
Options: options.Index(),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: 1}, {Key: "monthHot", Value: -1}},
|
||||
Options: options.Index(),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "createdAt", Value: 1}},
|
||||
Options: options.Index(),
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateInsertHotValue 更新热度数值,没有就插入
|
||||
func UpdateInsertHotValue(sumDate time.Time, mDayli map[primitive.ObjectID]int, mWeek map[primitive.ObjectID]int, mMonth map[primitive.ObjectID]int, mNow map[primitive.ObjectID]int) error {
|
||||
writes := make([]mongo.WriteModel, len(mNow))
|
||||
i := 0
|
||||
for vid, v := range mNow {
|
||||
filter := bson.M{
|
||||
"sumDate": sumDate,
|
||||
"videoID": vid,
|
||||
}
|
||||
update := bson.M{
|
||||
"$setOnInsert": bson.M{
|
||||
"sumDate": sumDate,
|
||||
"videoID": vid,
|
||||
"createdAt": time.Now(),
|
||||
},
|
||||
"$set": bson.M{
|
||||
"todayHot": mDayli[vid],
|
||||
"weekHot": mWeek[vid],
|
||||
"monthHot": mMonth[vid],
|
||||
"totalHot": v,
|
||||
"updatedAt": time.Now(),
|
||||
},
|
||||
}
|
||||
writes[i] = mongo.NewUpdateOneModel().SetFilter(filter).SetUpdate(update).SetUpsert(true)
|
||||
i++
|
||||
log.Debug(fmt.Sprintf("sumDate:%s table:%s [filter:%+v update:%+v ]\n", sumDate, table, filter, update))
|
||||
}
|
||||
if len(writes) == 0 {
|
||||
return nil
|
||||
}
|
||||
//bulkWrite 不是原子操作 不具备事务性
|
||||
opt := (&options.BulkWriteOptions{}).SetOrdered(false) //设为无序,触发并行写,提升写效率
|
||||
_, err := coll(nil).Bulk(writes, opt)
|
||||
return err
|
||||
}
|
||||
|
||||
func getHotValue(page, size uint64, cond bson.M, sort bson.D) ([]*HotStat, bool, error) {
|
||||
hasNext := false
|
||||
skip := (page - 1) * size
|
||||
opts := options.FindOptions{}
|
||||
if sort != nil {
|
||||
opts.SetSort(sort)
|
||||
}
|
||||
opts.SetSkip(int64(skip)).SetLimit(int64(size + 1))
|
||||
var back []*HotStat
|
||||
if err := coll(nil).Find(&back, cond, &opts); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "getHotValue", table, "Find", err),
|
||||
log.Any("page", page),
|
||||
log.Any("size", size),
|
||||
log.Any("cond", cond),
|
||||
log.Any("sort", sort),
|
||||
)
|
||||
return nil, hasNext, err
|
||||
}
|
||||
if uint64(len(back)) > size {
|
||||
hasNext = true
|
||||
back = back[:size]
|
||||
}
|
||||
return back, hasNext, nil
|
||||
}
|
||||
|
||||
func getSortedVideoID(page, size uint64, cond bson.M, sort bson.D) ([]primitive.ObjectID, bool, error) {
|
||||
ids := []primitive.ObjectID{}
|
||||
infos, hasNext, err := getHotValue(page, size, cond, sort)
|
||||
if err != nil {
|
||||
return ids, false, err
|
||||
}
|
||||
ids = make([]primitive.ObjectID, len(infos))
|
||||
for i, v := range infos {
|
||||
ids[i] = v.VideoID
|
||||
}
|
||||
return ids, hasNext, err
|
||||
}
|
||||
|
||||
// GetHotValueToday 查找热度值
|
||||
func GetHotValueToday(page, size uint64) ([]primitive.ObjectID, bool, error) {
|
||||
sumDate := timerange.LocDayRange(time.Now()).Head
|
||||
cond := bson.M{"sumDate": sumDate}
|
||||
sort := bson.D{{Key: "todayHot", Value: -1}}
|
||||
return getSortedVideoID(page, size, cond, sort)
|
||||
}
|
||||
|
||||
// GetHotValueWeek 查找热度值
|
||||
func GetHotValueWeek(page, size uint64) ([]primitive.ObjectID, bool, error) {
|
||||
sumDate := timerange.LocDayRange(time.Now()).Head
|
||||
cond := bson.M{"sumDate": sumDate}
|
||||
sort := bson.D{{Key: "weekHot", Value: -1}}
|
||||
return getSortedVideoID(page, size, cond, sort)
|
||||
}
|
||||
|
||||
// GetHotValueMonth 查找热度值
|
||||
func GetHotValueMonth(page, size uint64) ([]primitive.ObjectID, bool, error) {
|
||||
sumDate := timerange.LocDayRange(time.Now()).Head
|
||||
cond := bson.M{"sumDate": sumDate}
|
||||
sort := bson.D{{Key: "monthHot", Value: -1}}
|
||||
return getSortedVideoID(page, size, cond, sort)
|
||||
}
|
||||
|
||||
func getHotValueByDate(dt time.Time) (map[primitive.ObjectID]int, error) {
|
||||
var infos []*HotStat
|
||||
mValue := make(map[primitive.ObjectID]int)
|
||||
if err := coll(nil).Find(&infos, bson.M{"sumDate": dt}); err != nil {
|
||||
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "getHotValue", table, "Find", err))
|
||||
return mValue, err
|
||||
}
|
||||
for _, v := range infos {
|
||||
mValue[v.VideoID] = v.TotalHot
|
||||
}
|
||||
return mValue, nil
|
||||
}
|
||||
|
||||
// GetYesterdayHotValue 获取昨日热度值
|
||||
func GetYesterdayHotValue(dt time.Time) (map[primitive.ObjectID]int, error) {
|
||||
return getHotValueByDate(dt.AddDate(0, 0, -1))
|
||||
}
|
||||
|
||||
// GetLastWeekHotValue 获取上个周日热度值
|
||||
func GetLastWeekHotValue(dt time.Time) (map[primitive.ObjectID]int, error) {
|
||||
offset := 0
|
||||
wk := dt.Weekday()
|
||||
switch wk {
|
||||
case time.Monday:
|
||||
offset = -1
|
||||
case time.Tuesday:
|
||||
offset = -2
|
||||
case time.Wednesday:
|
||||
offset = -3
|
||||
case time.Thursday:
|
||||
offset = -4
|
||||
case time.Friday:
|
||||
offset = -5
|
||||
case time.Saturday:
|
||||
offset = -6
|
||||
}
|
||||
return getHotValueByDate(dt.AddDate(0, 0, offset))
|
||||
}
|
||||
|
||||
// GetLastMonthHotValue 获取上个月末热度值
|
||||
func GetLastMonthHotValue(dt time.Time) (map[primitive.ObjectID]int, error) {
|
||||
return getHotValueByDate(dt.AddDate(0, 0, -dt.Day()))
|
||||
}
|
||||
|
||||
func DeleteBeforeCreatedAt(t *db.MongoTool, tm time.Time) error {
|
||||
_, err := coll(t).DeleteMany(bson.M{"createdAt": bson.M{"$lt": tm}})
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package hotstatmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
|
||||
// HotStat 帖子热度统计表
|
||||
type HotStat struct {
|
||||
ID primitive.ObjectID `json:"_id" bson:"_id,omitempty"`
|
||||
SumDate time.Time `json:"sumDate" bson:"sumDate"`
|
||||
VideoID primitive.ObjectID `json:"videoID" bson:"videoID"`
|
||||
TodayHot int `json:"todayHot" bson:"todayHot"` //今日热度
|
||||
WeekHot int `json:"weekHot" bson:"weekHot"` //本周热度
|
||||
MonthHot int `json:"monthHot" bson:"monthHot"` //本月热度
|
||||
TotalHot int `json:"totalHot" bson:"totalHot"` //目前为止总热度
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package kwrankmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/timeutil/timerange"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.KWRankStat
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// InitIndex 设置index
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "word", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: -1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: -1}, {Key: "word", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "count", Value: -1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sortKey", Value: -1}}, //大的排前面
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: -1}, {Key: "sortKey", Value: -1}, {Key: "count", Value: -1}}, //大的排前面
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "recordAt", Value: -1}},
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
func Insert(kw Word) error {
|
||||
now := time.Now()
|
||||
kw.CreatedAt = now
|
||||
kw.UpdatedAt = now
|
||||
if _, err := coll(nil).InsertOne(kw); err != nil {
|
||||
log.ZapLog.Error(fmt.Sprintf("coll:%s Insert fail error:%+v:", table, err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Update(id ObjectID, doc RankDoc) error {
|
||||
update, err := common.ToBsonM(doc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("coll:%s update ToBsonM fail, error:%+v ", table, err)
|
||||
}
|
||||
update["updatedAt"] = time.Now()
|
||||
if _, err := coll(nil).UpdateOne(M{"_id": id}, M{"$set": update}); err != nil {
|
||||
log.ZapLog.Error(fmt.Sprintf("coll:%s update fail error:%+v:", table, err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteOne DeleteOne
|
||||
func Delete(id ObjectID) error {
|
||||
_, err := coll(nil).DeleteOne(M{"_id": id})
|
||||
if err != nil {
|
||||
log.ZapLog.Error(fmt.Sprintf("coll:%s DeleteOne fail error:%+v:", table, err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var rankSort = bson.D{
|
||||
{Key: "sumDate", Value: -1},
|
||||
{Key: "sortKey", Value: -1},
|
||||
{Key: "count", Value: -1},
|
||||
}
|
||||
|
||||
var enableIsTrue = true
|
||||
|
||||
// RecentRanking RecentRanking
|
||||
func RecentRanking(limit int64) ([]Keyword, error) {
|
||||
kws, err := KwsList(rankSort, 0, limit, (&EnableMatch{&enableIsTrue}).New())
|
||||
if err != nil {
|
||||
log.ZapLog.Error(fmt.Sprintf("coll:%s RecentRanking fail error:%+v:", table, err))
|
||||
}
|
||||
return kws, err
|
||||
}
|
||||
|
||||
func ChangeStatTrans(trans *db.MongoTool, position time.Time, recordTime time.Time, setList []RankSetDoc) error {
|
||||
if len(setList) == 0 {
|
||||
return nil
|
||||
}
|
||||
sumDate := timerange.LocDayRange(position).Head
|
||||
// create the slice of write models
|
||||
writes := make([]mongo.WriteModel, len(setList))
|
||||
for i, doc := range setList {
|
||||
filter := M{
|
||||
"sumDate": sumDate,
|
||||
"word": doc.Word,
|
||||
}
|
||||
update := M{
|
||||
"$setOnInsert": M{
|
||||
"sumDate": sumDate,
|
||||
"word": doc.Word,
|
||||
"enable": true, //首次插入时使能
|
||||
"createdAt": time.Now(),
|
||||
},
|
||||
"$set": M{
|
||||
"count": doc.Count, //设计为统计表keywordStat聚合word得到
|
||||
"sortKey": doc.Count, //控制app端排序
|
||||
"recordAt": recordTime,
|
||||
"updatedAt": time.Now(),
|
||||
},
|
||||
}
|
||||
writes[i] = mongo.NewUpdateOneModel().
|
||||
SetFilter(filter).
|
||||
SetUpdate(update).
|
||||
SetUpsert(true)
|
||||
log.Debug(fmt.Sprintf("sumDate:%s table:%s [ word:%+v filter:%+v update:%+v ]\n", sumDate, table, doc.Word, filter, update))
|
||||
}
|
||||
//bulkWrite 不是原子操作 不具备事务性
|
||||
opt := (&options.BulkWriteOptions{}).SetOrdered(false) //设为无序,触发并行写,提升写效率
|
||||
_, err := coll(trans).Bulk(writes, opt)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetListNewest(limit int64) (WordArray, error) {
|
||||
sort := bson.D{{Key: "createdAt", Value: -1}}
|
||||
enable := true
|
||||
enableMatch := EnableMatch{&enable}
|
||||
return List(sort, 0, limit, enableMatch.New())
|
||||
}
|
||||
|
||||
func GetListRandom(limit int64) (WordArray, error) {
|
||||
enable := true
|
||||
enableMatch := EnableMatch{&enable}
|
||||
count, err := Count(enableMatch.New())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
maxSkip := count - limit
|
||||
if maxSkip < 0 {
|
||||
maxSkip = 0
|
||||
}
|
||||
randSkip := rand.Int63n(maxSkip)
|
||||
sort := bson.D{{Key: "count", Value: -1}}
|
||||
return List(sort, randSkip, limit)
|
||||
}
|
||||
|
||||
func DeleteBeforeSumDate(t *db.MongoTool, tm time.Time) error {
|
||||
_, err := coll(t).DeleteMany(bson.M{"sumDate": bson.M{"$lt": tm}})
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package kwrankmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/pageopt"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type Matcher = pageopt.Matcher
|
||||
|
||||
// SumDateMatch
|
||||
type SumDateMatch struct {
|
||||
SumDate *time.Time
|
||||
}
|
||||
|
||||
func (i *SumDateMatch) New() Matcher {
|
||||
return pageopt.NewAssignMatch("sumDate", i.SumDate)
|
||||
}
|
||||
|
||||
// EnableMatch
|
||||
type EnableMatch struct {
|
||||
Enable *bool
|
||||
}
|
||||
|
||||
func (i *EnableMatch) New() Matcher {
|
||||
return pageopt.NewAssignMatch("enable", i.Enable)
|
||||
}
|
||||
|
||||
func List(sort bson.D, skip, limit int64, matchers ...Matcher) (WordArray, error) {
|
||||
filter := pageopt.MergeM(matchers)
|
||||
opt := &options.FindOptions{}
|
||||
if len(sort) != 0 {
|
||||
opt.SetSort(sort)
|
||||
}
|
||||
opt.SetSkip(skip)
|
||||
opt.SetLimit(limit)
|
||||
wordArray := make(WordArray, 0, limit)
|
||||
if err := coll(nil).Find(&wordArray, filter, opt); err != nil {
|
||||
log.ZapLog.Error(fmt.Sprintf("coll:%s List fail error:%+v:", table, err))
|
||||
return wordArray, err
|
||||
}
|
||||
return wordArray, nil
|
||||
}
|
||||
|
||||
type Keyword struct {
|
||||
KeyWord string `bson:"word" json:"keyWord"` //关键字
|
||||
Count int64 `bson:"count" json:"count"` //关键字搜索次数
|
||||
}
|
||||
|
||||
func KwsList(sort bson.D, skip, limit int64, matchers ...Matcher) ([]Keyword, error) {
|
||||
filter := pageopt.MergeM(matchers)
|
||||
opt := &options.FindOptions{}
|
||||
if len(sort) != 0 {
|
||||
opt.SetSort(sort)
|
||||
}
|
||||
opt.SetSkip(skip)
|
||||
opt.SetLimit(limit)
|
||||
opt.SetProjection(M{
|
||||
"word": 1,
|
||||
"count": 1,
|
||||
})
|
||||
list := make([]Keyword, 0, limit)
|
||||
if err := coll(nil).Find(&list, filter, opt); err != nil {
|
||||
log.ZapLog.Error(fmt.Sprintf("coll:%s List fail error:%+v:", table, err))
|
||||
return list, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func Count(matchers ...Matcher) (int64, error) {
|
||||
filter := pageopt.MergeM(matchers)
|
||||
return coll(nil).Count(filter)
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package kwrankmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ObjectID = primitive.ObjectID
|
||||
|
||||
type M = bson.M
|
||||
|
||||
type Word struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty"` // ID
|
||||
SumDate time.Time `bson:"sumDate"`
|
||||
ComplexProportion float64 `bson:"complexProportion"` //综合搜索占比
|
||||
VideoProportion float64 `bson:"videoProportion"` //视屏搜索占比
|
||||
UserProportion float64 `bson:"userProportion"` //用户搜索占比
|
||||
TagProportion float64 `bson:"tagProportion"` //标签(话题)搜索占比
|
||||
LocationProportion float64 `bson:"locationProportion"` //地点搜索占比
|
||||
Word string `bson:"word"` //词
|
||||
Count int64 `bson:"count"` //搜索量
|
||||
SortKey int64 `bson:"sortKey"` //排序量
|
||||
Enable bool `bson:"enable"` //使能
|
||||
RecordAt time.Time `bson:"recordAt"` //数据记录时间
|
||||
CreatedAt time.Time `bson:"createdAt"` // 创建时间
|
||||
UpdatedAt time.Time `bson:"updatedAt"` // 更新时间
|
||||
}
|
||||
|
||||
type RankDoc struct {
|
||||
Word *string `bson:"word,omitempty"`
|
||||
SortKey *int64 `bson:"sortKey,omitempty"`
|
||||
Enable *bool `bson:"enable,omitempty"`
|
||||
}
|
||||
|
||||
type RankSetDoc struct {
|
||||
Word *string `bson:"word,omitempty"`
|
||||
Count *int64 `bson:"count,omitempty"`
|
||||
ComplexProportion *float64 `bson:"complexProportion"`
|
||||
VideoProportion *float64 `bson:"videoProportion"`
|
||||
UserProportion *float64 `bson:"userProportion"`
|
||||
TagProportion *float64 `bson:"tagProportion"`
|
||||
LocationProportion *float64 `bson:"locationProportion"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
|
||||
type WordArray []Word
|
||||
|
||||
func (k WordArray) Len() int {
|
||||
return len(k)
|
||||
}
|
||||
|
||||
func (k WordArray) Less(i, j int) bool {
|
||||
return k[i].Count < k[j].Count
|
||||
}
|
||||
|
||||
func (k WordArray) Swap(i, j int) {
|
||||
k[i], k[j] = k[j], k[i]
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
package kwstatmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/constant"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/timeutil/timerange"
|
||||
"91porn-server/models"
|
||||
|
||||
"github.com/jinzhu/now"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.KeywordStat
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// InitIndex 设置index
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "word", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "realm", Value: 1}, {Key: "word", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: -1}, {Key: "realm", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: -1}, {Key: "realm", Value: 1}, {Key: "word", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "count", Value: -1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "createdAt", Value: -1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "updatedAt", Value: -1}},
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
func ChangeStatTrans(trans *db.MongoTool, position time.Time, recordTime time.Time, docList []KeywordIncDoc) error {
|
||||
sumDate := timerange.LocDayRange(position).Head
|
||||
// create the slice of write models
|
||||
writes := make([]mongo.WriteModel, len(docList))
|
||||
for i, doc := range docList {
|
||||
filter := M{
|
||||
"sumDate": sumDate,
|
||||
"realm": doc.Realm,
|
||||
"word": doc.Word,
|
||||
}
|
||||
update := M{
|
||||
"$setOnInsert": M{
|
||||
"sumDate": sumDate,
|
||||
"realm": doc.Realm,
|
||||
"word": doc.Word,
|
||||
"createdAt": time.Now(),
|
||||
},
|
||||
"$set": M{
|
||||
"recordAt": recordTime,
|
||||
"updatedAt": time.Now(),
|
||||
},
|
||||
"$inc": M{
|
||||
"count": doc.Count,
|
||||
},
|
||||
}
|
||||
writes[i] = mongo.NewUpdateOneModel().
|
||||
SetFilter(filter).
|
||||
SetUpdate(update).
|
||||
SetUpsert(true)
|
||||
log.Debug(fmt.Sprintf("sumDate:%s table:%s [ realm:%+v word:%+v filter:%+v update:%+v ]\n", sumDate, table, doc.Realm, doc.Word, filter, update))
|
||||
}
|
||||
if len(writes) == 0 {
|
||||
return nil
|
||||
}
|
||||
//bulkWrite 不是原子操作 不具备事务性
|
||||
opt := (&options.BulkWriteOptions{}).SetOrdered(false) //设为无序,触发并行写,提升写效率
|
||||
_, err := coll(trans).Bulk(writes, opt)
|
||||
return err
|
||||
}
|
||||
|
||||
func list(sumDate time.Time, realms []constant.RealmType, enable bool, sort bson.D, skip, limit int64) ([]Keyword, error) {
|
||||
filter := M{
|
||||
"sumDate": sumDate,
|
||||
"realm": M{"$in": realms},
|
||||
}
|
||||
realmCount := len(realms)
|
||||
if realmCount == 0 {
|
||||
return []Keyword{}, nil
|
||||
}
|
||||
if realmCount == 1 { //只有一个元素 不使用$in 提升效率
|
||||
filter["realm"] = realms[0]
|
||||
}
|
||||
opt := (&options.FindOptions{}).
|
||||
SetSort(sort).
|
||||
SetSkip(skip).
|
||||
SetLimit(limit)
|
||||
keywords := make([]Keyword, 0, limit)
|
||||
if err := coll(nil).Find(&keywords, filter, opt); err != nil {
|
||||
log.ZapLog.Error(fmt.Sprintf("coll:%s list fail error:%+v:", table, err))
|
||||
return nil, err
|
||||
}
|
||||
return keywords, nil
|
||||
}
|
||||
|
||||
// RealmRanking RealmRanking
|
||||
func RealmRanking(sumDate time.Time, realm constant.RealmType, skip int64, limit int64) ([]Keyword, error) {
|
||||
sort := bson.D{
|
||||
{Key: "sortKey", Value: -1},
|
||||
{Key: "count", Value: -1},
|
||||
}
|
||||
keywords, err := list(sumDate, []constant.RealmType{realm}, true, sort, skip, limit)
|
||||
if err != nil {
|
||||
log.ZapLog.Error(fmt.Sprintf("coll:%s RealmRanking fail error:%+v:", table, err))
|
||||
return nil, err
|
||||
}
|
||||
return keywords, nil
|
||||
}
|
||||
|
||||
// KeywordCountMapBySumDate
|
||||
func KeywordCountMapBySumDate(sumDate time.Time) (map[string]int64, error) {
|
||||
pipeline := []M{
|
||||
{
|
||||
"$match": M{
|
||||
"sumDate": sumDate,
|
||||
},
|
||||
},
|
||||
{
|
||||
"$group": M{
|
||||
"_id": "$word",
|
||||
"count": M{"$sum": "$count"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"$sort": M{
|
||||
"count": -1,
|
||||
},
|
||||
},
|
||||
}
|
||||
var list []struct {
|
||||
Word string `bson:"_id"`
|
||||
Count int64 `bson:"count"`
|
||||
}
|
||||
if err := coll(nil).Aggregate(&list, pipeline); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := make(map[string]int64, len(list))
|
||||
for _, v := range list {
|
||||
m[v.Word] = v.Count
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// HotSearchWordsToday 获取今日搜索较高的关键词 视频关键字
|
||||
func HotSearchWordsToday(top int) ([]string, error) {
|
||||
var kw []Keyword
|
||||
var words []string
|
||||
opts := options.FindOptions{}
|
||||
sort := bson.D{{Key: "count", Value: -1}}
|
||||
opts.SetSort(sort).SetLimit(int64(top))
|
||||
if err := coll(nil).Find(&kw, M{"realm": "video", "sumDate": now.BeginningOfDay()}, &opts); err != nil {
|
||||
log.Error("keywordStat model HotSearchWordsToday error", log.E(err), log.Any("top", top))
|
||||
return words, err
|
||||
}
|
||||
words = make([]string, len(kw))
|
||||
for i, k := range kw {
|
||||
words[i] = k.Word
|
||||
}
|
||||
return words, nil
|
||||
}
|
||||
|
||||
func GetKeywordsExcludeWords(sumDate time.Time, realm string, words []string, skip int64, limit int64) (data []Keyword, err error) {
|
||||
if words == nil {
|
||||
words = []string{}
|
||||
}
|
||||
query := bson.M{"word": bson.M{"$nin": words}}
|
||||
opts := options.Find()
|
||||
sort := bson.D{
|
||||
{Key: "sortKey", Value: -1},
|
||||
{Key: "count", Value: -1},
|
||||
}
|
||||
opts.SetSort(sort).SetSkip(skip).SetLimit(limit)
|
||||
if err = coll(nil).Find(&data, query, opts); err != nil {
|
||||
log.Error("keywordStat model GetKeywordsExcludeWords error", log.E(err), log.Any("sumDate", sumDate), log.Any("words", words))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 根据时间获取今日加昨日的关键字
|
||||
func GetKeywordsBySumDate(sumDate time.Time, realm string, skip int64, limit int64) (data []Keyword, err error) {
|
||||
var query = bson.M{"sumDate": bson.M{"$gte": sumDate}, "realm": realm}
|
||||
var opts = options.Find()
|
||||
opts.SetSort(bson.D{{Key: "sortKey", Value: -1}, {Key: "count", Value: -1}}).SetSkip(skip).SetLimit(limit)
|
||||
if err = coll(nil).Find(&data, query, opts); err != nil {
|
||||
log.Error("keywordStat model GetKeywordsBySumDate error", log.E(err), log.Any("sumDate", sumDate), log.Any("realm", realm))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 根据时间段获取关键字
|
||||
func GetKeywordsByTimeRange(start time.Time, end time.Time) (data []Keyword, err error) {
|
||||
var query = bson.M{"updatedAt": bson.M{"$gte": start, "$lt": end}}
|
||||
if err = coll(nil).Find(&data, query); err != nil {
|
||||
log.Error("keywordStat model GetKeywordsByTimeRange error", log.E(err))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func DeleteBeforeSumDate(t *db.MongoTool, tm time.Time) error {
|
||||
_, err := coll(t).DeleteMany(bson.M{"sumDate": bson.M{"$lt": tm}})
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package kwstatmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/constant"
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type (
|
||||
ObjectID = primitive.ObjectID
|
||||
|
||||
M = bson.M
|
||||
|
||||
KeywordSetDoc = KeywordIncDoc
|
||||
)
|
||||
type Keyword struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty"` // ID
|
||||
SumDate time.Time `bson:"sumDate"`
|
||||
Realm constant.RealmType `bson:"realm"`
|
||||
Word string `bson:"word"`
|
||||
Count int64 `bson:"count"`
|
||||
RecordAt time.Time `bson:"recordAt"` //数据记录时间
|
||||
CreatedAt time.Time `bson:"createdAt"` // 创建时间
|
||||
UpdatedAt time.Time `bson:"updatedAt"` // 更新时间
|
||||
}
|
||||
|
||||
type ESKeywordSrc struct {
|
||||
ID primitive.ObjectID `json:"id"` // ID
|
||||
SumDate time.Time `json:"sumDate"`
|
||||
Realm constant.RealmType `json:"realm"`
|
||||
Word string `json:"word"`
|
||||
Count int64 `json:"count"`
|
||||
RecordAt time.Time `json:"recordAt"` //数据记录时间
|
||||
CreatedAt time.Time `json:"createdAt"` // 创建时间
|
||||
UpdatedAt time.Time `json:"updatedAt"` // 更新时间
|
||||
}
|
||||
|
||||
type KeywordIncDoc struct {
|
||||
Realm constant.RealmType `bson:"realm,omitempty"`
|
||||
Word string `bson:"word,omitempty"`
|
||||
Count int64 `bson:"count,omitempty"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package sectionstatmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
// IncSectionHits 增加专题每日点击量
|
||||
func IncSectionHits(sectionID primitive.ObjectID, date string) error {
|
||||
filter := bson.M{"sectionID": sectionID, "date": date}
|
||||
_, err := coll(nil).UpdateOne(filter, bson.M{"$inc": bson.M{"hitsPerDay": 1}})
|
||||
return err
|
||||
}
|
||||
|
||||
// UpsertSectionHits upsert某一天专题点击量
|
||||
func UpsertSectionHits(sectionID primitive.ObjectID, date string) error {
|
||||
filter := bson.M{"sectionID": sectionID, "date": date}
|
||||
now := time.Now()
|
||||
update := bson.M{
|
||||
"$set": bson.M{"sectionID": sectionID, "date": date, "updatedAt": now},
|
||||
"$setOnInsert": bson.M{"createdAt": now},
|
||||
"$inc": bson.M{"hitsPerDay": 1},
|
||||
}
|
||||
_, err := coll(nil).UpsertOne(filter, update)
|
||||
return err
|
||||
}
|
||||
|
||||
// ListSectionHits 按页检索专题统计数据
|
||||
func ListSectionHits(req ListRequest) (resp ListResponse, err error) {
|
||||
opts := options.Find().SetSkip(int64(req.PageSize * (req.PageNumber - 1))).SetLimit(int64(req.PageSize + 1)).
|
||||
SetSort(bson.D{{Key: "date", Value: -1}})
|
||||
if err = coll(nil).Find(&resp.List, bson.M{"sectionID": req.SectionID}, opts); err != nil {
|
||||
return
|
||||
}
|
||||
if uint64(len(resp.List)) > req.PageSize {
|
||||
resp.HasNext = true
|
||||
resp.List = resp.List[:req.PageSize]
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package sectionstatmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/commod"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
type SectionStat struct {
|
||||
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // id
|
||||
SectionID primitive.ObjectID `json:"sectionID" bson:"sectionID"` // 专题ID
|
||||
HitsPerday int64 `json:"hitsPerDay" bson:"hitsPerDay"` // 每日点击量
|
||||
Date string `json:"date" bson:"date"` // 统计日期
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt,omitempty"` // 创建时间
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt,omitempty"` // 刷新时间
|
||||
}
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.SectionClick
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
|
||||
// initIndex 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "sectionID", Value: 1}, {Key: "date", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
type ListRequest struct {
|
||||
SectionID primitive.ObjectID `json:"sectionID" swaggertype:"string" binding:"required"` // 专题ID
|
||||
commod.Page
|
||||
}
|
||||
|
||||
type ListResponse struct {
|
||||
List []SectionStat // 统计列表
|
||||
HasNext bool // 下一页
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package statordermod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/pageopt"
|
||||
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type (
|
||||
Matcher = pageopt.Matcher
|
||||
|
||||
// ChannelMatch
|
||||
ChannelMatch struct {
|
||||
Type *string
|
||||
}
|
||||
)
|
||||
|
||||
func (t *ChannelMatch) New() Matcher {
|
||||
return pageopt.NewAssignMatch("channel", t.Type)
|
||||
}
|
||||
|
||||
// TypeMatch
|
||||
type TypeMatch struct {
|
||||
Type *OrderType
|
||||
}
|
||||
|
||||
func (t *TypeMatch) New() Matcher {
|
||||
return pageopt.NewAssignMatch("type", t.Type)
|
||||
}
|
||||
|
||||
// SumDateGTEAndLTMatch
|
||||
type SumDateGTEAndLTMatch struct {
|
||||
GTE *time.Time
|
||||
LT *time.Time
|
||||
}
|
||||
|
||||
func (s *SumDateGTEAndLTMatch) New() Matcher {
|
||||
return pageopt.NewGTEAndLTMatch("sumDate", s.GTE, s.LT)
|
||||
}
|
||||
|
||||
var Sort_SumDate_n1 = Sort{{Key: "sumDate", Value: -1}}
|
||||
|
||||
func List(sort Sort, skip, limit *int64, matchers ...Matcher) ([]OrderState, error) {
|
||||
filter := pageopt.MergeM(matchers)
|
||||
opt := (&options.FindOptions{})
|
||||
if len(sort) != 0 {
|
||||
opt.SetSort(sort)
|
||||
}
|
||||
if skip != nil {
|
||||
opt.SetSkip(*skip)
|
||||
}
|
||||
if limit != nil {
|
||||
opt.SetLimit(*limit)
|
||||
}
|
||||
list := []OrderState{}
|
||||
if err := coll(nil).Find(&list, filter, opt); err != nil {
|
||||
log.Error("statordermod List error", log.E(err))
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func Count(matchers ...Matcher) (int64, error) {
|
||||
filter := pageopt.MergeM(matchers)
|
||||
count, err := coll(nil).Count(filter)
|
||||
if err != nil {
|
||||
log.Error("statordermod Count error", log.E(err))
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// Sum
|
||||
func Sum(matchers ...Matcher) (Items, error) {
|
||||
filter := pageopt.MergeM(matchers)
|
||||
pipeline := []M{}
|
||||
pipeline = append(pipeline, M{"$match": filter})
|
||||
pipeline = append(pipeline, M{"$group": M{"_id": nil,
|
||||
"orderCount": M{"$sum": "$orderCount"},
|
||||
"completeOrderCount": M{"$sum": "$completeOrderCount"},
|
||||
"orderAmount": M{"$sum": "$orderAmount"},
|
||||
"completeOrderAmount": M{"$sum": "$completeOrderAmount"},
|
||||
"paidOrderCount": M{"$sum": "$paidOrderCount"},
|
||||
"paidAmount": M{"$sum": "$paidAmount"},
|
||||
}})
|
||||
items := Items{}
|
||||
if err := coll(nil).AggregateDecode(&items, pipeline); err != nil {
|
||||
log.Error("statordermod Sum error", log.E(err))
|
||||
return Items{}, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package statordermod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.OrderStat
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// initIndex 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: -1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "channel", Value: 1}, {Key: "type", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "sumDate", Value: -1}, {Key: "channel", Value: 1}, {Key: "type", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
func ChangeRechargeStatTrans(trans *db.MongoTool, sumDate, recordTime time.Time, stateMap RecOrderStateMap) error {
|
||||
writes := make([]mongo.WriteModel, len(stateMap))
|
||||
i := 0
|
||||
for channel, statDoc := range stateMap {
|
||||
model, err := toMgoModel(sumDate, recordTime, channel, Recharge, statDoc.RechargeOrderStateIncDoc, statDoc.RechargeOrderStateSetDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writes[i] = model
|
||||
i++
|
||||
}
|
||||
if len(writes) == 0 {
|
||||
return nil
|
||||
}
|
||||
//bulkWrite 不是原子操作 不具备事务性
|
||||
opt := (&options.BulkWriteOptions{}).SetOrdered(false) //设为无序,触发并行写,提升写效率
|
||||
_, err := coll(trans).Bulk(writes, opt)
|
||||
return err
|
||||
}
|
||||
|
||||
func ChangeWithDrawStatTrans(trans *db.MongoTool, sumDate, recordTime time.Time, stateMap WitOrderStateMap) error {
|
||||
writes := make([]mongo.WriteModel, len(stateMap))
|
||||
i := 0
|
||||
for channel, statDoc := range stateMap {
|
||||
model, err := toMgoModel(sumDate, recordTime, channel, WithDraw, statDoc.WithDrawOrderStateIncDoc, statDoc.WithDrawOrderStateSetDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writes[i] = model
|
||||
i++
|
||||
}
|
||||
if len(writes) == 0 {
|
||||
return nil
|
||||
}
|
||||
//bulkWrite 不是原子操作 不具备事务性
|
||||
opt := (&options.BulkWriteOptions{}).SetOrdered(false) //设为无序,触发并行写,提升写效率
|
||||
_, err := coll(trans).Bulk(writes, opt)
|
||||
return err
|
||||
}
|
||||
|
||||
func toMgoModel(sumDate, recordTime time.Time, channel string, typ OrderType, inc orderStateIncDoc, set orderStateSetDoc) (mongo.WriteModel, error) {
|
||||
filter := M{
|
||||
"sumDate": sumDate,
|
||||
"channel": channel,
|
||||
"type": typ,
|
||||
}
|
||||
setM, err := common.ToBsonM(set)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
setM["recordAt"] = recordTime
|
||||
setM["updatedAt"] = time.Now()
|
||||
incM, err := common.ToBsonM(inc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
update := M{
|
||||
"$setOnInsert": M{
|
||||
"sumDate": sumDate,
|
||||
"channel": channel,
|
||||
"type": typ,
|
||||
"createdAt": time.Now(),
|
||||
},
|
||||
}
|
||||
if len(incM) != 0 {
|
||||
update["$inc"] = incM
|
||||
}
|
||||
if len(setM) != 0 {
|
||||
update["$set"] = setM
|
||||
}
|
||||
model := mongo.NewUpdateOneModel().
|
||||
SetFilter(filter).
|
||||
SetUpdate(update).
|
||||
SetUpsert(true)
|
||||
log.Debug(fmt.Sprintf("sumDate:%s table:%s [ typ:%s channel:%s filter:%+v update:%+v ]\n", sumDate, table, typ.String(), channel, filter, update))
|
||||
return model, nil
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package statordermod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type (
|
||||
OrderType int
|
||||
|
||||
M = bson.M
|
||||
|
||||
Sort = bson.D
|
||||
)
|
||||
|
||||
const (
|
||||
Recharge OrderType = 1
|
||||
WithDraw OrderType = 2
|
||||
)
|
||||
|
||||
func (o *OrderType) String() string {
|
||||
switch *o {
|
||||
case Recharge:
|
||||
return "recharge"
|
||||
case WithDraw:
|
||||
return "withDraw"
|
||||
default:
|
||||
return "unknow"
|
||||
}
|
||||
}
|
||||
|
||||
type Items struct {
|
||||
OrderCount int64 `json:"orderCount" bson:"orderCount"` //生产订单数
|
||||
CompleteOrderCount int64 `json:"completeOrderCount" bson:"completeOrderCount"` //完成订单数
|
||||
OrderAmount int64 `json:"orderAmount" bson:"orderAmount"` //生产订单金额
|
||||
CompleteOrderAmount int64 `json:"completeOrderAmount" bson:"completeOrderAmount"` //完成订单的实际支付金额
|
||||
PaidOrderCount int64 `json:"paidOrderCount" bson:"paidOrderCount"` //用户已支付金额/三方已出款金额
|
||||
PaidAmount int64 `json:"paidAmount" bson:"paidAmount"` //用户已支付订单数/三方已出款订单数
|
||||
}
|
||||
|
||||
// OrderState 充值提现统计
|
||||
type OrderState struct {
|
||||
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // ID
|
||||
SumDate time.Time `json:"sumDate" bson:"sumDate"`
|
||||
|
||||
Items `bson:",inline"`
|
||||
|
||||
Channel string `json:"channel" bson:"channel"` //充值渠道
|
||||
Type OrderType `json:"type" bson:"type"` //订单类型, 1,充值;2,提现
|
||||
RecordAt time.Time `json:"recordAt" bson:"recordAt"` //数据记录时间
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //文档创建时间
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` //文档更新时间
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
|
||||
type orderStateSetDoc struct {
|
||||
}
|
||||
|
||||
type orderStateIncDoc struct {
|
||||
OrderCount *int64 `bson:"orderCount,omitempty"` //订单数
|
||||
CompleteOrderCount *int64 `bson:"completeOrderCount,omitempty"` //完成订单数
|
||||
OrderAmount *int64 `bson:"orderAmount,omitempty"` //订单金额
|
||||
CompleteOrderAmount *int64 `bson:"completeOrderAmount,omitempty"` //实际支付金额
|
||||
PaidOrderCount *int64 `bson:"paidOrderCount,omitempty"` //用户已支付订单数/三方已出款订单数
|
||||
PaidAmount *int64 `bson:"paidAmount,omitempty"` //用户已支付金额/三方已出款金额
|
||||
}
|
||||
|
||||
type RechargeOrderStateIncDoc = orderStateIncDoc
|
||||
type RechargeOrderStateSetDoc = orderStateSetDoc
|
||||
type RechargeOrderStateDoc struct {
|
||||
RechargeOrderStateIncDoc
|
||||
RechargeOrderStateSetDoc
|
||||
}
|
||||
type RecOrderStateMap = map[string]*RechargeOrderStateDoc
|
||||
|
||||
type WithDrawOrderStateIncDoc = orderStateIncDoc
|
||||
type WithDrawOrderStateSetDoc = orderStateSetDoc
|
||||
type WithDrawOrderStateDoc struct {
|
||||
WithDrawOrderStateIncDoc
|
||||
WithDrawOrderStateSetDoc
|
||||
}
|
||||
type WitOrderStateMap = map[string]*WithDrawOrderStateDoc
|
||||
@@ -0,0 +1,182 @@
|
||||
package statrecordmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.StatRecord
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
// initIndex 初始化索引
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "name", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "job", Value: 1}, {Key: "item", Value: 1}},
|
||||
Options: options.Index().SetSparse(true).SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "createdAt", Value: -1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "updatedAt", Value: -1}},
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
// ChangeStatTrans ChangeStatTrans
|
||||
func UpsertOneTrans(trans *db.MongoTool, name string, recordTime time.Time) error {
|
||||
filter := bson.M{
|
||||
"name": name,
|
||||
}
|
||||
update := bson.M{
|
||||
"$set": bson.M{
|
||||
"recordTime": recordTime,
|
||||
"updatedAt": time.Now(),
|
||||
},
|
||||
"$setOnInsert": bson.M{
|
||||
"name": name,
|
||||
"fristRecordTime": recordTime,
|
||||
"createdAt": time.Now(),
|
||||
},
|
||||
}
|
||||
if _, err := coll(trans).UpsertOne(filter, update); err != nil {
|
||||
log.Error("statrecordmod UpsertOneTrans error:%v\n", log.E(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ItemRecordAt struct {
|
||||
Job string
|
||||
Item string
|
||||
RecordTime time.Time
|
||||
}
|
||||
|
||||
func MergeName(job string, item string) string {
|
||||
return fmt.Sprintf("%s.%s", job, item)
|
||||
}
|
||||
|
||||
func UpsertOneItemTrans(trans *db.MongoTool, job string, item string, recordTime time.Time) error {
|
||||
filter := bson.M{
|
||||
"job": job,
|
||||
"item": item,
|
||||
}
|
||||
update := bson.M{
|
||||
"$set": bson.M{
|
||||
"recordTime": recordTime,
|
||||
"updatedAt": time.Now(),
|
||||
},
|
||||
"$setOnInsert": bson.M{
|
||||
"name": MergeName(job, item),
|
||||
"job": job,
|
||||
"item": item,
|
||||
"fristRecordTime": recordTime,
|
||||
"createdAt": time.Now(),
|
||||
},
|
||||
}
|
||||
if _, err := coll(trans).UpsertOne(filter, update); err != nil {
|
||||
log.Error("statrecordmod UpsertOneItemTrans error:%v\n", log.E(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindOne FindOne
|
||||
func findOneByName(Name string) (Record, error) {
|
||||
filter := bson.M{
|
||||
"name": Name,
|
||||
}
|
||||
doc := Record{}
|
||||
return doc, coll(nil).FindOne(&doc, filter)
|
||||
}
|
||||
|
||||
// LastRecordTime 最后的记录时间,服务器的时区
|
||||
func LastRecordTime(name string, defaultTime time.Time) (time.Time, error) {
|
||||
//获取上次记录时间
|
||||
doc, err := findOneByName(name)
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf("LastRecordTime err:%+v\n", err)
|
||||
}
|
||||
//设定为服务器的时区
|
||||
var tim = defaultTime
|
||||
if !doc.RecordTime.IsZero() {
|
||||
tim = doc.RecordTime
|
||||
}
|
||||
//不依赖数据库 保证时间是服务器时间
|
||||
localTime := tim.In(time.Local)
|
||||
log.Debug("LastRecordTime local Info", log.Any("Local", time.Local), log.Any("time", tim), log.Any("returnTime", localTime))
|
||||
return localTime, nil
|
||||
}
|
||||
|
||||
func FristRecordTimeByName(name string) (time.Time, error) {
|
||||
doc, err := findOneByName(name)
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf("FristRecordTimeByName err:%+v\n", err)
|
||||
}
|
||||
return doc.FristRecordTime, nil
|
||||
}
|
||||
|
||||
func findOneByJob(job string, item string) (Record, error) {
|
||||
filter := bson.M{
|
||||
"job": job,
|
||||
"item": item,
|
||||
}
|
||||
doc := Record{}
|
||||
return doc, coll(nil).FindOne(&doc, filter)
|
||||
}
|
||||
|
||||
func FristRecordTimeByJob(job string, item string) (time.Time, error) {
|
||||
doc, err := findOneByJob(job, item)
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf("FristRecordTimeByName err:%+v\n", err)
|
||||
}
|
||||
return doc.FristRecordTime, nil
|
||||
}
|
||||
|
||||
func findManyByJob(job string) ([]Record, error) {
|
||||
filter := bson.M{
|
||||
"job": job,
|
||||
}
|
||||
list := []Record{}
|
||||
return list, coll(nil).Find(&list, filter)
|
||||
}
|
||||
|
||||
func LastRecordTimeMap(job string, defaultTimeMap map[string]time.Time) (map[string]time.Time, error) {
|
||||
list, err := findManyByJob(job)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range list {
|
||||
defaultTimeMap[v.Item] = v.RecordTime
|
||||
}
|
||||
return defaultTimeMap, nil
|
||||
}
|
||||
|
||||
func DeleteStatRecordByName(name string) error {
|
||||
_, err := coll(nil).DeleteOne(bson.M{"name": name})
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package statrecordmod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type Record struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty"`
|
||||
|
||||
Name string `bson:"name"` //任务名
|
||||
|
||||
Job string `bson:"job"` //工作
|
||||
Item string `bson:"item"` //项目
|
||||
|
||||
RecordTime time.Time `bson:"recordTime"` //提交时间
|
||||
FristRecordTime time.Time `bson:"fristRecordTime"` //第一次提交时间
|
||||
CreatedAt time.Time `bson:"createdAt"` //创建时间
|
||||
UpdatedAt time.Time `bson:"updatedAt"` //更新时间
|
||||
}
|
||||
|
||||
const (
|
||||
OneMinuteScale = 1 //对齐时间(分钟)
|
||||
FiveMinuteScale = 5 //对齐时间(分钟)
|
||||
FifteenMinuteScale = 15 //对齐时间(分钟)
|
||||
ThirtyMinuteScale = 30 //对齐时间(分钟)
|
||||
OneDayScale = 1440 //对齐时间(分钟)
|
||||
)
|
||||
|
||||
const (
|
||||
//stat 基本统计
|
||||
DailyStatJob1 = "dailyStatJob1"
|
||||
ChannelStatJob = "channelStatJob"
|
||||
VideoStatJob = "videoStatJob"
|
||||
VideoTotalStatJob = "videoTotalStatJob"
|
||||
ChannelRetainStatJob = "channelRetainStatJob"
|
||||
KeywordStatJob = "keywordStatJob"
|
||||
KeywordRankStatJob = "keywordRankStatJob"
|
||||
RechargeOrderStatJob = "rechargeOrderStatJob"
|
||||
WithdrawOrderStatJob = "withdrawOrderStatJob"
|
||||
TagPlayStatJob = "tagPlayStatJob"
|
||||
ADSStatJob = "adsStatJob"
|
||||
TotalJob = "totalJob"
|
||||
ChTotalJob = "chTotalJob"
|
||||
InvitStatJob = "InvitStatJob"
|
||||
DataPointJob = "dataPointJob"
|
||||
UserStatJob = "userStatJob"
|
||||
DiscStatJob = "discStatJob"
|
||||
DiscTotalStatJob = "discTotalStatJob"
|
||||
Retain1StatJob = "retainStatJob1"
|
||||
DicsZoomStatJob = "dicsZoomStatJob"
|
||||
|
||||
//act 活动统计,生命周期等于活动时间
|
||||
ActInvitCountJob_01_17 = "ActInvitCountJob_01_17"
|
||||
ActInvitCoinsJob_01_17 = "ActInvitCoinsJob_01_17"
|
||||
LotteryActID = "LotteryActID"
|
||||
|
||||
// 数据同步
|
||||
ElasticSyncVideoJob = "esVideoJob"
|
||||
ElasticSyncMediaJob = "esMediaJob"
|
||||
ElasticSyncTagJob = "esTagJob"
|
||||
ElasticSyncUserJob = "esUserJob"
|
||||
ElasticSyncKeywordJob = "esKeywordJob"
|
||||
ElasticSyncSearchLogJob = "esSearchLogJob"
|
||||
ElasticSyncLoufengJob = "esLouFengJob"
|
||||
ElasticSyncAudioBookJob = "esAudioBookJob"
|
||||
SpiderSyncLoufengJob = "spiderLouFengJob"
|
||||
SpiderSyncfictionJob = "spiderFictionJob"
|
||||
SpiderSyncAudiobookJob = "spiderAudiobookJob"
|
||||
SpiderSyncLoufengAgentJob = "spiderSyncLoufengAgentJob"
|
||||
RedisSyncShortVideoJob = "rdShortVideoJob"
|
||||
|
||||
//sql折叠
|
||||
SqlCollasperVidPageView = "sqlCollasperVidPageView"
|
||||
SqlCollasperUserTotalWork = "sqlCollasperUserTotalWorks"
|
||||
)
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package stattagplaymod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
const table = models.TagPlayStat
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
func initIndex() {
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "tagID", Value: 1}, {Key: "videoID", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "playCount", Value: 1}, {Key: "updatedAt", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "updatedAt", Value: -1}},
|
||||
},
|
||||
}
|
||||
if _, err := coll(nil).CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
func GetTagPlayCount(tagID ObjectID, videoID ObjectID) (TagPlay, error) {
|
||||
tagPlay := TagPlay{}
|
||||
if err := coll(nil).FindOne(&tagPlay, bson.M{"tagID": tagID, "videoID": videoID}); err != nil {
|
||||
log.Error("stat tag play model GetTagPlayCount error", log.E(err), log.Any("tagID", tagID), log.Any("videoID", videoID))
|
||||
return tagPlay, err
|
||||
}
|
||||
return tagPlay, nil
|
||||
}
|
||||
|
||||
func ChangeStatTrans(trans *db.MongoTool, incDoc []IncDoc) error {
|
||||
incDocLen := len(incDoc)
|
||||
if incDocLen == 0 {
|
||||
return nil
|
||||
}
|
||||
// create the slice of write models
|
||||
writes := make([]mongo.WriteModel, incDocLen)
|
||||
for i, tagPlay := range incDoc {
|
||||
filter := bson.M{
|
||||
"tagID": tagPlay.TagID,
|
||||
"videoID": tagPlay.VideoID,
|
||||
}
|
||||
update := bson.M{
|
||||
"$setOnInsert": bson.M{
|
||||
"tagID": tagPlay.TagID,
|
||||
"videoID": tagPlay.VideoID,
|
||||
},
|
||||
"$inc": bson.M{
|
||||
"playCount": tagPlay.PlayCount,
|
||||
},
|
||||
"$set": bson.M{
|
||||
"updatedAt": time.Now(),
|
||||
},
|
||||
}
|
||||
writes[i] = mongo.NewUpdateOneModel().
|
||||
SetFilter(filter).
|
||||
SetUpdate(update).
|
||||
SetUpsert(true)
|
||||
}
|
||||
//bulkWrite 不是原子操作 不具备事务性
|
||||
opt := (&options.BulkWriteOptions{}).SetOrdered(false) //设为无序,触发并行写,提升写效率
|
||||
if _, err := coll(trans).Bulk(writes, opt); err != nil {
|
||||
log.Warn("stat tag play model Bulk error", log.E(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package stattagplaymod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type ObjectID = primitive.ObjectID
|
||||
|
||||
type TagPlay struct {
|
||||
ID ObjectID `bson:"_id,omitempty"`
|
||||
TagID ObjectID `bson:"tagID"`
|
||||
VideoID ObjectID `bson:"videoID"`
|
||||
PlayCount int64 `bson:"playCount"`
|
||||
UpdatedAt time.Time `bson:"updatedAt"`
|
||||
}
|
||||
|
||||
type IncDoc struct {
|
||||
TagID ObjectID `bson:"tagID"`
|
||||
VideoID ObjectID `bson:"videoID"`
|
||||
PlayCount int64 `bson:"playCount"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user