package plan import ( "fmt" "applet/app/utils" "applet/app/utils/logx" ) //佣金 积分 区块币计算 func BuyBili(level, ownbuyReturnType, peerNum int, userType string, fee float64, opt *PlanOpt) (float64, float64) { var commissionBili = opt.UserRate[level].SelfRate var commission = fee * commissionBili if userType == "same_lv" { commissionBili = opt.UserRate[level].PeerRate[peerNum] } if userType == "team" { commissionBili = opt.UserRate[level].TeamRate } commission = fee * commissionBili // 这里只用金额的 不用ReturnType了 /*if opt.UserRate[level].ReturnType != nil { //返佣类型 commissionBili = 0 commission = 0 for _, v := range opt.UserRate[level].ReturnType { if v == "commission" || v == "0" { //佣金 v==0 兼容新的版本 0代表金额 commissionBili = utils.StrToFloat64(opt.UserRate[level].SelfRateList.Commission) if userType == "same_lv" { //同级处理 commissionBili = utils.StrToFloat64(opt.UserRate[level].PeerRateList[peerNum].Commission) } if userType == "team" { //团队的 commissionBili = utils.StrToFloat64(opt.UserRate[level].TeamRateList.Commission) } commission = fee * commissionBili } if v == "integral" { //积分 integralBili = utils.StrToFloat64(opt.UserRate[level].SelfRateList.Integral) if userType == "same_lv" { //同级处理 integralBili = utils.StrToFloat64(opt.UserRate[level].PeerRateList[peerNum].Integral) } if userType == "team" { //团队的 integralBili = utils.StrToFloat64(opt.UserRate[level].TeamRateList.Integral) } integral = fee * integralBili } if v == "block_icons" { //区块币 blockIconsBili = utils.StrToFloat64(opt.UserRate[level].SelfRateList.BlockIcons) if userType == "same_lv" { //同级处理 blockIconsBili = utils.StrToFloat64(opt.UserRate[level].PeerRateList[peerNum].Commission) } if userType == "team" { //团队的 blockIconsBili = utils.StrToFloat64(opt.UserRate[level].TeamRateList.Commission) } blockIcons = fee * blockIconsBili } } }*/ if ownbuyReturnType == 1 { //自购不返利 commission = 0 commissionBili = 0 } commission = utils.FloatFormat(commission, 6) commissionBili = utils.FloatFormat(commissionBili, 6) return commission, commissionBili } // 按总佣金的比例进行划分计算 func CalcAll(grade map[int]*LvGrade, totalAmt float64, userList *LvUser, pvd string, sysFee float64, opt *PlanOpt) error { if len(grade) == 0 { return logx.Warn("level grade is not set") } //查出用户自购佣金 commission, commissionLeaveBili := BuyBili(userList.Lv, userList.OwnbuyReturnType, 0, "own", totalAmt, opt) userList.Profit = commission userList.SubsidyFee = 0 var ( node = userList maxLv = node.Lv // 当前等级 maxLevelWeight = node.LevelWeight // 当前权重 peerNum = 0 // 存在同级数 peerRate float64 = 0 // 同级累计比例 restAmt = totalAmt - userList.Profit // 剩余比例 commissionBili = commissionLeaveBili // 累计佣金比例 ) Loop: for node.ParentUser != nil { //查找上级用户 node.ParentUser.Profit = 0 //佣金补贴奖励 isCommissionSubsidyFee := 0 commissionBreak := false var commissionSubsidyBili float64 node.ParentUser.SubsidyFee, isCommissionSubsidyFee, commissionSubsidyBili = subsidyFee(grade, totalAmt, node.ParentUser, userList.NewLv, pvd, sysFee, "commission") // 如果父级比当前级别低, 跳过 // 同级奖, 如果父级别与当前级别一致,并且设置了对应比例 count := len(grade[maxLv].PeerRate) if grade[maxLv].PeerRateList != nil { count = len(grade[maxLv].PeerRateList) } // 同级奖 if node.ParentUser.LevelWeight == maxLevelWeight && count > peerNum { //同级奖励比例 commission, commissionLeaveBili := BuyBili(maxLv, userList.OwnbuyReturnType, peerNum, "same_lv", totalAmt, opt) //佣金 node.ParentUser.Profit, restAmt, commissionBili, peerRate, node.ParentUser.SubsidyFee, commissionBreak = sameMoney(node.Lv, isCommissionSubsidyFee, restAmt, commission, peerRate, commissionBili, commissionLeaveBili, node.ParentUser.SubsidyFee, commissionSubsidyBili, opt, "commission", opt.UserRate[maxLv].ReturnType) //如果都为true就结束 if commissionBreak { break Loop } peerNum++ } else if node.ParentUser.LevelWeight > maxLevelWeight { if _, ok := grade[node.Lv]; !ok { return logx.Warn("level grade node.Lv is not set") } if _, ok := grade[node.ParentUser.Lv]; !ok { return logx.Warn("level grade node.ParentUser.Lv is not set") } _, commissionLeaveBili := BuyBili(node.ParentUser.Lv, userList.OwnbuyReturnType, peerNum, "team", totalAmt, opt) //佣金 node.ParentUser.Profit = commissionLeaveBili node.ParentUser.Profit, restAmt, commissionBili, node.ParentUser.SubsidyFee, commissionBreak = teamDiffMoney(node.ParentUser.Profit, grade[node.Lv].PayMode, isCommissionSubsidyFee, totalAmt, restAmt, grade[node.ParentUser.Lv].TeamRate, commissionBili, peerRate, node.ParentUser.SubsidyFee, commissionSubsidyBili, "commission", grade[node.ParentUser.Lv].ReturnType) //如果都为true就结束 if commissionBreak { break Loop } // 等级往上升则置0 maxLevelWeight, maxLv, peerRate, peerNum = node.ParentUser.LevelWeight, node.ParentUser.Lv, 0, 0 } node.Profit = utils.StrToFloat64(fmt.Sprintf("%.4f", node.Profit)) node = node.ParentUser } return nil } //公共处理同级计算 func sameMoney(lv, isSubsidyFee int, restAmt, profit, peerRate, totalBili, leaveBili, subsidyFee, subsidyBili float64, opt *PlanOpt, types string, returnType []string) (float64, float64, float64, float64, float64, bool) { if returnType != nil { isReturn := 1 for _, v := range returnType { if v == types || (v == "0" && types == "commission") { isReturn = 0 } } if isReturn == 1 { //该方式没有返利 return profit, restAmt, totalBili, peerRate, subsidyFee, false } } else if types != "commission" && types != "0" { //该方式没有返利 兼容旧版 return profit, restAmt, totalBili, peerRate, subsidyFee, false } //如果不够扣了,并且是比例返利就跳过 if restAmt < profit { profit = 0 } //如果都邓毅0才跳过 if profit == 0 { return profit, restAmt, totalBili, peerRate, subsidyFee, true } //极差返利 if opt.UserRate[lv].PayMode == 0 && isSubsidyFee == 0 { restAmt -= profit // 剩余可分 restAmt = utils.FloatFormat(restAmt, 6) peerRate += leaveBili totalBili += leaveBili } else if isSubsidyFee == 1 { //如果只返补贴 当成是极差的一部分 所以要扣 不是额外的 profit = 0 if opt.UserRate[lv].PayMode == 0 { if restAmt < subsidyFee { subsidyFee = 0 return profit, restAmt, totalBili, subsidyFee, peerRate, true } restAmt -= subsidyFee // 剩余可分 restAmt = utils.FloatFormat(restAmt, 6) totalBili += utils.FloatFormat(subsidyBili, 6) } } return profit, restAmt, totalBili, peerRate, subsidyFee, false } //公共处理下团队-上一层 func teamDiffMoney(profit float64, payMode, isSubsidyFee int, totalAmt, restAmt, teamBili, totalBili, peerRate, subsidyFee, subsidyBili float64, types string, returnType []string) (float64, float64, float64, float64, bool) { if returnType != nil { isReturn := 1 for _, v := range returnType { if v == types || (v == "0" && types == "commission") { isReturn = 0 } } if isReturn == 1 { //该方式没有返利 return profit, restAmt, totalBili, subsidyFee, false } } else if types != "commission" && types != "0" { //该方式没有返利 兼容旧版 return profit, restAmt, totalBili, subsidyFee, false } // 如果是团队内部支出团队比例大于同级累计比例 或站长支出 if payMode == 1 || teamBili > peerRate { teamBili = utils.FloatFormat(teamBili-totalBili, 6) } //极差返利 if isSubsidyFee == 0 { totalBili += teamBili //出现负数跳过 if teamBili <= 0 { profit = 0 return profit, restAmt, totalBili, subsidyFee, true } profit = utils.FloatFormat(teamBili*totalAmt, 6) if restAmt < profit { profit = 0 return profit, restAmt, totalBili, subsidyFee, true } restAmt -= profit // 剩余可分 } else if isSubsidyFee == 1 { //如果只返补贴 当成是极差的一部分 所以要扣 不是额外的 totalBili += utils.FloatFormat(subsidyBili, 6) profit = 0 if restAmt < subsidyFee { profit = 0 subsidyFee = 0 return profit, restAmt, totalBili, subsidyFee, true } restAmt -= subsidyFee // 剩余可分 } restAmt = utils.FloatFormat(restAmt, 6) return profit, restAmt, totalBili, subsidyFee, false } //补贴金额计算 仅针对会员费 func subsidyFee(grade map[int]*LvGrade, totalAmt float64, lvuser *LvUser, newLv int, pvd string, sysFee float64, types string) (float64, int, float64) { lv := lvuser.Lv var subsidyFee float64 = 0 var bilis float64 = 0 //会员费分佣只有直推的奖励 if pvd == "user_level_up" && lvuser.Diff != 1 { return subsidyFee, 0, bilis } if _, ok := grade[lv]; !ok { return 0, 0, 0 } if grade[lv].UserSubsidyType == "" { grade[lv].UserSubsidyType = "up_lv" } isSubsidyFee := 0 //只有额外补贴跟 分销补贴按钮都开启才有的分 if grade[lv].SubsidyEnable == 1 && grade[lv].UserLvUpSubsidyEnable == 1 { //判断有没有开启 如果不是推荐会员模式 if pvd == "user_level_up" && grade[lv].UserSubsidyType != "up_lv" { return subsidyFee, isSubsidyFee, bilis } //如果不是购买商品模式 跳过 if pvd != "user_level_up" && grade[lv].UserSubsidyType != "buy_goods" { return subsidyFee, isSubsidyFee, bilis } //处理每个条件的返利 if grade[lv].UserLvUpSubsidyList != nil { fmt.Println(grade[lv].UserLvUpSubsidyList) for k, v1 := range grade[lv].UserLvUpSubsidyList { v, ok := v1.(map[string]interface{}) if ok { //如果不相等并且是会员升级的没的返 if newLv != int(utils.AnyToInt64(v["lv"])) && pvd == "user_level_up" { continue } //如果层级不是当前层级 且不是会员升级 if pvd != "user_level_up" && k+1 != lvuser.Diff { continue } //如果没开启与补贴共存 只能拿这个奖励 if int(utils.AnyToInt64(v["is_use"])) != 1 { isSubsidyFee = 1 } mode := grade[lv].SubsidyCommissionMode bili := utils.AnyToFloat64(v["bili"]) if mode != "" { //换字段了 bili = utils.AnyToFloat64(v["commission"]) } if mode == "" { //兼容旧的 if grade[lv].UserLvUpSubsidyMode == 1 { mode = "money" } } if types == "integral" { //积分 mode = grade[lv].SubsidyIntegralMode bili = utils.AnyToFloat64(v["integral"]) } if types == "block_icons" { //区块币 mode = grade[lv].SubsidyBlockIconsMode bili = utils.AnyToFloat64(v["block_icons"]) } //如果是按固定金额 if mode == "money" { subsidyFee += bili bilis = bili / totalAmt } else { //按比例分 bilis = bili / 100 //如果是按利润 if grade[lv].SubsidyMode == 1 { subsidyFee += sysFee * (bili / 100) } else { //如果按佣金 subsidyFee += totalAmt * (bili / 100) } } } } } } subsidyFee = utils.FloatFormat(subsidyFee, 6) bilis = utils.FloatFormat(bilis, 6) return subsidyFee, isSubsidyFee, bilis }