package agentSer import ( "context" "sort" "stat/api/proto" "stat/models/channelmod" "time" "github.com/jinzhu/now" "go.mongodb.org/mongo-driver/bson" ) type AgentSummary struct { StartTime *time.Time EndTime *time.Time AppId *int32 FilterChannel *string ChannelInfo *channelmod.ChannelInfo ChannelMap ChannelMap RuleMap RuleMap AppMap AppMap StatMap SourceAgentStatMap SelfAgent *AgentNode SelfStats []*proto.AgentDeductedStat ChildStats []*proto.AgentDeductedStat StatTotal *proto.AgentDeductedStat } func GetAgentSummary(ctx context.Context, selfChannel string, childChannel *string, appId *int32, start, end *time.Time) (*AgentSummary, error) { summary := AgentSummary{ AppId: appId, StartTime: start, EndTime: end, FilterChannel: childChannel, SelfStats: make([]*proto.AgentDeductedStat, 0), ChildStats: make([]*proto.AgentDeductedStat, 0), AppMap: make(AppMap), } // 获取app信息字典 appMap, err := GetAppMap(ctx) if err != nil { return nil, err } summary.AppMap = appMap // 获取渠道信息和统计信息 channelInfo, statDict, err := GetAllAgentStatDict(ctx, selfChannel, appId, start, end) if err != nil { return nil, err } summary.ChannelInfo = channelInfo summary.StatMap = statDict // 获取顶层节点 rootAgent, err := GetRootAgentNode(ctx, channelInfo, childChannel, statDict) if err != nil { return nil, err } summary.SelfAgent = rootAgent // 获取渠道列表扣量规则字典 channelMap, ruleMap, err := MakeChannelAndRuleMap(ctx, channelInfo) if err != nil { return nil, err } summary.ChannelMap = channelMap summary.RuleMap = ruleMap // 添加子渠道节点 if err := rootAgent.AddChildNodes(statDict, channelMap); err != nil { return nil, err } // 累计子渠道到上级渠道 if err := rootAgent.AccumulateChildNodes(ruleMap); err != nil { return nil, err } // 计算扣量 if err := rootAgent.CalculateDeduction(channelMap, ruleMap); err != nil { return nil, err } for _, stat := range rootAgent.Stats { summary.SelfStats = append(summary.SelfStats, stat.DeductedStat) } for _, agent := range rootAgent.Children { for _, stat := range agent.Stats { summary.ChildStats = append(summary.ChildStats, stat.DeductedStat) } } // 统计总量 base := &AgentChannelStat{ DeductedStat: &proto.AgentDeductedStat{}, } for _, item := range rootAgent.Stats { AccumulateAgentChannelStat(base, item, true) } summary.StatTotal = base.DeductedStat return &summary, nil } func (a *AgentSummary) GetAgentStats(outType OutputStatListType, pageNum int64, pageSize int64) (int64, []*proto.AgentDeductedStat) { totalAgentStatList := make(AgentDeductedStatList, 0) switch outType { case OutputStatListTypeSelf: totalAgentStatList = append(totalAgentStatList, a.SelfStats...) case OutputStatListTypeChild: totalAgentStatList = append(totalAgentStatList, a.ChildStats...) default: totalAgentStatList = append(totalAgentStatList, a.SelfStats...) totalAgentStatList = append(totalAgentStatList, a.ChildStats...) } childChannel := a.FilterChannel if childChannel != nil { // 如果存在渠道过滤 outAgentStatList := make([]*proto.AgentDeductedStat, 0) for _, item := range totalAgentStatList { if item.Channel == *childChannel { outAgentStatList = append(outAgentStatList, item) } } totalAgentStatList = outAgentStatList } // 处理排序 sort.Sort(totalAgentStatList) // 处理分页输出 list := GetAgentChannelStatListPageData(totalAgentStatList, pageNum, pageSize) // 添加app名字 for _, item := range list { item.AppName = a.AppMap.GetAppName(item.AppId) if item.Channel == a.ChannelInfo.Channel { item.DivideRate = 100 } if item.Settlement == channelmod.SettlementCPA && !CPA_SHOW_MONEY { item.Recharge = 0 item.RechargeSelf = 0 item.RechargeChild = 0 } if item.Settlement == channelmod.SettlementCPS && !CPS_SHOW_COUNT { item.DirectCount = 0 item.DirectCountSelf = 0 item.DirectCountChild = 0 } } return int64(len(totalAgentStatList)), list } func (a *AgentSummary) GetAgentSummaryStats(outType OutputStatListType, pageNum int64, pageSize int64) (int64, proto.AgentSummaryStatHomeList) { totalAgentStatList := make(AgentDeductedStatList, 0) channelList := make([]*channelmod.ChannelInfo, 0) switch outType { case OutputStatListTypeSelf: channelList = append(channelList, a.SelfAgent.ChannelInfo) totalAgentStatList = append(totalAgentStatList, a.SelfStats...) case OutputStatListTypeChild: for _, node := range a.SelfAgent.Children { channelList = append(channelList, node.ChannelInfo) } totalAgentStatList = append(totalAgentStatList, a.ChildStats...) default: channelList = append(channelList, a.SelfAgent.ChannelInfo) for _, node := range a.SelfAgent.Children { channelList = append(channelList, node.ChannelInfo) } totalAgentStatList = append(totalAgentStatList, a.SelfStats...) totalAgentStatList = append(totalAgentStatList, a.ChildStats...) } // 按渠道进行汇总 summaryList := make(proto.AgentSummaryStatHomeList, 0) for _, channel := range channelList { summary := &proto.AgentSummaryStatHome{ Channel: channel.Channel, ParentAgent: channel.ParentAgent, ChildCount: channel.ChildCount, TotalStat: &proto.StatDataDetail{}, TodayStat: &proto.StatDataDetail{}, WeekStat: &proto.StatDataDetail{}, MonthStat: &proto.StatDataDetail{}, YearStat: &proto.StatDataDetail{}, } summaryList = append(summaryList, summary) } // 统计日周月年数据 nowTime := time.Now() for _, summary := range summaryList { for _, stat := range totalAgentStatList { if summary.Channel == stat.Channel { AccumulateSummaryStat(summary, stat, nowTime, true) } } } // 处理排序,收益多的靠前 sort.Sort(summaryList) // 处理分页输出 list := GetAgentSummaryStatListPageData(summaryList, pageNum, pageSize) // 添加app名字,CAP屏蔽充值,CPS屏蔽新增 for _, item := range list { item.AppName = a.AppMap.GetAppName(item.AppId) if item.Channel == a.ChannelInfo.Channel { item.DivideRate = 100 } } return int64(len(summaryList)), list } func AccumulateSummaryStat(base *proto.AgentSummaryStatHome, stat *proto.AgentDeductedStat, today time.Time, ruleData bool) { // 时间范围 now.WeekStartDay = time.Monday Now := now.With(today.In(time.Local)) todayBegin := Now.BeginningOfDay() todayEnd := Now.EndOfDay() weekBegin := Now.BeginningOfWeek() monthBegin := Now.BeginningOfMonth() yearBegin := Now.BeginningOfYear() // 复制信息 base.AppId = stat.AppId base.AppName = stat.AppName base.Settlement = stat.Settlement base.CPAPrice = stat.CPAPrice base.CPSRate = stat.CPSRate base.DivideRate = stat.DivideRate // 全部数据累加 AccumulateStatData(base.TotalStat, stat, ruleData) if (stat.SumDate.Equal(todayBegin) || stat.SumDate.After(todayBegin)) && (stat.SumDate.Equal(todayEnd) || stat.SumDate.Before(todayEnd)) { AccumulateStatData(base.TodayStat, stat, ruleData) } if (stat.SumDate.Equal(weekBegin) || stat.SumDate.After(weekBegin)) && (stat.SumDate.Equal(todayEnd) || stat.SumDate.Before(todayEnd)) { AccumulateStatData(base.WeekStat, stat, ruleData) } if (stat.SumDate.Equal(monthBegin) || stat.SumDate.After(monthBegin)) && (stat.SumDate.Equal(todayEnd) || stat.SumDate.Before(todayEnd)) { AccumulateStatData(base.MonthStat, stat, ruleData) } if (stat.SumDate.Equal(yearBegin) || stat.SumDate.After(yearBegin)) && (stat.SumDate.Equal(todayEnd) || stat.SumDate.Before(todayEnd)) { AccumulateStatData(base.YearStat, stat, ruleData) } } func GetAgentChannelStatListPageData(list []*proto.AgentDeductedStat, pageNum int64, pageSize int64) []*proto.AgentDeductedStat { start, end := GetPageRange(len(list), int(pageNum), int(pageSize)) return list[start:end] } func GetAgentSummaryStatListPageData(list proto.AgentSummaryStatHomeList, pageNum int64, pageSize int64) proto.AgentSummaryStatHomeList { start, end := GetPageRange(len(list), int(pageNum), int(pageSize)) return list[start:end] } func GetAllAgentStatDict(ctx context.Context, channel string, appId *int32, startTime, endTime *time.Time) (*channelmod.ChannelInfo, SourceAgentStatMap, error) { // 获取渠道信息 checkFilter := bson.M{channelmod.FN.ChannelInfo.Channel: channel} channelInfo, err := channelmod.FindOneChannelInfo(ctx, checkFilter) if err != nil || channelInfo.Channel != channel { return nil, nil, err } // 获取一级渠道的所有子孙数据 var channelTop string if channelInfo.Type.IsTop() { channelTop = channelInfo.Channel } else { channelTop = channelInfo.ParentChannel } srcfilter := bson.M{ channelmod.FN.ChannelStat.Type: bson.M{"$gte": channelInfo.Type}, "$or": bson.A{ bson.M{channelmod.FN.ChannelStat.Channel: channelTop}, bson.M{channelmod.FN.ChannelStat.ParentChannel: channelTop}, }} if appId != nil { srcfilter[channelmod.FN.ChannelStat.AppId] = *appId } if startTime != nil && endTime != nil { srcfilter[channelmod.FN.ChannelStat.SumDate] = bson.M{"$gte": *startTime, "$lte": *endTime} } srcList, err := channelmod.FindManyChannelStat(ctx, srcfilter) if err != nil { return nil, nil, err } srcDict := make(SourceAgentStatMap) types := channelmod.GetAllChannelTypes() for _, t := range types { srcDict[t] = make(map[string]ChannelAgentStatList) } for _, stat := range srcList { stat.CorrectValidData() stat.CalcIncomeRate() aStat := &AgentChannelStat{ ChannelStat: *stat, ChildValidDirectCount: 0, ChildValidPayMoney: 0, ChildChannelStats: make([]*AgentChannelStat, 0), } srcDict[stat.Type][stat.Channel] = append(srcDict[stat.Type][stat.Channel], aStat) } return channelInfo, srcDict, nil }