package agentSer import ( "context" "fmt" "stat/models/channelmod" "go.mongodb.org/mongo-driver/bson" ) type RuleMap map[string]*AgentChannelRule type AgentChannelRule struct { channelmod.ChannelDeductionRule DivideRateBP int64 // 分成比列(万分比) } func (c RuleMap) GetRule(channel string, appId int32) *AgentChannelRule { key := fmt.Sprintf("%s %d", channel, appId) return c[key] } func (c RuleMap) SetRule(rule *AgentChannelRule) { key := fmt.Sprintf("%s %d", rule.Channel, rule.AppId) c[key] = rule } func GetMergedRule(channelMap ChannelMap, ruleMap RuleMap, channel string, appId int32) *AgentChannelRule { rules := make([]*AgentChannelRule, 0) cInfo := channelMap[channel] for cInfo != nil { rule := ruleMap.GetRule(cInfo.Channel, appId) if rule != nil { rules = append(rules, rule) } if cInfo.ParentAgent != "" { cInfo = channelMap[cInfo.ParentAgent] } else { cInfo = nil } } if len(rules) == 0 { return nil } for i, j := 0, len(rules)-1; i < j; i, j = i+1, j-1 { rules[i], rules[j] = rules[j], rules[i] } base := *rules[0] // 沿用父渠道代理扣量规则 rules = rules[1:] for _, rule := range rules { base.AppType = rule.AppType base.PromoteMode = rule.PromoteMode base.CPSRate = rule.CPSRate base.CPAPrice = MinInt64(base.CPAPrice, rule.CPAPrice) // 取最小的CPA价格 base.DivideRate = base.DivideRate * rule.DivideRate / 100 base.DivideRateBP = (base.DivideRateBP * rule.DivideRateBP) / 10000 } return &base } func MergedRule(parent, self *AgentChannelRule) *AgentChannelRule { if parent != nil && self != nil { rule := *self //rule.CPSRate //CPSRate not change rule.AppType = parent.AppType rule.PromoteMode = parent.PromoteMode rule.CPAPrice = MinInt64(rule.CPAPrice, parent.CPAPrice) // 取最小的CPA价格 rule.DivideRate = rule.DivideRate * parent.DivideRate / 100 rule.DivideRateBP = (rule.DivideRateBP * parent.DivideRateBP) / 10000 rule.ProxyDeduction = parent.ProxyDeduction // 传递父渠道代理扣量到子渠道 return &rule } else if parent != nil && self == nil { rule := *parent return &rule } else if parent == nil && self != nil { rule := *self return &rule } return nil } func MakeChannelAndRuleMap(ctx context.Context, channelInfo *channelmod.ChannelInfo) (ChannelMap, RuleMap, error) { var err error ruleMap := make(RuleMap) channelMap := make(ChannelMap) var channelTop string if channelInfo.Type.IsTop() { channelTop = channelInfo.Channel } else { channelTop = channelInfo.ParentChannel } filter := bson.M{ "$or": bson.A{ bson.M{channelmod.FN.ChannelInfo.Channel: channelTop}, bson.M{channelmod.FN.ChannelInfo.ParentChannel: channelTop}, }, } channelList, err := channelmod.FindManyChannelInfo(ctx, filter) if err != nil { return nil, nil, err } for _, c := range channelList { channelMap[c.Channel] = c } channels := make([]string, 0) channelInfos := channelMap.GetAncestorAndOffspringChannels(channelInfo.Channel) for _, info := range channelInfos { channels = append(channels, info.Channel) } rules, err := channelmod.FindManyChannelDeductionRule(ctx, bson.M{channelmod.FN.ChannelDeductionRule.Channel: bson.M{"$in": channels}}) if err != nil { return nil, nil, err } for _, item := range rules { item.CPAPrice = EnsureRangeInt64(item.CPAPrice, 0, 10000) item.CPSRate = EnsureRangeInt64(item.CPSRate, 0, 100) item.DivideRate = EnsureRangeInt64(item.DivideRate, 0, 100) if item.DivideRate == 0 { item.DivideRate = 100 } rule := &AgentChannelRule{ ChannelDeductionRule: *item, DivideRateBP: EnsureRangeInt64(item.DivideRate, 0, 100) * 100, } ruleMap.SetRule(rule) } return channelMap, ruleMap, nil }