@@ -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) { | |||
@@ -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"` | |||
@@ -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 | |||
@@ -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 | |||
} |
@@ -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"` | |||
} |
@@ -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 { | |||
@@ -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 { | |||