@@ -0,0 +1,114 @@
|
||||
package visit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
"videoweb/app/middleware/reptilerecord"
|
||||
"videoweb/pub/common/enum/consts"
|
||||
"videoweb/pub/common/enum/redisconst"
|
||||
"videoweb/pub/common/ipaddr"
|
||||
"videoweb/pub/common/srvdef"
|
||||
"videoweb/pub/common/useragent"
|
||||
"videoweb/pub/common/utils"
|
||||
"videoweb/pub/models/usermod"
|
||||
"videoweb/pub/models/uservisitlog"
|
||||
"videoweb/pub/redis"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// Visit 用户日活访问中间件:每天首次访问写入 user_visit_log
|
||||
func Visit(ctx *gin.Context) {
|
||||
if reptilerecord.IsBot(ctx) {
|
||||
return
|
||||
}
|
||||
val, ok := ctx.Get(consts.CtxUA)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
ua, ok := val.(useragent.UA)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
RecordDailyVisit(ctx, ctx.GetInt64(consts.CtxUserID), ua, ipaddr.ResolveClientIP(ctx))
|
||||
}
|
||||
|
||||
// RecordDailyVisit 当天首次访问写入 user_visit_log,游客新建成功后也会立刻记一笔。
|
||||
func RecordDailyVisit(ctx context.Context, userId int64, ua useragent.UA, ip string) {
|
||||
if userId <= 0 {
|
||||
return
|
||||
}
|
||||
now := time.Now()
|
||||
userVisitLogKey := redisconst.UserVisitLogKey(userId, now)
|
||||
exist, err := redis.Exists(userVisitLogKey)
|
||||
if err != nil || exist {
|
||||
return
|
||||
}
|
||||
visitInfo := &uservisitlog.UserVisitLog{
|
||||
Id: primitive.NewObjectID(),
|
||||
UserId: userId,
|
||||
SysType: ua.SysType,
|
||||
DevType: ua.DevType,
|
||||
DevID: ua.DevID,
|
||||
Version: ua.Ver,
|
||||
IP: ip,
|
||||
VisitAt: now,
|
||||
}
|
||||
if serr := uservisitlog.InsertOneVisitLog(ctx, visitInfo); serr != nil {
|
||||
return
|
||||
}
|
||||
if serr := userVisitStatus(ctx, userId, ua, visitInfo.IP, visitInfo.VisitAt); serr != nil {
|
||||
return
|
||||
}
|
||||
_ = redis.Set(userVisitLogKey, "1", utils.BeginOfToday().Add(24*time.Hour).Sub(now)+5*time.Minute)
|
||||
}
|
||||
|
||||
func userVisitStatus(ctx context.Context, uId int64, ua useragent.UA, ip string, visitTime time.Time) *srvdef.SrvErr {
|
||||
uFilter := primitive.M{usermod.FN.User.Id: uId}
|
||||
user, serr := usermod.FindOneUser(ctx, uFilter)
|
||||
if serr != nil {
|
||||
return serr
|
||||
}
|
||||
|
||||
todayZero := utils.BeginOfToday()
|
||||
yesterdayZero := todayZero.AddDate(0, 0, -1)
|
||||
setDoc := primitive.M{
|
||||
usermod.FN.User.AppVer: ua.Ver,
|
||||
usermod.FN.User.SysType: ua.SysType,
|
||||
usermod.FN.User.Device: ua.DevType,
|
||||
usermod.FN.User.LastIp: ip,
|
||||
usermod.FN.User.LastLoginAt: visitTime,
|
||||
}
|
||||
mergeUAExtFields(setDoc, user, ua)
|
||||
var updateDoc primitive.M
|
||||
if user.LastLoginAt.Before(todayZero) && user.LastLoginAt.After(yesterdayZero) {
|
||||
updateDoc = primitive.M{
|
||||
"$inc": primitive.M{usermod.FN.User.ConsecutiveLogin: 1},
|
||||
"$set": setDoc,
|
||||
}
|
||||
} else {
|
||||
setDoc[usermod.FN.User.ConsecutiveLogin] = int64(1)
|
||||
updateDoc = primitive.M{"$set": setDoc}
|
||||
}
|
||||
return usermod.UpdateOneUser(ctx, uFilter, updateDoc)
|
||||
}
|
||||
|
||||
func mergeUAExtFields(setDoc primitive.M, user *usermod.User, ua useragent.UA) {
|
||||
if v := strings.TrimSpace(ua.SessionID); v != "" && v != user.SessionID {
|
||||
setDoc[usermod.FN.User.SessionID] = v
|
||||
}
|
||||
if v := strings.TrimSpace(ua.DeviceBrand); v != "" && v != user.DeviceBrand {
|
||||
setDoc[usermod.FN.User.DeviceBrand] = v
|
||||
}
|
||||
if v := strings.TrimSpace(ua.DeviceModel); v != "" && v != user.DeviceModel {
|
||||
setDoc[usermod.FN.User.DeviceModel] = v
|
||||
}
|
||||
if v := strings.TrimSpace(ua.SystemName); v != "" && v != user.SystemName {
|
||||
setDoc[usermod.FN.User.SystemName] = v
|
||||
}
|
||||
if v := strings.TrimSpace(ua.SystemVersion); v != "" && v != user.SystemVersion {
|
||||
setDoc[usermod.FN.User.SystemVersion] = v
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user