Files
2026-05-20 16:13:58 +08:00

291 lines
9.6 KiB
Go

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
}