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 }