diff --git a/lib/comm_plan/init.go b/lib/comm_plan/init.go index 4c04ab6..ac9ddb6 100644 --- a/lib/comm_plan/init.go +++ b/lib/comm_plan/init.go @@ -7,7 +7,7 @@ var Fn = map[string]func(opt *PlanOpt, totalAmt, integralTotalAmt float64, userL "lv_self": CalcSelf, "lv_subsidy": CalcAll, "lv_price": CalcAll, - "lv_winery": CalcAll, + "lv_winery": CalcWinery, "lv_price_other": CalcOther, } diff --git a/lib/comm_plan/winery.go b/lib/comm_plan/winery.go new file mode 100644 index 0000000..3e57366 --- /dev/null +++ b/lib/comm_plan/winery.go @@ -0,0 +1,188 @@ +package comm_plan + +import ( + zhios_order_relate_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils" + zhios_order_relate_logx "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/logx" + "fmt" +) + +// 按总佣金的比例进行划分计算 +func CalcWinery(opt *PlanOpt, totalAmt, integralTotalAmt float64, userList *LvUser, pvd string, sysFee float64, integralSysFee float64, level, levelWeight int) error { + grade := opt.UserRate + if len(grade) == 0 { + return zhios_order_relate_logx.Warn("level grade is not set") + } + + //查出用户自购佣金 + commission, commissionRatio, amountList, ratioList := CalReturnAmountAndRatio(userList.Lv, userList.OwnbuyReturnType, 0, "own", totalAmt, integralTotalAmt, opt) + userList.Profit = commission // 另外出来的佣金 兼容旧的 + userList.ProfitList = amountList // 各币种分佣 + userList.SubsidyFee = 0 + ratioListMap := convertList2Map(ratioList) + + for k, v := range userList.ProfitList { + userList.ProfitList[k].Val = ratioListMap[v.Cid] * v.Val + } + // 各种币换算出总的额度 + totalAmtList := make([]*VirtualCoinCommission, 0) + for coinId, rate := range opt.VirtualCoinMoneyRatioList { + var amount float64 + if coinId == 0 { + amount = totalAmt + } else { + amount = integralTotalAmt * zhios_order_relate_utils.AnyToFloat64(rate) + } + totalAmtList = append(totalAmtList, &VirtualCoinCommission{ + Cid: zhios_order_relate_utils.AnyToString(coinId), + Val: amount, + }) + } + + var ( + node = userList + maxLv = node.Lv // 当前等级 + maxLevelWeight = node.LevelWeight // 当前权重 + peerNum = 0 // 存在同级数 + peerRate float64 = 0 // 同级累计比例 + peerRateList = make([]*VirtualCoinCommission, 0) // 各虚拟币同级累计 + restAmtList = make([]*VirtualCoinCommission, 0) // 各虚拟币剩余额度 + accumulateRatioList = make([]*VirtualCoinCommission, 0) // 各虚拟币累计比例 + restAmt = totalAmt - userList.Profit // 剩余比例 + totalCommissionRatio = commissionRatio // 累计佣金比例 + first = 1 + sameProfit float64 = 0 + sameProfitList = make([]*VirtualCoinCommission, 0) + ) + // 计算剩余额度 + restAmtList, _ = CalVirtualCommissionMinus(totalAmtList, amountList) + // 累计比例 + accumulateRatioList = ratioList + restAmt = zhios_order_relate_utils.FloatFormat(restAmt, 2) + +Loop: + for node.ParentUser != nil { //查找上级用户 + node.ParentUser.Profit = 0 + + //佣金补贴奖励 + subsidyFee, subsidyRatio, isOnlySubsidyFee, subsidyFeeList, subsidyRatioList := subsidyFeeDo(opt, totalAmt, integralTotalAmt, node.ParentUser, userList.NewLv, pvd, sysFee, integralSysFee) + node.ParentUser.SubsidyFee = subsidyFee + node.ParentUser.SubsidyFeeList = subsidyFeeList // 各币种补贴 + + // 如果父级比当前级别低, 跳过 + // 同级奖, 如果父级别与当前级别一致,并且设置了对应比例 + count := len(grade[maxLv].PeerRate) + if grade[maxLv].PeerRateList != nil { + count = len(grade[maxLv].PeerRateList) + } + var isBreak bool + zeroList := make(map[string]struct{}) + // 同级奖 + if node.ParentUser.LevelWeight == maxLevelWeight && count > peerNum { + var commission float64 + var commissionRatio float64 + var amountList = make([]*VirtualCoinCommission, 0) + var ratioList = make([]*VirtualCoinCommission, 0) + //同级奖励比例 + if first == 0 { + commission, commissionRatio, amountList, ratioList = CalReturnAmountAndRatioWinery(maxLv, userList.OwnbuyReturnType, peerNum, "same_lv", sameProfit, sameProfitList, opt) + } else { + commission, commissionRatio, amountList, ratioList = CalReturnAmountAndRatio(maxLv, userList.OwnbuyReturnType, peerNum, "same_lv", totalAmt, integralTotalAmt, opt) + } + //佣金 (lv, isOnlySubsidy int, restAmt, profit, peerRate, totalRatio, restRatio, subsidyFee, subsidyBili float64, opt *PlanOpt) + node.ParentUser.Profit, restAmt, totalCommissionRatio, peerRate, node.ParentUser.SubsidyFee, isBreak = sameMoney(node.Lv, isOnlySubsidyFee, restAmt, commission, peerRate, totalCommissionRatio, commissionRatio, node.ParentUser.SubsidyFee, subsidyRatio, opt) + node.ParentUser.ProfitList, restAmtList, accumulateRatioList, peerRateList, node.ParentUser.SubsidyFeeList, zeroList = sameMoneyV2(node.Lv, isOnlySubsidyFee, totalAmtList, restAmtList, amountList, peerRateList, accumulateRatioList, ratioList, node.ParentUser.SubsidyFeeList, subsidyRatioList, opt) + + // 全部都没得分了 + if isBreak && len(zeroList) == len(opt.UserRate[maxLv].ReturnType) { + break Loop + } + peerNum++ + } else if node.ParentUser.LevelWeight > maxLevelWeight { + if _, ok := grade[node.Lv]; !ok { + return zhios_order_relate_logx.Warn("level grade node.Lv is not set") + } + if _, ok := grade[node.ParentUser.Lv]; !ok { + return zhios_order_relate_logx.Warn("level grade node.ParentUser.Lv is not set") + } + commission, _, amountList, teamRatioList := CalReturnAmountAndRatio(node.ParentUser.Lv, userList.OwnbuyReturnType, peerNum, "team", totalAmt, integralTotalAmt, opt) + //佣金 + node.ParentUser.Profit = commission + node.ParentUser.Profit, restAmt, totalCommissionRatio, node.ParentUser.SubsidyFee, isBreak = teamDiffMoney(node.ParentUser.Profit, grade[node.Lv].PayMode, isOnlySubsidyFee, totalAmt, restAmt, grade[node.ParentUser.Lv].TeamRate, totalCommissionRatio, peerRate, node.ParentUser.SubsidyFee, subsidyRatio) + //积分 + node.ParentUser.ProfitList = amountList + // profitList []*VirtualCoinCommission, payMode, isOnlySubsidy int, totalAmtList, restAmtList, teamRatioList, totalRatioList, peerRateList, subsidyFeeList, subsidyRatioList []*VirtualCoinCommission + node.ParentUser.ProfitList, restAmtList, accumulateRatioList, node.ParentUser.SubsidyFeeList, zeroList = teamDiffMoneyV2(node.ParentUser.ProfitList, grade[node.Lv].PayMode, isOnlySubsidyFee, totalAmtList, restAmtList, teamRatioList, accumulateRatioList, peerRateList, subsidyFeeList, subsidyRatioList) + + // 没得分了 就结束 + if isBreak && len(zeroList) == len(opt.UserRate[maxLv].ReturnType) { + break Loop + } + // 等级往上升则置0 + maxLevelWeight, maxLv, peerRate, peerRateList, peerNum, first, sameProfit, sameProfitList = node.ParentUser.LevelWeight, node.ParentUser.Lv, 0, nil, 0, 0, node.ParentUser.Profit, node.ParentUser.ProfitList + } + //如果是酒庄制度,要看这里处理 额外的补贴 + subsidyFee, subsidyRatio, isOnlySubsidyFee, subsidyFeeList, subsidyRatioList = subsidyFeeDo(opt, totalAmt, integralTotalAmt, node.ParentUser, userList.NewLv, pvd, sysFee, integralSysFee) + node.ParentUser.SubsidyFee = subsidyFee + node.ParentUser.SubsidyFeeList = subsidyFeeList // 各币种补贴 + node.Profit = zhios_order_relate_utils.StrToFloat64(fmt.Sprintf("%.4f", node.Profit)) + node = node.ParentUser + } + + return nil +} +func CalReturnAmountAndRatioWinery(level, ownbuyReturnType, peerNum int, userType string, profit float64, profitList []*VirtualCoinCommission, opt *PlanOpt) (commission, commissionRatio float64, amountList, ratioList []*VirtualCoinCommission) { + // 佣金的比例兼容旧系统 比例独立出来的 所以这样算 + commissionRatio = getCommissionRatio(userType, level, peerNum, opt.UserRate) + commission = profit * commissionRatio + var maxReturnTypeCount = 0 + var returnType = make([]string, 0) + for _, v := range opt.UserRate { + if v.ReturnType != nil { + if len(v.ReturnType) > maxReturnTypeCount { + maxReturnTypeCount = len(v.ReturnType) + returnType = v.ReturnType + } + } + } + profitListMap := make(map[string]float64) + for _, v := range profitList { + profitListMap[v.Cid] = v.Val + } + // 新版支持多种虚拟币 支持的种类id保存在ReturnType id=0代表现金佣金 其他为虚拟币 + if returnType != nil { //返佣类型 + + for _, coinId := range returnType { + newFee := profitListMap[coinId] + if coinId == "0" { + newFee = profit + } + ratio := getVirtualCoinRatio(userType, level, peerNum, opt.UserRate, coinId) + amount := getCoinAmount(ratio, zhios_order_relate_utils.StrToInt(coinId), newFee, opt.VirtualCoinMoneyRatioList) + if coinId != "0" && opt.Mode == "lv_winery" && userType == "own" { //酒庄模式不在这里计算 + amount = 0 + } + amountList = append(amountList, &VirtualCoinCommission{ + Cid: coinId, + Val: amount, + }) + ratioList = append(ratioList, &VirtualCoinCommission{ + Cid: coinId, + Val: zhios_order_relate_utils.AnyToFloat64(ratio), + }) + } + } + + if ownbuyReturnType == 1 { //自购不返利 + commission = 0 + for i := range amountList { + amountList[i].Val = 0 + } + } + commission = zhios_order_relate_utils.FloatFormat(commission, 2) + + for i, coin := range amountList { + amountList[i].Val = zhios_order_relate_utils.FloatFormat(coin.Val, 6) + } + + return commission, commissionRatio, amountList, ratioList +}