diff --git a/lib/comm_plan/all_more_percentage.go b/lib/comm_plan/all_more_percentage.go new file mode 100644 index 0000000..5dd1460 --- /dev/null +++ b/lib/comm_plan/all_more_percentage.go @@ -0,0 +1,263 @@ +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" + "xorm.io/xorm" +) + +// 按总佣金的比例进行划分计算 +func CalcAllMorePercentage(opt *PlanOpt, totalAmt, integralTotalAmt float64, userList *LvUser, pvd string, sysFee float64, integralSysFee float64, level, levelWeight int, eg *xorm.Engine) 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 // 累计佣金比例 + ) + // 计算剩余额度 + restAmtList, _ = CalVirtualCommissionMinus(totalAmtList, amountList) + // 累计比例 + accumulateRatioList = ratioList + restAmt = zhios_order_relate_utils.FloatFormat(restAmt, 8) + +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 { + //同级奖励比例 + 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 = sameMoneyV2More(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 = teamDiffMoneyV2More(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 = node.ParentUser.LevelWeight, node.ParentUser.Lv, 0, nil, 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 // 各币种补贴 + node.Profit = zhios_order_relate_utils.StrToFloat64(fmt.Sprintf("%.4f", node.Profit)) + node = node.ParentUser + } + + return nil +} +func sameMoneyV2More(lv, isOnlySubsidy int, totalAmtList, restAmtList, profitList, peerRateList, totalRatioList, restRatioList, subsidyFeeList, subsidyRatioList []*VirtualCoinCommission, opt *PlanOpt) ([]*VirtualCoinCommission, []*VirtualCoinCommission, []*VirtualCoinCommission, []*VirtualCoinCommission, []*VirtualCoinCommission, map[string]struct{}) { + + restAmtMap := convertList2Map(restAmtList) + totalAmtMap := convertList2Map(totalAmtList) + //profitMap := convertList2Map(profitList) + restRatioMap := convertList2Map(restRatioList) + totalRatioMap := convertList2Map(totalRatioList) + peerRateMap := convertList2Map(peerRateList) + subsidyMap := convertList2Map(subsidyFeeList) + subsidyRatioMap := convertList2Map(subsidyRatioList) + + zeroList := make(map[string]struct{}) + + newProfitList := make([]*VirtualCoinCommission, 0) + newRestAmtList := make([]*VirtualCoinCommission, 0) + newTotalRatioList := make([]*VirtualCoinCommission, 0) + newPeerRateList := make([]*VirtualCoinCommission, 0) + newSubsidyFeeList := subsidyFeeList + if opt == nil { + return newProfitList, newRestAmtList, newTotalRatioList, newPeerRateList, newSubsidyFeeList, zeroList + } + if opt.UserRate == nil { + return newProfitList, newRestAmtList, newTotalRatioList, newPeerRateList, newSubsidyFeeList, zeroList + } + if opt.UserRate[lv] == nil { + return newProfitList, newRestAmtList, newTotalRatioList, newPeerRateList, newSubsidyFeeList, zeroList + } + //极差返利 + if opt.UserRate[lv].PayMode == 0 && isOnlySubsidy == 0 { + for _, coin := range profitList { + profitOne := &VirtualCoinCommission{} + profitOne.Cid = coin.Cid + profitOne.Val = totalAmtMap[coin.Cid] * restRatioMap[coin.Cid] + // 不够扣了 也给 + //if restAmtMap[coin.Cid] < profitOne.Val { + // profitOne.Val = 0 + // zeroList[coin.Cid] = struct{}{} + //} + // 分佣 + newProfitList = append(newProfitList, profitOne) + + // 剩余 + restAmtMap[coin.Cid] -= profitOne.Val + + // 累计比例 + totalRatioMap[coin.Cid] += restRatioMap[coin.Cid] + + // 同级累计比例 + if _, ok := peerRateMap[coin.Cid]; !ok { + peerRateMap[coin.Cid] = 0 + } + peerRateMap[coin.Cid] += restRatioMap[coin.Cid] + } + } else if isOnlySubsidy == 1 { + newSubsidyFeeList = make([]*VirtualCoinCommission, 0) + for _, coin := range profitList { + profitOne := &VirtualCoinCommission{} + subsidyFeeOne := &VirtualCoinCommission{} + + profitOne.Cid = coin.Cid + profitOne.Val = 0 + newProfitList = append(newProfitList, profitOne) + + if opt.UserRate[lv].PayMode == 0 { + subsidyFeeOne.Cid = coin.Cid + subsidyFeeOne.Val = subsidyMap[coin.Cid] + //if restAmtMap[coin.Cid] < subsidyMap[coin.Cid] { + // subsidyFeeOne.Val = 0 + // zeroList[coin.Cid] = struct{}{} + //} + newSubsidyFeeList = append(newSubsidyFeeList, subsidyFeeOne) + } + + // 剩余额度 + restAmtMap[coin.Cid] -= subsidyFeeOne.Val + + // 累计比例 + totalRatioMap[coin.Cid] += subsidyRatioMap[coin.Cid] + + // 同级累计比例 + if _, ok := peerRateMap[coin.Cid]; !ok { + peerRateMap[coin.Cid] = 0 + } + peerRateMap[coin.Cid] += restRatioMap[coin.Cid] + } + } + + newTotalRatioList = convertMap2List(totalRatioMap) + newPeerRateList = convertMap2List(peerRateMap) + newRestAmtList = convertMap2List(restAmtMap) + + return newProfitList, newRestAmtList, newTotalRatioList, newPeerRateList, newSubsidyFeeList, zeroList +} +func teamDiffMoneyV2More(profitList []*VirtualCoinCommission, payMode, isOnlySubsidy int, totalAmtList, restAmtList, teamRatioList, totalRatioList, peerRateList, subsidyFeeList, subsidyRatioList []*VirtualCoinCommission) (newProfitList, newRestAmtList, newTotalRatioList, newSubsidyFeeList []*VirtualCoinCommission, zeroList map[string]struct{}) { + restAmtMap := convertList2Map(restAmtList) + totalAmtMap := convertList2Map(totalAmtList) + profitMap := convertList2Map(profitList) + totalRatioMap := convertList2Map(totalRatioList) + peerRateMap := convertList2Map(peerRateList) + subsidyFeeMap := convertList2Map(subsidyFeeList) + subsidyRatioMap := convertList2Map(subsidyRatioList) + teamRatioMap := convertList2Map(teamRatioList) + + zeroList = make(map[string]struct{}) + newProfitList = make([]*VirtualCoinCommission, 0) + + for _, coin := range profitList { + // 如果是团队内部支出团队比例大于同级累计比例 或站长支出 + if payMode == 1 || teamRatioMap[coin.Cid] > peerRateMap[coin.Cid] { + teamRatioMap[coin.Cid] = zhios_order_relate_utils.FloatFormat(teamRatioMap[coin.Cid]-totalRatioMap[coin.Cid], 8) + } + + if isOnlySubsidy == 0 { + totalRatioMap[coin.Cid] += teamRatioMap[coin.Cid] + + profitOne := &VirtualCoinCommission{} + profitOne.Cid = coin.Cid + profitOne.Val = zhios_order_relate_utils.FloatFormat(totalAmtMap[coin.Cid]*teamRatioMap[coin.Cid], 8) + // 剩余不足或比例小于0 + if teamRatioMap[coin.Cid] < 0 { + zeroList[coin.Cid] = struct{}{} + profitOne.Val = 0 + } + newProfitList = append(newProfitList, profitOne) + + restAmtMap[coin.Cid] -= profitOne.Val + } else if isOnlySubsidy == 1 { //如果只返补贴 当成是极差的一部分 所以要扣 不是额外的 + totalRatioMap[coin.Cid] += zhios_order_relate_utils.FloatFormat(subsidyRatioMap[coin.Cid], 8) + profitMap[coin.Cid] = 0 + //if restAmtMap[coin.Cid] < subsidyFeeMap[coin.Cid] { + // subsidyFeeMap[coin.Cid] = 0 + //} + restAmtMap[coin.Cid] -= subsidyFeeMap[coin.Cid] + } + } + newTotalRatioList = convertMap2List(totalRatioMap) + newRestAmtList = convertMap2List(restAmtMap) + newSubsidyFeeList = convertMap2List(subsidyFeeMap) + + return newProfitList, newRestAmtList, newTotalRatioList, newSubsidyFeeList, zeroList +} diff --git a/lib/comm_plan/init.go b/lib/comm_plan/init.go index 001b037..d94eed7 100644 --- a/lib/comm_plan/init.go +++ b/lib/comm_plan/init.go @@ -3,19 +3,21 @@ package comm_plan import "xorm.io/xorm" var Fn = map[string]func(opt *PlanOpt, totalAmt, integralTotalAmt float64, userList *LvUser, pvd string, sysFee float64, integralSysFee float64, level, levelWeight int, eg *xorm.Engine) error{ - "lv_all": CalcAll, - "niubei_commission": NiuBeiCalcAll, - "niubei_amount": NiuBeiCalcAll, - "lv_self": CalcSelf, - "lv_subsidy": CalcAll, - "lv_price": CalcAll, - "lv_price_public_platoon": CalcAll, - "lv_commission_public_platoon": CalcAll, - "lv_winery": CalcWinery, - "lv_winery_adv": CalcAdv, - "lv_price_other": CalcOther, - "lv_commission_other": CalcOther, - "lv_ds_check": CalcDsCheck, + "lv_all": CalcAll, + "niubei_commission": NiuBeiCalcAll, + "niubei_amount": NiuBeiCalcAll, + "lv_self": CalcSelf, + "lv_subsidy": CalcAll, + "lv_price": CalcAll, + "lv_price_public_platoon": CalcAll, + "lv_commission_public_platoon": CalcAll, + "lv_winery": CalcWinery, + "lv_winery_adv": CalcAdv, + "lv_price_other": CalcOther, + "lv_commission_other": CalcOther, + "lv_ds_check": CalcDsCheck, + "lv_all_more_percentage_commission": CalcAllMorePercentage, + "lv_all_more_percentage_price": CalcAllMorePercentage, } type NiuBeiIntegralReleaseO2oRatio struct { diff --git a/svc/reward_commission.go b/svc/reward_commission.go index 20b65c4..34c61ac 100644 --- a/svc/reward_commission.go +++ b/svc/reward_commission.go @@ -83,7 +83,7 @@ func GetRewardCommission(engine *xorm.Engine, rmd *md.CommissionParam, isShare b fmt.Println(com) fmt.Println(price) comf := zhios_order_relate_utils.StrToFloat64(com) - if zhios_order_relate_utils.InArr(cfg.Mode, []string{"lv_price_public_platoon", "lv_price", "lv_price_other", "lv_winery", "extend_price", "niubei_amount"}) && zhios_order_relate_utils.StrToFloat64(rmd.OldPrice) > 0 { //价格为基数 + if zhios_order_relate_utils.InArr(cfg.Mode, []string{"lv_all_more_percentage_price", "lv_price_public_platoon", "lv_price", "lv_price_other", "lv_winery", "extend_price", "niubei_amount"}) && zhios_order_relate_utils.StrToFloat64(rmd.OldPrice) > 0 { //价格为基数 comf = zhios_order_relate_utils.StrToFloat64(rmd.OldPrice) } if cfg.Mode == "public_platoon" { @@ -335,7 +335,7 @@ func GetRewardCommissionService(engine *xorm.Engine, rmd *md.CommissionParam, is fmt.Println(com) fmt.Println(price) comf := zhios_order_relate_utils.StrToFloat64(com) - if zhios_order_relate_utils.InArr(cfg.Mode, []string{"lv_price_public_platoon", "lv_price", "lv_price_other", "lv_winery", "extend_price", "niubei_amount"}) && zhios_order_relate_utils.StrToFloat64(rmd.OldPrice) > 0 { //价格为基数 + if zhios_order_relate_utils.InArr(cfg.Mode, []string{"lv_all_more_percentage_price", "lv_price_public_platoon", "lv_price", "lv_price_other", "lv_winery", "extend_price", "niubei_amount"}) && zhios_order_relate_utils.StrToFloat64(rmd.OldPrice) > 0 { //价格为基数 comf = zhios_order_relate_utils.StrToFloat64(rmd.OldPrice) } if cfg.Mode == "public_platoon" { @@ -899,8 +899,8 @@ func CommFee(fee float64, opt *comm_plan.PlanOpt, types string, rmd *md.Commissi } // 根据用户计算对应的手续费 -//ownbuyReturnType 0返利 1不返利 (免单商品是淘礼金商品的时候用的) -//pvd 只是为了判断是会员升级的订单 可不传 +// ownbuyReturnType 0返利 1不返利 (免单商品是淘礼金商品的时候用的) +// pvd 只是为了判断是会员升级的订单 可不传 func CalcCommission(uid, level, oldDiff, ownbuyReturnType int, fee, integralFee float64, isShare bool, opt *comm_plan.PlanOpt, userRelationShip *[]md.UserRelation, pvd string, newLevel int, eg *xorm.Engine, isGoods string, rmd *md.CommissionParam) (pvdFee, sysFee, subsidyFee float64, lvUser *comm_plan.LvUser, err error) { //佣金扣除抽成后 var feeFirst float64 = 1 @@ -1020,8 +1020,8 @@ func CalcCommission(uid, level, oldDiff, ownbuyReturnType int, fee, integralFee } // 根据用户计算对应的手续费 -//ownbuyReturnType 0返利 1不返利 (免单商品是淘礼金商品的时候用的) -//pvd 只是为了判断是会员升级的订单 可不传 +// ownbuyReturnType 0返利 1不返利 (免单商品是淘礼金商品的时候用的) +// pvd 只是为了判断是会员升级的订单 可不传 func NiuBeiCalcCommission(uid, level, oldDiff, ownbuyReturnType int, fee, integralFee float64, isShare bool, opt *comm_plan.PlanOpt, userRelationShip *[]md.UserRelation, pvd string, newLevel int, eg *xorm.Engine, isGoods string, rmd *md.CommissionParam) (pvdFee, sysFee, subsidyFee float64, lvUser *comm_plan.LvUser, err error) { //佣金扣除抽成后 fee, _, pvdFee, sysFee = CommFee(fee, opt, "commission", rmd)