Browse Source

Merge remote-tracking branch 'origin/master'

tags/v3.2.2
DengBiao 2 years ago
parent
commit
560006cc13
10 changed files with 347 additions and 16 deletions
  1. +12
    -0
      db/db_user_level.go
  2. +6
    -2
      db/dbs_user.go
  3. +46
    -2
      lib/comm_plan/all.go
  4. +7
    -6
      lib/comm_plan/init.go
  5. +257
    -0
      lib/comm_plan/other.go
  6. +1
    -1
      lib/comm_plan/self.go
  7. +2
    -0
      md/commission_parameter.go
  8. +3
    -0
      rule/relate_commission.go
  9. +11
    -3
      svc/reward_commission.go
  10. +2
    -2
      svc/user_relative_network.go

+ 12
- 0
db/db_user_level.go View File

@@ -37,6 +37,18 @@ func UserLevelDescByWeightLow(session *xorm.Session) (userIds []int, err error)
}
return userIds, nil

}
func UserLevelInIDescByWeightLowWithOne(Db *xorm.Engine) (*model.UserLevel, error) {
var ms model.UserLevel
has, err := Db.Asc("level_weight").Get(&ms)
if err != nil {
return nil, err
}
if has == false {
return nil, zhios_order_relate_logx.Warn(errors.New("等级不存在"))
}
return &ms, nil

}

// UserLevlEgAll is 获取所有开启等级并且升序返回


+ 6
- 2
db/dbs_user.go View File

@@ -17,9 +17,13 @@ func DbsUserFindByIds(eg *xorm.Engine, uid []int) (*[]model.User, error) {
return &users, nil
}

func DbsUserRelate(eg *xorm.Engine, uid int) (*[]model.UserRelate, error) {
func DbsUserRelate(eg *xorm.Engine, uid, level int) (*[]model.UserRelate, error) {
var userRelate []model.UserRelate
if err := eg.Where("uid = ?", uid).Asc("level").Find(&userRelate); err != nil {
sess := eg.Where("uid = ?", uid)
if level > 0 {
sess.And("level<=?", level)
}
if err := sess.Asc("level").Find(&userRelate); err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
if len(userRelate) == 0 {


+ 46
- 2
lib/comm_plan/all.go View File

@@ -60,6 +60,33 @@ func CalReturnAmountAndRatio(level, ownbuyReturnType, peerNum int, userType stri
return commission, commissionRatio, amountList, ratioList
}

//佣金 积分 区块币计算
func CalReturnAmountAndRatioByLevel(level, ownbuyReturnType, peerNum int, userType string, fee, integralFee float64, opt *PlanOpt) (commissionRatio float64, ratioList []*VirtualCoinCommission) {
// 佣金的比例兼容旧系统 比例独立出来的 所以这样算
commissionRatio = getCommissionRatio(userType, level, peerNum, opt.UserRate)
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
}
}
}
// 新版支持多种虚拟币 支持的种类id保存在ReturnType id=0代表现金佣金 其他为虚拟币
if returnType != nil { //返佣类型
for _, coinId := range returnType {
ratio := getVirtualCoinRatio(userType, level, peerNum, opt.UserRate, coinId)
ratioList = append(ratioList, &VirtualCoinCommission{
Cid: coinId,
Val: zhios_order_relate_utils.AnyToFloat64(ratio),
})
}
}
return commissionRatio, ratioList
}

//佣金 积分 区块币计算
func CalReturnAmountAndRatioToWinery(level int, fee, integralFee float64, opt *PlanOpt) (commission, commissionRatio float64, amountList, ratioList []*VirtualCoinCommission) {
if opt.UserRate[level].ReturnType != nil { //返佣类型
@@ -89,7 +116,7 @@ func CalReturnAmountAndRatioToWinery(level int, fee, integralFee float64, opt *P
}

// 按总佣金的比例进行划分计算
func CalcAll(opt *PlanOpt, totalAmt, integralTotalAmt float64, userList *LvUser, pvd string, sysFee float64, integralSysFee float64) error {
func CalcAll(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")
@@ -624,8 +651,25 @@ func GetLvUpSubsidyVirtualCoinRatio(level, newLevel, diff int, grade map[int]*Lv
jsons, ok := oneLevelMap["rate_list"].([]interface{})
if ok {
levelRateListArr = jsons
} else {
jsons1, ok := oneLevelMap["rate_list"].(map[string]interface{})
if ok {
max := 0
for k, _ := range jsons1 {
if zhios_order_relate_utils.StrToInt(k) > max {
max = zhios_order_relate_utils.StrToInt(k)
}
}
for i := 0; i <= max; i++ {
bili, ok := jsons1[zhios_order_relate_utils.IntToStr(i)]
if ok {
levelRateListArr = append(levelRateListArr, bili)
} else {
levelRateListArr = append(levelRateListArr, "0")
}
}
}
}

}
}
if len(levelRateListArr) == 0 {


+ 7
- 6
lib/comm_plan/init.go View File

@@ -1,11 +1,12 @@
package comm_plan

var Fn = map[string]func(opt *PlanOpt, totalAmt, integralTotalAmt float64, userList *LvUser, pvd string, sysFee float64, integralSysFee float64) error{
"lv_all": CalcAll,
"lv_self": CalcSelf,
"lv_subsidy": CalcAll,
"lv_price": CalcAll,
"lv_winery": CalcAll,
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,
}

type PlanOpt struct {


+ 257
- 0
lib/comm_plan/other.go View File

@@ -0,0 +1,257 @@
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 CalcOther(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 = level // 当前等级
maxLevelWeight = 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, 6)

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 = otherSameMoney(node.Lv, isOnlySubsidyFee, restAmt, commission, peerRate, totalCommissionRatio, commissionRatio, node.ParentUser.SubsidyFee, subsidyRatio, opt)
node.ParentUser.ProfitList, restAmtList, accumulateRatioList, peerRateList, node.ParentUser.SubsidyFeeList, zeroList = otherSameMoneyV2(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")
}
if node.ParentUser.Diff == 1 {
commissionRatio1, ratioList1 := CalReturnAmountAndRatioByLevel(node.ParentUser.Lv, userList.OwnbuyReturnType, 0, "own", totalAmt, integralTotalAmt, opt)
totalCommissionRatio = commissionRatio1
accumulateRatioList = ratioList1
}
peerNum1 := 0 //不用扣同级
commission, _, amountList, teamRatioList := CalReturnAmountAndRatio(node.ParentUser.Lv, userList.OwnbuyReturnType, peerNum1, "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
}

//公共处理同级计算 (只计算佣金 旧版本用)
func otherSameMoney(lv, isOnlySubsidy int, restAmt, profit, peerRate, totalRatio, restRatio, subsidyFee, subsidyBili float64, opt *PlanOpt) (float64, float64, float64, float64, float64, bool) {
//如果不够扣了,并且是比例返利就跳过
if restAmt < profit {
return 0, restAmt, totalRatio, peerRate, subsidyFee, true
}
if opt == nil {
return 0, restAmt, totalRatio, peerRate, subsidyFee, true
}
if opt.UserRate == nil {
return 0, restAmt, totalRatio, peerRate, subsidyFee, true
}
if opt.UserRate[lv] == nil {
return 0, restAmt, totalRatio, peerRate, subsidyFee, true
}
//极差返利
if opt.UserRate[lv].PayMode == 0 && isOnlySubsidy == 0 {
restAmt -= profit // 剩余可分
restAmt = zhios_order_relate_utils.FloatFormat(restAmt, 6)
peerRate += restRatio
totalRatio += restRatio
} else if isOnlySubsidy == 1 { //如果只返补贴 当成是极差的一部分 所以要扣 不是额外的
profit = 0
if opt.UserRate[lv].PayMode == 0 {
if restAmt < subsidyFee {
subsidyFee = 0
return profit, restAmt, totalRatio, subsidyFee, peerRate, true
}
restAmt -= subsidyFee // 剩余可分
restAmt = zhios_order_relate_utils.FloatFormat(restAmt, 6)
totalRatio += zhios_order_relate_utils.FloatFormat(subsidyBili, 6)
}
}
return profit, restAmt, totalRatio, peerRate, subsidyFee, false
}

func otherSameMoneyV2(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)

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]
// 不够扣了 设为0
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
}

+ 1
- 1
lib/comm_plan/self.go View File

@@ -7,7 +7,7 @@ import (
)

// 按自购佣金进行计算
func CalcSelf(opt *PlanOpt, totalAmt float64, integralTotalAmt float64, userList *LvUser, pvd string, sysFee float64, integralSysFee float64) error {
func CalcSelf(opt *PlanOpt, totalAmt float64, 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")


+ 2
- 0
md/commission_parameter.go View File

@@ -14,6 +14,7 @@ type CommissionParam struct {
PaidPrice string `json:"paid_price"`
Oid string `json:"oid"` //标记
IsGoods string `json:"is_goods"`
IsShowExtend string `json:"is_show_extend"`
}
type CommissionFirstParam struct {
CommissionParam CommissionParam `json:"commission_param"`
@@ -27,4 +28,5 @@ type CommissionFirstParam struct {
OwnbuyReturnType int `json:"ownbuy_return_type"` //自购是否返利 0返利 1不返利
Oid string `json:"oid"`
ShowLevel string `json:"show_level"`
IsShowExtend string `json:"is_show_extend"`
}

+ 3
- 0
rule/relate_commission.go View File

@@ -45,6 +45,8 @@ func BatchGetCommissionByGoods(eg *xorm.Engine, dbName string, commissionParamLi
}
param.CommissionParam.Oid = param.GoodsId
param.CommissionParam.IsGoods = "1"
param.CommissionParam.IsShowExtend = param.IsShowExtend

_, _, _, _, lvUser, err := svc.GetRewardCommission(eg, &param.CommissionParam, isShare, param.Uid, param.Provider, dbName, isAllLevelReturn, map[string]string{}, virType)
if err != nil {
return err
@@ -146,6 +148,7 @@ func SettleCommWithGoodsDetail(eg *xorm.Engine, dbName string, CommissionParam m
}
CommissionParam.CommissionParam.Oid = CommissionParam.GoodsId
CommissionParam.CommissionParam.IsGoods = "1"
CommissionParam.CommissionParam.IsShowExtend = CommissionParam.IsShowExtend

profit, pvdFee, sysFee, subsidyFee, lvUser, err := svc.GetRewardCommission(eg, &CommissionParam.CommissionParam, isShare, CommissionParam.Uid, CommissionParam.Provider, dbName, isAllLevelReturn, mapData, virType)
return profit, pvdFee, sysFee, subsidyFee, lvUser, err


+ 11
- 3
svc/reward_commission.go View File

@@ -182,10 +182,11 @@ func GetRewardCommission(engine *xorm.Engine, rmd *md.CommissionParam, isShare b
return 0, pvdFee, sysFee, 0, ulink, nil
}
//常规级差

var userRelationship *[]md.UserRelation
if returnAllLevel {
userRelationship, err = UserRelativeNetwork(engine, uid)
userRelationship, err = UserRelativeNetwork(engine, uid, 0)
} else if rmd.IsShowExtend == "1" {
userRelationship, err = UserRelativeNetwork(engine, uid, 1)
} else {
userRelationship = nil
}
@@ -483,7 +484,14 @@ func CalcCommission(uid, level, oldDiff, ownbuyReturnType int, fee, integralFee
node.ParentUser = &comm_plan.LvUser{Uid: v.Uid, Lv: v.Level, Diff: v.Diff, OldDiff: v.OldDiff, LevelWeight: levelWeight}
node = node.ParentUser
}
if err := comm_plan.Fn[opt.Mode](opt, fee, integralFee, lvUser, pvd, sysFee, integralSysFee); err != nil {
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
}


+ 2
- 2
svc/user_relative_network.go View File

@@ -7,8 +7,8 @@ import (
)

// 获取用户关系等级, 如果返回nil则没有上级用户
func UserRelativeNetwork(eg *xorm.Engine, uid int) (*[]md.UserRelation, error) {
parent, err := db.DbsUserRelate(eg, uid)
func UserRelativeNetwork(eg *xorm.Engine, uid, level int) (*[]md.UserRelation, error) {
parent, err := db.DbsUserRelate(eg, uid, level)
if err != nil || parent == nil {
return nil, err
}


Loading…
Cancel
Save