From 979e0a5278c818453826f67ee47df28349d27d1c Mon Sep 17 00:00:00 2001 From: huangjiajun <582604932@qq.com> Date: Tue, 29 Nov 2022 10:33:38 +0800 Subject: [PATCH] add reverse:for v4.1.2 test --- db/db_niu_bei_coin_basic.go | 12 +++ db/model/niu_bei_coin_basic.go | 7 +- lib/comm_plan/init.go | 19 ++-- lib/comm_plan/niubei_all.go | 150 +++++++++++++++++++++++++++++ md/block_star_chain.go | 7 ++ rule/niu_bei_release_settlement.go | 20 ++++ svc/reward_commission.go | 97 ++++++++++++++++++- 7 files changed, 301 insertions(+), 11 deletions(-) create mode 100644 lib/comm_plan/niubei_all.go diff --git a/db/db_niu_bei_coin_basic.go b/db/db_niu_bei_coin_basic.go index 77bf4bc..9bbbacd 100644 --- a/db/db_niu_bei_coin_basic.go +++ b/db/db_niu_bei_coin_basic.go @@ -87,6 +87,18 @@ func NiuBeiCoinBasicGetOneByParams(session *xorm.Session, params map[string]inte } return &m, nil } +func NiuBeiCoinBasicGetOneByParamsEg(eg *xorm.Engine, params map[string]interface{}) (*model.NiuBeiCoinBasic, error) { + var m model.NiuBeiCoinBasic + var query = fmt.Sprintf("%s =?", params["key"]) + has, err := eg.Where(query, params["value"]).Get(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + if has == false { + return nil, errors.New("未查询到相应的 block_star_chain 记录") + } + return &m, nil +} // NiuBeiCoinBasicFindByParams 通过传入的参数查询数据(多条) func NiuBeiCoinBasicFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.NiuBeiCoinBasic, error) { diff --git a/db/model/niu_bei_coin_basic.go b/db/model/niu_bei_coin_basic.go index 4087734..05ffa3b 100644 --- a/db/model/niu_bei_coin_basic.go +++ b/db/model/niu_bei_coin_basic.go @@ -16,9 +16,10 @@ type NiuBeiCoinBasic struct { DailyNiubeiCoinReleaseRatio string `json:"daily_niubei_coin_release_ratio" xorm:"not null default 0.0000 comment('每日牛贝积分释放比例') DECIMAL(10,4)"` DailyCouponCoinReleaseRatio string `json:"daily_coupon_coin_release_ratio" xorm:"not null default 0.0000 comment('每日抵扣劵释放比例') DECIMAL(10,4)"` CouponConsumeDeductionRatio string `json:"coupon_consume_deduction_ratio" xorm:"not null default 0.0000 comment('抵扣劵消费抵扣比例') DECIMAL(10,4)"` - SupplyRatio string `json:"supply_ratio" xorm:"not null default 0.0000 comment('供应链获得积分比例') DECIMAL(10,4)"` - MallRatio string `json:"mall_ratio" xorm:"not null default 0.0000 comment('自营商品获得积分比例') DECIMAL(10,4)"` - O2oRatio string `json:"o2o_ratio" xorm:"not null default '' comment('o2o获得积分比例 json ') VARCHAR(255)"` + SupplyRatio string `json:"supply_ratio" xorm:"not null default 0.0000 comment('供应链获得积分比例') DECIMAL(10,4)"` + O2oRatio string `json:"o2o_ratio" xorm:"not null default 0.0000 comment('O2O商品获得积分比例') DECIMAL(10,4)"` + MallRatio string `json:"mall_ratio" xorm:"not null default 0.0000 comment('自营商品获得积分比例') DECIMAL(10,4)"` + O2oPayRatio string `json:"o2o_pay_ratio" xorm:"not null default '' comment('o2o获得积分比例 json ') VARCHAR(255)"` ReleaseDate string `json:"release_date" xorm:"not null default '0000-00-00' comment('释放日期') VARCHAR(50)"` Ext string `json:"ext" xorm:"TEXT"` CreateAt time.Time `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' comment('创建时间') TIMESTAMP"` diff --git a/lib/comm_plan/init.go b/lib/comm_plan/init.go index 60c28db..ad66003 100644 --- a/lib/comm_plan/init.go +++ b/lib/comm_plan/init.go @@ -1,14 +1,19 @@ package comm_plan var Fn = map[string]func(opt *PlanOpt, totalAmt, integralTotalAmt float64, userList *LvUser, pvd string, sysFee float64, integralSysFee float64, level, levelWeight int) error{ - "lv_all": CalcAll, - "lv_self": CalcSelf, - "lv_subsidy": CalcAll, - "lv_price": CalcAll, - "lv_winery": CalcAll, - "lv_price_other": CalcOther, + "lv_all": CalcAll, + "niubei_commission": NiuBeiCalcAll, + "niubei_amount": NiuBeiCalcAll, + "lv_self": CalcSelf, + "lv_subsidy": CalcAll, + "lv_price": CalcAll, + "lv_winery": CalcAll, + "lv_price_other": CalcOther, +} +type NiuBeiIntegralReleaseO2oRatio struct { + Ratio string `json:"ratio"` + Key string `json:"key"` } - type PlanOpt struct { IntegralOpen int PlanCommissionId int diff --git a/lib/comm_plan/niubei_all.go b/lib/comm_plan/niubei_all.go new file mode 100644 index 0000000..2b8145b --- /dev/null +++ b/lib/comm_plan/niubei_all.go @@ -0,0 +1,150 @@ +package comm_plan + +import ( + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db" + 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" + "encoding/json" + "fmt" + "xorm.io/xorm" +) + +//佣金 积分 区块币计算 +func NiuBeiCalReturnAmountAndRatio(eg *xorm.Engine, pvd, bili string, integralFee float64, opt *PlanOpt) (commission, commissionRatio float64, amountList, ratioList []*VirtualCoinCommission) { + niuBeiRelease, err := db.NiuBeiCoinBasicGetOneByParamsEg(eg, map[string]interface{}{ + "key": "is_use", + "value": 1, + }) + if err != nil || niuBeiRelease == nil { + return 0, 0, nil, nil + } + // 佣金的比例兼容旧系统 比例独立出来的 所以这样算 + newFee := integralFee + ratio := "" + if zhios_order_relate_utils.InArr(pvd, []string{"super_group_buy", "mall_goods", "mall_group_buy", "mall_goods_user_lv"}) { + ratio = niuBeiRelease.MallRatio + } + if pvd == "mall_supply" { + ratio = niuBeiRelease.SupplyRatio + } + if pvd == "O2O" { + ratio = niuBeiRelease.O2oRatio + } + if pvd == "O2O_PAY" { + var o2oRatioSet = make([]NiuBeiIntegralReleaseO2oRatio, 0) + err := json.Unmarshal([]byte(niuBeiRelease.O2oPayRatio), &o2oRatioSet) + if err != nil { + return 0, 0, nil, nil + } + for _, v := range o2oRatioSet { + if v.Key == bili { + ratio = v.Ratio + } + } + } + amount := getCoinAmount(ratio, niuBeiRelease.Coin1, newFee, opt.VirtualCoinMoneyRatioList) + amountList = append(amountList, &VirtualCoinCommission{ + Cid: zhios_order_relate_utils.IntToStr(niuBeiRelease.Coin1), + Val: amount, + }) + ratioList = append(ratioList, &VirtualCoinCommission{ + Cid: zhios_order_relate_utils.IntToStr(niuBeiRelease.Coin1), + Val: zhios_order_relate_utils.AnyToFloat64(ratio), + }) + + for i, coin := range amountList { + amountList[i].Val = zhios_order_relate_utils.FloatFormat(coin.Val, 8) + } + + return commission, commissionRatio, amountList, ratioList +} + +// 按总佣金的比例进行划分计算 +func NiuBeiCalcAll(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") + } + //查出用户自购佣金 + userList.Profit = 0 // 另外出来的佣金 兼容旧的 + userList.ProfitList = make([]*VirtualCoinCommission, 0) // 各币种分佣 + userList.SubsidyFee = 0 + // 各种币换算出总的额度 + totalAmtList := make([]*VirtualCoinCommission, 0) + + 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 float64 = 0 // 累计佣金比例 + ) + +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 = 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 = 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 +} diff --git a/md/block_star_chain.go b/md/block_star_chain.go index 3e1e16d..2321d9e 100644 --- a/md/block_star_chain.go +++ b/md/block_star_chain.go @@ -131,3 +131,10 @@ type DealLotteryDrawReq struct { Uid int `json:"uid"` Amount string `json:"amount"` } + +type OrdParam struct { + Uid string `json:"uid"` + Pvd string `json:"pvd"` + Amount string `json:"amount"` + OrdId string `json:"ord_id"` +} diff --git a/rule/niu_bei_release_settlement.go b/rule/niu_bei_release_settlement.go index a234eff..c70961c 100644 --- a/rule/niu_bei_release_settlement.go +++ b/rule/niu_bei_release_settlement.go @@ -338,6 +338,26 @@ func ReleaseNiuBeiCoinForUser(session *xorm.Session, mid string, niuBeiRelease * return nil } +//加入释放订单 +func InsertNiuBeiOrd(session *xorm.Session, req md.OrdParam) (err error) { + var tmp = model.NiuBeiCoinUserWithOrd{ + Uid: zhios_order_relate_utils.StrToInt(req.Uid), + OrdId: req.OrdId, + Pvd: zhios_order_relate_utils.StrToInt(req.Pvd), + TotalConsumeCoinNum: req.Amount, + CreateAt: time.Now(), + UpdateAt: time.Now(), + } + insert, err := session.Insert(&tmp) + if insert == 0 { + return errors.New("写入失败") + } + if err != nil { + return err + } + return nil +} + // DealUserCoinForNiuBeiRelease 处理给用户虚拟币积分 func DealUserCoinForNiuBeiRelease(session *xorm.Session, req md.DealUserCoinReq) (err error) { if req.Amount < 0 { diff --git a/svc/reward_commission.go b/svc/reward_commission.go index db222d2..86d272c 100644 --- a/svc/reward_commission.go +++ b/svc/reward_commission.go @@ -73,7 +73,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", "lv_winery", "extend_price"}) && zhios_order_relate_utils.StrToFloat64(rmd.OldPrice) > 0 { //价格为基数 + if zhios_order_relate_utils.InArr(cfg.Mode, []string{"lv_price", "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" { //公排 @@ -173,6 +173,7 @@ func GetRewardCommission(engine *xorm.Engine, rmd *md.CommissionParam, isShare b comm(commArr, ulink) return ulink.Profit, pvdFee, sysFee, 0, ulink, nil } + if cfg.Mode == "extend_price" { //直推奖励 var ulink = &comm_plan.LvUser{} if rmd.IsGoods == "1" { //自购没奖励,就不计算了 @@ -225,6 +226,21 @@ func GetRewardCommission(engine *xorm.Engine, rmd *md.CommissionParam, isShare b } else { userRelationship = nil } + if cfg.Mode == "niubei_commission" || cfg.Mode == "niubei_amount" { // + price = zhios_order_relate_utils.Float64ToStrByPrec(comf, 8) + if cfg.Mode == "niubei_amount" { + price = rmd.OldPrice + } + pvdFee, sysFee, subsidyFee, ulink, err := NiuBeiCalcCommission(uid, level, 0, ownbuyReturnType, comf, zhios_order_relate_utils.StrToFloat64(price), isShare, cfg, userRelationship, newProvider, newLevel, engine, rmd.IsGoods, rmd) + if err != nil { + return 0, 0, 0, 0, nil, nil + } + if ulink == nil { + return 0, 0, 0, 0, nil, nil + } + comm(commArr, ulink) + return ulink.Profit, pvdFee, sysFee, subsidyFee, ulink, nil + } // userRelationship == nil 是只返回第一层 即用户自己的 pvdFee, sysFee, subsidyFee, ulink, err := CalcCommission(uid, level, 0, ownbuyReturnType, comf, zhios_order_relate_utils.StrToFloat64(price), isShare, cfg, userRelationship, newProvider, newLevel, engine, rmd.IsGoods) if err != nil { @@ -570,6 +586,85 @@ func CalcCommission(uid, level, oldDiff, ownbuyReturnType int, fee, integralFee } return pvdFee, sysFee, subsidyFee, lvUser, nil } + +// 根据用户计算对应的手续费 +//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", isGoods) + //积分扣除抽成后 + var integralSysFee float64 = 0 + integralFee, _, integralSysFee = CommFee(integralFee, opt, "integral", isGoods) + // 计算自购补贴比例 + subsidyFee = 0 + //如果没登录,要找出权重最低的那个 + if uid == 0 { + lvList, err := db.UserLevelInIDescByWeightLow(eg) + if err != nil { + fmt.Println(err) + } + if lvList != nil { + for _, v := range lvList { + level = v.Id + } + } + } + // 判断当前用户等级是否有分佣设置 + if _, ok := opt.UserRate[level]; !ok { + return 0, 0, 0, nil, errors.New("opt.UserRate[level] is nil uid=" + zhios_order_relate_utils.IntToStr(uid)) + } + // 获得自购的 + commission, _, amountList, ratioList := comm_plan.NiuBeiCalReturnAmountAndRatio(eg, pvd, rmd.GoodsCommission, integralFee, opt) + ratioListMap := convertList2Map(ratioList) + for k, v := range amountList { + amountList[k].Val = ratioListMap[v.Cid] * v.Val + } + // 如果获取用户关系失败或者佣金方案不存在, 那么只计算当前用户的佣金, 平台佣金, 以及供应商方的佣金 + if _, ok := comm_plan.Fn[opt.Mode]; !ok || userRelationShip == nil || len(*userRelationShip) == 0 { + //重新计算佣金 + return pvdFee, sysFee, subsidyFee, &comm_plan.LvUser{Uid: uid, Lv: level, OldDiff: oldDiff, Profit: commission, ProfitList: amountList, Diff: 0}, nil + } + + //查出所有等级替换权重 + levelList, _ := db.UserLevlEgAll(eg) + levelWeight := 0 + for _, v1 := range levelList { + if v1.Id == level { + levelWeight = v1.LevelWeight + } + } + lvUser = &comm_plan.LvUser{Uid: uid, Lv: level, Diff: 0, OldDiff: oldDiff, NewLv: newLevel, LevelWeight: levelWeight, OwnbuyReturnType: ownbuyReturnType} + var node = lvUser + //关系链处理 + for _, v := range *userRelationShip { + if v.Uid == 0 { + continue + } + for _, v1 := range levelList { + levelId := v.Level + if v1.Id == levelId { + levelWeight = v1.LevelWeight + } + } + node.ParentUser = &comm_plan.LvUser{Uid: v.Uid, Lv: v.Level, Diff: v.Diff, OldDiff: v.OldDiff, LevelWeight: levelWeight} + node = node.ParentUser + } + levelWeight1 := 0 + level1 := 0 + lvWeight, _ := db.UserLevelInIDescByWeightLowWithOne(eg) + if lvWeight != nil { + levelWeight1 = lvWeight.LevelWeight + level1 = lvWeight.Id + } + if err := comm_plan.Fn[opt.Mode](opt, fee, integralFee, lvUser, pvd, sysFee, integralSysFee, level1, levelWeight1); err != nil { + fmt.Println("方案有问题1") + return 0, 0, 0, nil, err + } + lvUser.Profit = commission + lvUser.ProfitList = amountList + return pvdFee, sysFee, subsidyFee, lvUser, nil +} func getOwnSubsidy(opt *comm_plan.PlanOpt, level int, isShare bool, fee, sysFee, integralFee float64) map[string]float64 { var res = make(map[string]float64) if opt.UserRate[level].SubsidyEnable != 1 {