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

130 lines
3.7 KiB
Go

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
}