package channelSer import ( "context" "errors" "runtime" "stat/api/proto" "stat/common/utils" "stat/models/channelmod" "time" "github.com/jinzhu/now" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" ) // SearchChannelStat 查询渠道扣量规则信息 func SearchChannelStat(ctx context.Context, req *proto.ChannelStatSearch) (*proto.ChannelStatSearchResp, error) { resp := &proto.ChannelStatSearchResp{ List: make(channelmod.ChannelStatList, 0), } filter := bson.M{} opt := &options.FindOptions{} opt.SetSkip((req.PageNum - 1) * req.PageSize) opt.SetLimit(req.PageSize) if req.Channel != nil && *req.Channel != "" { if req.WithChild != nil && *req.WithChild { filter = bson.M{ "$or": bson.A{ bson.M{channelmod.FN.ChannelStat.Channel: *req.Channel}, bson.M{channelmod.FN.ChannelStat.ParentChannel: *req.Channel}, }, } } else { filter[channelmod.FN.ChannelStat.Channel] = *req.Channel } } else if req.DayType != nil { timeNow := time.Now() now.WeekStartDay = time.Monday Now := now.With(timeNow.In(time.Local)) todayBegin := utils.BeginWithTime(timeNow) weekBegin := Now.BeginningOfWeek() monthBegin := Now.BeginningOfMonth() var timeBegin time.Time if *req.DayType == 1 { // 今天内 timeBegin = todayBegin } else if *req.DayType == 2 { // 昨天和今天 timeBegin = todayBegin.AddDate(0, 0, -1) } else if *req.DayType == 3 { // 三天内 timeBegin = todayBegin.AddDate(0, 0, -2) } else if *req.DayType == 4 { // 七天内 timeBegin = todayBegin.AddDate(0, 0, -6) } else if *req.DayType == 5 { // 本周内 timeBegin = weekBegin } else if *req.DayType == 6 { // 两周内 timeBegin = weekBegin.AddDate(0, 0, -7) } else if *req.DayType == 7 { // 本月内 timeBegin = monthBegin } else if *req.DayType == 8 { // 两月内 timeBegin = monthBegin.AddDate(0, -1, 0) } channelList, err := channelmod.FindManyChannelInfo(ctx, bson.M{ channelmod.FN.ChannelInfo.CreatedAt: bson.M{ "$gte": timeBegin, "$lte": timeNow, }, }) if err != nil { return resp, err } channelIds := make([]string, 0) for _, channelInfo := range channelList { channelIds = append(channelIds, channelInfo.Channel) } if len(channelIds) > 0 { if req.WithChild != nil && *req.WithChild { filter = bson.M{ "$or": bson.A{ bson.M{channelmod.FN.ChannelStat.Channel: bson.M{"$in": channelIds}}, bson.M{channelmod.FN.ChannelStat.ParentChannel: bson.M{"$in": channelIds}}, }, } } else { filter[channelmod.FN.ChannelStat.Channel] = bson.M{"$in": channelIds} } } else { return resp, nil } } // //排序 if req.RankType != nil { if *req.RankType == 1 { opt.SetSort(bson.D{{Key: channelmod.FN.ChannelStat.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStat.DirectAmount, Value: -1}}) } else if *req.RankType == 2 { opt.SetSort(bson.D{{Key: channelmod.FN.ChannelStat.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStat.NewDirectCount, Value: -1}}) } else if *req.RankType == 3 { opt.SetSort(bson.D{{Key: channelmod.FN.ChannelStat.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStat.NewRechargeAmount, Value: -1}}) } else if *req.RankType == 4 { opt.SetSort(bson.D{{Key: channelmod.FN.ChannelStat.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStat.IncomeRate, Value: -1}}) } } else { opt.SetSort(bson.D{{Key: channelmod.FN.ChannelStat.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStat.NewDirectCount, Value: -1}}) } if req.UserName != nil && *req.UserName != "" { filter[channelmod.FN.ChannelStat.UserName] = bson.M{"$regex": *req.UserName} } if req.AppId != nil { filter[channelmod.FN.ChannelStat.AppId] = bson.M{"$in": *req.AppId} } if req.Start != nil && req.End != nil { filter[channelmod.FN.ChannelStat.SumDate] = bson.M{"$gte": *req.Start, "$lte": *req.End} } if req.WithChild != nil && !*req.WithChild { filter[channelmod.FN.ChannelStat.Type] = channelmod.ChannelTypeParent } if req.Settlement != nil { filter[channelmod.FN.ChannelStat.Settlement] = *req.Settlement } if req.Detail != nil && *req.Detail { if req.SumDate == nil { return resp, errors.New("param error") } filter = bson.M{ "$or": bson.A{ bson.M{channelmod.FN.ChannelStat.Channel: *req.Channel}, bson.M{channelmod.FN.ChannelStat.ParentChannel: *req.Channel}, }, channelmod.FN.ChannelStat.SumDate: *req.SumDate, } } ChannelStatList, err := channelmod.FindManyChannelStat(ctx, filter, opt) if err != nil { return resp, err } for _, v := range ChannelStatList { v.CorrectValidData() v.CalcIncomeRate() } resp.List = ChannelStatList // 汇总 canSum := utils.M(filter).HasKey(channelmod.FN.ChannelStat.AppId) && utils.M(filter).HasKey(channelmod.FN.ChannelStat.SumDate) if canSum { var total int64 err = channelmod.FindManyChannelStatShard(ctx, filter, 10000, func(item *channelmod.ChannelStat) { total++ channelmod.ChannelStatSummation(&resp.TotalInfo, item) if req.WithChild != nil && *req.WithChild { for _, v := range ChannelStatList { if item.ParentChannel == v.Channel && v.SumDate.Equal(item.SumDate) { channelmod.ChannelStatSummation(v, item) } } } }) if err != nil { return resp, err } if total == 0 { return resp, nil } if total > 10000 { runtime.GC() } resp.Total = total var ruleInfo *channelmod.ChannelDeductionRule if req.Channel != nil && *req.Channel != "" { ruleFilter := bson.M{ channelmod.FN.ChannelDeductionRule.Channel: req.Channel, // channelmod.FN.ChannelDeductionRule.AppId: req.AppId, } ruleInfo, _ = channelmod.FindOneChannelDeductionRule(ctx, ruleFilter) } if ruleInfo != nil { resp.TotalInfo.Channel = ruleInfo.Channel resp.TotalInfo.Settlement = ruleInfo.Settlement resp.TotalInfo.AppId = ruleInfo.AppId resp.TotalInfo.CPAPrice = ruleInfo.CPAPrice resp.TotalInfo.CPSRate = ruleInfo.CPSRate resp.TotalInfo.AppType = ruleInfo.AppType resp.TotalInfo.PromoteMode = ruleInfo.PromoteMode resp.TotalInfo.CalcIncomeRate() resp.Income, resp.Desc = channelmod.CalculateChannelIncome(&resp.TotalInfo) } } else { resp.Total = 1000000 } return resp, nil } // SearchChannelSettlement 查询渠道结算信息 func SearchChannelSettlement(ctx context.Context, req *proto.ChannelSettlementSearch) ( *proto.ChannelSettlementSearchResp, error) { resp := &proto.ChannelSettlementSearchResp{} filter := bson.M{} opt := &options.FindOptions{} opt.SetSort(bson.M{channelmod.FN.ChannelSettlement.CreatedAt: -1}) opt.SetSkip((req.PageNum - 1) * req.PageSize) opt.SetLimit(req.PageSize) if req.Channel != nil && *req.Channel != "" { filter[channelmod.FN.ChannelSettlement.Channel] = *req.Channel } if req.AppId != nil { filter[channelmod.FN.ChannelSettlement.AppId] = *req.AppId } if req.Start != nil && req.End != nil { filter[channelmod.FN.ChannelSettlement.SumDate] = bson.M{"$gt": *req.Start, "$lt": *req.End} } if req.WithChild != nil && *req.WithChild { filter[channelmod.FN.ChannelSettlement.Type] = channelmod.ChannelTypeParent } total, serr := channelmod.CountChannelSettlements(ctx, filter) if serr != nil { return nil, serr } if total == 0 { return resp, nil } ChannelSettlementList, err := channelmod.FindManyChannelSettlement(ctx, filter, opt) if serr != nil { return nil, err } if req.WithChild != nil && *req.WithChild { channels := make([]string, 0) for _, v := range ChannelSettlementList { channels = append(channels, v.Channel) } childTypes := channelmod.GetChildChannelTypes() filter[channelmod.FN.ChannelSettlement.Type] = bson.M{"$in": childTypes} filter[channelmod.FN.ChannelSettlement.ParentChannel] = bson.M{"$in": channels} channelsettlementList, err := channelmod.FindManyChannelStat(ctx, filter) if err != nil { return nil, err } for _, channnelSettlementInfo := range channelsettlementList { for _, v := range ChannelSettlementList { if channnelSettlementInfo.ParentChannel == v.Channel { channnelSettlementInfo.AccumulateTo(v) } } } } resp.Total = total resp.List = ChannelSettlementList return resp, nil } // SearchChannelStatCompared 渠道同时段对比 func SearchChannelStatCompared(ctx context.Context, req *proto.SearchChannelStatComparedReq) (*proto.SearchChannelStatComparedResp, error) { resp := &proto.SearchChannelStatComparedResp{} filter := bson.M{} opt := &options.FindOptions{} opt.SetSkip((req.PageNum - 1) * req.PageSize) opt.SetLimit(req.PageSize) opt.SetSort( bson.D{ {Key: channelmod.FN.ChannelStatYestoday.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStatYestoday.NewCount, Value: -1}, }, ) if req.Channel != nil && *req.Channel != "" { if req.WithChild != nil && *req.WithChild { filter = bson.M{ "$or": bson.A{ bson.M{channelmod.FN.ChannelStatYestoday.Channel: *req.Channel}, bson.M{channelmod.FN.ChannelStatYestoday.ParentChannel: *req.Channel}, }, } } else { filter[channelmod.FN.ChannelStatYestoday.Channel] = *req.Channel } } if req.AppId != nil { filter[channelmod.FN.ChannelStatYestoday.AppId] = *req.AppId } if req.Start != nil && req.End != nil { filter[channelmod.FN.ChannelStatYestoday.SumDate] = bson.M{"$gte": *req.Start, "$lte": *req.End} } if req.Settlement != nil { filter[channelmod.FN.ChannelStatYestoday.Settlement] = *req.Settlement } total, err := channelmod.CountChannelStatYestoday(ctx, filter) if err != nil { return nil, err } channelStatList, err := channelmod.FindManyChannelStatYestoday(ctx, filter, opt) if err != nil { return nil, err } resp.Total = total resp.List = channelStatList return resp, nil }