Initial commit

This commit is contained in:
2026-05-20 16:13:58 +08:00
commit ceffbe382e
500 changed files with 157469 additions and 0 deletions
+395
View File
@@ -0,0 +1,395 @@
package statdailyhour
import (
"context"
"errors"
"stat/common/log"
"stat/common/statutils"
"stat/common/utils"
"stat/models/accessmod"
"stat/models/dailyhourstatmod"
"stat/models/downloadinfo"
"stat/models/rechargegamemod"
"stat/models/rechargemod"
"stat/models/registermod"
"stat/models/syncrecharge"
"stat/models/syncvip"
"stat/models/versionMod"
"stat/models/withdrawGameOrdermod"
"strings"
"time"
"go.mongodb.org/mongo-driver/bson"
)
const (
AppVisitCount string = "appVisitCount" // app访问数
RechargeAmount string = "rechargeAmount" // 直推充值金额
NewCount string = "newDirectCount" // 新增直推
VipRechargeAmount string = "vipRechargeAmount" // VIP购买数
RechargeOrderCount string = "RechargeOrder" // VIP购买数
GameRecharge string = "GameRecharget" // 游戏充值
LandpageClick string = "landpageClick" // 游戏充值
)
func defaultTimeMap(defaultStatDate time.Time) map[string]time.Time {
return map[string]time.Time{
AppVisitCount: defaultStatDate, // App访问人数
RechargeAmount: defaultStatDate, // 直推充值金额
NewCount: defaultStatDate, // 新增直推
VipRechargeAmount: defaultStatDate, // VIP购买数
RechargeOrderCount: defaultStatDate, // 发起充值数
GameRecharge: defaultStatDate, // 游戏充值
LandpageClick: defaultStatDate, // 落地页
}
}
// 获取统计方法
type StatMethod = func(ctx context.Context, start time.Time, end time.Time, appIds []int32) error
// 统计方法汇总
var statMethodMap = map[string]StatMethod{
AppVisitCount: AppVisitCountMethod, // App访问人数
RechargeAmount: RechargeAmountMethod, // 直推充值金额
NewCount: NewCountMethod, // 新增数
VipRechargeAmount: VipRechargeAmountMethod, // VIP购买数
RechargeOrderCount: RechargeCountMethod, // 发起充值数
GameRecharge: GameRechargeMethod, // 游戏充值
LandpageClick: LandpageClickMethod, // 落地页
}
// AppVisitCountMethod app访问数
func AppVisitCountMethod(ctx context.Context, start time.Time, end time.Time, appIds []int32) error {
for _, appid := range appIds {
stat := &statutils.Stat{}
err := accessmod.VisitInfoByTimeShard(ctx, appid, start, end, utils.GlobalShardHour, func(item *accessmod.AccessMod) {
client := statutils.GetClientInfo(item.SysType, item.DevType, item.DistrictCode, item.IsDirect, false, item.IsFormalUser)
stat.Add(1, client)
})
if err != nil {
log.Error("AppVisitCountMethod ", log.E(err))
return err
}
//更新数据库
doc := dailyhourstatmod.DailyHourStatDoc{
TotalVisitCount: stat.CountRef(),
DirectVisitCount: stat.Total.Direct.CountRef(),
NaturalVisitCount: stat.Total.Direct.Natural.CountRef(),
FissionVisitCount: stat.Total.Fission.CountRef(),
DeductionVisitCount: stat.Total.Deduction.CountRef(),
IosVisitCount: stat.Ios.CountRef(),
AndroidVisitCount: stat.Android.CountRef(),
LightVisitCount: stat.Light.CountRef(),
LightVisitDirectCount: stat.Light.Total.Direct.CountRef(),
LightVisitFissionCount: stat.Light.Total.Fission.CountRef(),
LightVisitDeductionCount: stat.Light.Total.Deduction.CountRef(),
LightVisitNaturalCount: stat.Light.Total.Direct.Natural.CountRef(),
LightVisitWebCount: stat.Light.Total.Web.CountRef(),
LightVisitNormalCount: stat.Light.Total.Normal.CountRef(),
LightVisitDistrictCount: stat.Light.Total.District.CountRef(),
H5VisitCount: stat.H5.CountRef(),
H5PcVisitCount: stat.H5.Pc.CountRef(),
H5IosVisitCount: stat.H5.Ios.CountRef(),
H5AndroidVisitCount: stat.H5.Android.CountRef(),
WebVisitCount: stat.Total.Web.CountRef(),
NormalVisitCount: stat.Total.Normal.CountRef(),
DistrictVisitCount: stat.Total.District.CountRef(),
}
err = dailyhourstatmod.UpsertDailyHourStat(ctx, end, appid, doc)
if err != nil {
log.Error("DirectAmountMethod UpsertDailyHourStat ", log.E(err))
return err
}
}
return nil
}
// RechargeAmountMethod 充值金额
func RechargeAmountMethod(ctx context.Context, start time.Time, end time.Time, appIds []int32) error {
for _, appid := range appIds {
// 获取充值金额
itemList, err := rechargemod.TotalRechargeListV1(ctx, appid, start, end)
if err != nil {
log.Error("DirectAmountMethod DirectRechargeAmount ", log.E(err))
return err
}
stat := &statutils.Stat{}
repStat := &statutils.Stat{}
newStat := &statutils.Stat{}
for _, item := range itemList {
client := statutils.GetClientInfo(item.SysType, item.DevType, item.DistrictCode, item.IsDirect, false, item.IsFormalUser)
stat.Add(item.Money, client)
if item.RegisterTime.After(item.SuccessAt.AddDate(0, 0, -1)) {
newStat.Add(item.Money, client)
}
if item.Repeat {
repStat.Add(item.Money, client)
}
}
// 更新数据库
doc := dailyhourstatmod.DailyHourStatDoc{
TotalAmount: stat.ValueRef(),
SuccessRechargeOrder: stat.CountRef(),
DirectAmount: stat.Total.Direct.ValueRef(),
DirectAmountCount: stat.Total.Direct.CountRef(),
FissionAmount: stat.Total.Fission.ValueRef(),
FissionAmountCount: stat.Total.Fission.CountRef(),
NaturalAmount: stat.Total.Direct.Natural.ValueRef(),
NaturalAmountCount: stat.Total.Direct.Natural.CountRef(),
DeductionAmount: stat.Total.Deduction.ValueRef(),
DeductionAmountCount: stat.Total.Deduction.CountRef(),
AndroidAmount: stat.Android.ValueRef(),
AndroidAmountCount: stat.Android.CountRef(),
IosAmount: stat.Ios.ValueRef(),
IosAmountCount: stat.Ios.CountRef(),
LightAmount: stat.Light.ValueRef(),
LightDirectAmount: stat.Light.Total.Direct.ValueRef(),
LightFissionAmount: stat.Light.Total.Fission.ValueRef(),
LightDeductionAmount: stat.Light.Total.Deduction.ValueRef(),
LightNaturalAmount: stat.Light.Total.Direct.Natural.ValueRef(),
LightWebAmount: stat.Light.Total.Web.ValueRef(),
LightNormalAmount: stat.Light.Total.Normal.ValueRef(),
LightDistrictAmount: stat.Light.Total.District.ValueRef(),
LightAmountCount: stat.Light.CountRef(),
LightDirectAmountCount: stat.Light.Total.Direct.CountRef(),
LightFissionAmountCount: stat.Light.Total.Fission.CountRef(),
LightDeductionAmountCount: stat.Light.Total.Deduction.CountRef(),
LightNaturalAmountCount: stat.Light.Total.Direct.Natural.CountRef(),
LightWebAmountCount: stat.Light.Total.Web.CountRef(),
LightNormalAmountCount: stat.Light.Total.Normal.CountRef(),
LightDistrictAmountCount: stat.Light.Total.District.CountRef(),
H5Amount: stat.H5.ValueRef(),
H5AmountCount: stat.H5.CountRef(),
H5FormalAmount: stat.H5.Formal.ValueRef(),
H5FormalAmountCount: stat.H5.Formal.CountRef(),
H5PcAmount: stat.H5.Pc.ValueRef(),
H5PcAmountCount: stat.H5.Pc.CountRef(),
H5IosAmount: stat.H5.Ios.ValueRef(),
H5IosAmountCount: stat.H5.Ios.CountRef(),
H5AndroidAmount: stat.Android.ValueRef(),
H5AndroidAmountCount: stat.Android.CountRef(),
WebAmount: stat.Total.Web.ValueRef(),
WebAmountCount: stat.Total.Web.CountRef(),
NormalAmount: stat.Total.Normal.ValueRef(),
NormalAmountCount: stat.Total.Normal.CountRef(),
DistrictAmount: stat.Total.District.ValueRef(),
DistrictAmountCount: stat.Total.District.CountRef(),
RepeatAmount: repStat.ValueRef(),
RepeatAmountCount: repStat.CountRef(),
NewRechargeAmount: newStat.ValueRef(),
NewRechargeCount: newStat.CountRef(),
}
err = dailyhourstatmod.UpsertDailyHourStat(ctx, end, appid, doc)
if err != nil {
log.Error("DirectAmountMethod UpsertDailyHourStat ", log.E(err))
return err
}
}
return nil
}
// NewCountMethod 新增直推
func NewCountMethod(ctx context.Context, start time.Time, end time.Time, appIds []int32) error {
for _, appid := range appIds {
stat := &statutils.Stat{}
userDict := make(map[uint64]bool)
err := registermod.RegisterFormalsInfoByTimeShard(ctx, appid, start, end, utils.GlobalShardHour, func(item *registermod.RegisterMod) {
if item.IsFormal && statutils.IsClientH5OrLight(item.SysType, item.DevType) {
if _, exists := userDict[item.UserId]; !exists {
userDict[item.UserId] = true
client := statutils.GetClientInfo(item.SysType, item.DevType,
item.DistrictCode, item.IsDirect, false, item.IsFormal)
stat.Add(1, client)
}
}
})
if err != nil {
return err
}
err = registermod.RegisterUsersInfoByTimeShard(ctx, appid, start, end, utils.GlobalShardHour, func(item *registermod.RegisterMod) {
userDict[item.UserId] = true
client := statutils.GetClientInfo(item.SysType, item.DevType,
item.DistrictCode, item.IsDirect, false, item.IsFormal)
stat.Add(1, client)
})
if err != nil {
return err
}
hour := end.Local().Hour()
// 更新数据库
doc := dailyhourstatmod.DailyHourStatDoc{
SumHour: &hour,
NewTotalCount: stat.CountRef(),
NewDirectCount: stat.Total.Direct.CountRef(),
NewFissionCount: stat.Total.Fission.CountRef(),
NewDeductionCount: stat.Total.Deduction.CountRef(),
NewNaturalCount: stat.Total.Direct.Natural.CountRef(),
NewAndroidCount: stat.Android.Total.CountRef(),
NewIosCount: stat.Ios.Total.CountRef(),
NewLightCount: stat.Light.CountRef(),
NewLightGuestCount: stat.Light.Guest.CountRef(),
NewLightFormalCount: stat.Light.Formal.CountRef(),
NewLightDirectCount: stat.Light.Total.Direct.CountRef(),
NewLightFissionCount: stat.Light.Total.Fission.CountRef(),
NewLightDeductionCount: stat.Light.Total.Deduction.CountRef(),
NewLightNaturalCount: stat.Light.Total.Direct.Natural.CountRef(),
NewLightWebCount: stat.Light.Total.Web.CountRef(),
NewLightNormalCount: stat.Light.Total.Normal.CountRef(),
NewLightDistrictCount: stat.Light.Total.District.CountRef(),
NewH5Count: stat.H5.CountRef(),
NewH5PcCount: stat.H5.Pc.CountRef(),
NewH5IosCount: stat.H5.Ios.CountRef(),
NewH5AndroidCount: stat.H5.Android.CountRef(),
NewWebCount: stat.Total.Web.CountRef(),
NewNormalCount: stat.Total.Normal.CountRef(),
NewDistrictCount: stat.Total.District.CountRef(),
}
err = dailyhourstatmod.UpsertDailyHourStat(ctx, end, appid, doc)
if err != nil {
log.Error("NewDirectCountMethod UpsertDailyHourStat ", log.E(err))
return err
}
}
return nil
}
// VipRechargeAmountMethod VIP购买次数
func VipRechargeAmountMethod(ctx context.Context, start time.Time, end time.Time, appIds []int32) error {
for _, appid := range appIds {
money := int64(0)
amount := int64(0)
repeat := int64(0)
filter := bson.M{syncvip.FN.SyncVip.AppId: appid, syncvip.FN.SyncVip.SuccessAt: bson.M{"$gt": start, "$lt": end}}
viporderList, serr := syncvip.FindManySyncVip(ctx, filter)
if serr != nil {
return errors.New(serr.Error())
}
for _, viporder := range viporderList {
money += viporder.Money
amount += viporder.Amount
if viporder.Repeat {
repeat += viporder.Money
}
}
// 更新数据库
doc := dailyhourstatmod.DailyHourStatDoc{
VipPayByMoney: &money,
VipPayByAmount: &amount,
VipRepeatAmount: &repeat,
}
err := dailyhourstatmod.UpsertDailyHourStat(ctx, end, appid, doc)
if err != nil {
log.Error("NewDeductionCountMethod UpsertDailyHourStat ", log.E(err))
return err
}
}
return nil
}
// RechargeCountMethod 充值次数
func RechargeCountMethod(ctx context.Context, start time.Time, end time.Time, appIds []int32) error {
for _, appid := range appIds {
filter := bson.M{syncvip.FN.SyncVip.AppId: appid, syncrecharge.FN.SyncRechargeOrder.CreatedAt: bson.M{"$gt": start, "$lt": end}}
total, serr := syncrecharge.CountSyncRechargeOrders(ctx, filter)
if serr != nil {
return errors.New(serr.Error())
}
// 更新数据库
doc := dailyhourstatmod.DailyHourStatDoc{
TotalRechargeOrder: &total,
}
err := dailyhourstatmod.UpsertDailyHourStat(ctx, end, appid, doc)
if err != nil {
log.Error("NewDeductionCountMethod UpsertDailyHourStat ", log.E(err))
return err
}
}
return nil
}
// GameRechargeMethod 游戏充值
func GameRechargeMethod(ctx context.Context, start time.Time, end time.Time, appIds []int32) error {
for _, appid := range appIds {
rechageAmount := int64(0)
withdrawAmount := int64(0)
withdrawList, serr := withdrawGameOrdermod.GetGameWithdrawOrder(ctx, appid, start, end)
if serr != nil {
return errors.New(serr.Error())
}
for _, withdrawInfo := range withdrawList {
withdrawAmount += withdrawInfo.Money
}
filter := bson.M{"appId": appid, "successAt": bson.M{"$gt": start, "$lt": end}}
rechageList, serr := rechargegamemod.FindManyRechargeInfo(ctx, filter)
if serr != nil {
return errors.New(serr.Error())
}
for _, rechageInfo := range rechageList {
rechageAmount += rechageInfo.Money
}
// 更新数据库
doc := dailyhourstatmod.DailyHourStatDoc{
GameRechageAmount: &rechageAmount,
GameWithdrawAmount: &withdrawAmount,
}
err := dailyhourstatmod.UpsertDailyHourStat(ctx, end, appid, doc)
if err != nil {
log.Error("NewDeductionCountMethod UpsertDailyHourStat ", log.E(err))
return err
}
}
return nil
}
// LandpageClickMethod 落地页访问次数
func LandpageClickMethod(ctx context.Context, start time.Time, end time.Time, appIds []int32) error {
for _, appid := range appIds {
downloadList, err := downloadinfo.GetAccessCountByTime(ctx, appid, start, end)
if err != nil {
log.Error("RunMonitor, GetAccessCountByTime", log.E(err))
return err
}
androidClick := int64(0)
appstoreClick := int64(0)
iosAtherClick := int64(0)
h5Click := int64(0)
for _, downloadInfo := range downloadList {
if downloadInfo.SysType == "android" {
androidClick += 1
} else if strings.Contains(downloadInfo.SysType, "ios") || strings.Contains(downloadInfo.SysType, "light") {
if downloadInfo.PackageType == versionMod.Shop {
appstoreClick += 1
} else if downloadInfo.PackageType == versionMod.Enterprise {
iosAtherClick += 1
} else if downloadInfo.PackageType == versionMod.Light {
h5Click += 1
}
}
}
// 更新数据库
doc := dailyhourstatmod.DailyHourStatDoc{
LandpageAndroidClick: &androidClick,
LandpageIosAppstoreClick: &appstoreClick,
LandpageIosAthorClick: &iosAtherClick,
LandpageIosH5Click: &h5Click,
}
err = dailyhourstatmod.UpsertDailyHourStat(ctx, end, appid, doc)
if err != nil {
log.Error("NewDeductionCountMethod UpsertDailyHourStat ", log.E(err))
return err
}
}
return nil
}