From c35cb218d52a18df3153ad322ab8a4a91cbbd7df Mon Sep 17 00:00:00 2001 From: DengBiao <2319963317@qq.com> Date: Thu, 4 Aug 2022 14:23:29 +0800 Subject: [PATCH] add Reverse: for v1.6.0 --- db/db_user_small_public_platoon_relation.go | 184 ++++++ .../user_small_public_platoon_relation.go | 21 + md/small_public_platoon_relate_commission.go | 37 ++ rule/public_platoon_relate_commission.go | 2 +- .../small_public_platoon_relate_commission.go | 574 ++++++++++++++++++ svc/small_public_platoon_relate_commission.go | 128 ++++ 6 files changed, 945 insertions(+), 1 deletion(-) create mode 100644 db/db_user_small_public_platoon_relation.go create mode 100644 db/model/user_small_public_platoon_relation.go create mode 100644 md/small_public_platoon_relate_commission.go create mode 100644 rule/small_public_platoon_relate_commission.go create mode 100644 svc/small_public_platoon_relate_commission.go diff --git a/db/db_user_small_public_platoon_relation.go b/db/db_user_small_public_platoon_relation.go new file mode 100644 index 0000000..80a5ea2 --- /dev/null +++ b/db/db_user_small_public_platoon_relation.go @@ -0,0 +1,184 @@ +package db + +import ( + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model" + 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" + "errors" + "fmt" + "reflect" + "xorm.io/xorm" +) + +// BatchSelectUserSmallPublicPlatoonRelations 批量查询数据 TODO::和下面的方法重复了,建议采用下面的 `UserSmallPublicPlatoonRelationFindByParams` 方法 +func BatchSelectUserSmallPublicPlatoonRelations(Db *xorm.Engine, params map[string]interface{}) (*[]model.UserSmallPublicPlatoonRelation, error) { + var UserSmallPublicPlatoonRelationData []model.UserSmallPublicPlatoonRelation + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]). + Find(&UserSmallPublicPlatoonRelationData); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &UserSmallPublicPlatoonRelationData, nil +} + +// UserSmallPublicPlatoonRelationInsert 插入单条数据 +func UserSmallPublicPlatoonRelationInsert(Db *xorm.Engine, UserSmallPublicPlatoonRelation *model.UserSmallPublicPlatoonRelation) (int, error) { + _, err := Db.InsertOne(UserSmallPublicPlatoonRelation) + if err != nil { + return 0, err + } + return UserSmallPublicPlatoonRelation.Id, nil +} + +// BatchAddUserSmallPublicPlatoonRelations 批量新增数据 +func BatchAddUserSmallPublicPlatoonRelations(Db *xorm.Engine, UserSmallPublicPlatoonRelationData []*model.UserSmallPublicPlatoonRelation) (int64, error) { + affected, err := Db.Insert(UserSmallPublicPlatoonRelationData) + if err != nil { + return 0, err + } + return affected, nil +} + +func GetUserSmallPublicPlatoonRelationCount(Db *xorm.Engine) int { + var UserSmallPublicPlatoonRelation model.UserSmallPublicPlatoonRelation + session := Db.Where("") + count, err := session.Count(&UserSmallPublicPlatoonRelation) + if err != nil { + return 0 + } + return int(count) +} + +// UserSmallPublicPlatoonRelationDelete 删除记录 +func UserSmallPublicPlatoonRelationDelete(Db *xorm.Engine, id interface{}) (int64, error) { + if reflect.TypeOf(id).Kind() == reflect.Slice { + return Db.In("id", id).Delete(model.UserSmallPublicPlatoonRelation{}) + } else { + return Db.Where("id = ?", id).Delete(model.UserSmallPublicPlatoonRelation{}) + } +} + +// UserSmallPublicPlatoonRelationUpdate 更新记录 +func UserSmallPublicPlatoonRelationUpdate(session *xorm.Session, id interface{}, UserSmallPublicPlatoonRelation *model.UserSmallPublicPlatoonRelation, forceColums ...string) (int64, error) { + var ( + affected int64 + err error + ) + if forceColums != nil { + affected, err = session.Where("id=?", id).Cols(forceColums...).Update(UserSmallPublicPlatoonRelation) + } else { + affected, err = session.Where("id=?", id).Update(UserSmallPublicPlatoonRelation) + } + if err != nil { + return 0, err + } + return affected, nil +} + +// UserSmallPublicPlatoonRelationGetOneByParams 通过传入的参数查询数据(单条) +func UserSmallPublicPlatoonRelationGetOneByParams(Db *xorm.Engine, params map[string]interface{}) (*model.UserSmallPublicPlatoonRelation, error) { + var m model.UserSmallPublicPlatoonRelation + var query = fmt.Sprintf("%s =?", params["key"]) + if has, err := Db.Where(query, params["value"]).Get(&m); err != nil || has == false { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil +} + +func UserSmallPublicPlatoonRelationGetOneByPid(Db *xorm.Engine, pid string, params map[string]interface{}) (*model.UserSmallPublicPlatoonRelation, error) { + var m model.UserSmallPublicPlatoonRelation + var query = fmt.Sprintf("%s =?", params["key"]) + if has, err := Db.Where("pid = ?", pid).And(query, params["value"]).Get(&m); err != nil || has == false { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil +} + +func UserSmallPublicPlatoonRelationFindByPidLike(Db *xorm.Engine, pid string) ([]model.UserSmallPublicPlatoonRelation, error) { + var m []model.UserSmallPublicPlatoonRelation + if err := Db.Where("pid like ?", "%"+pid+"%").OrderBy("position Desc"). + Find(m); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return m, nil +} + +// UserSmallPublicPlatoonRelationFindByParams 通过传入的参数查询数据(多条) +func UserSmallPublicPlatoonRelationFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.UserSmallPublicPlatoonRelation, error) { + var m []model.UserSmallPublicPlatoonRelation + if params["value"] == nil { + return nil, errors.New("参数有误") + } + if params["key"] == nil { + //查询全部数据 + err := Db.Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Find(&m); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &m, nil + } else { + var query = fmt.Sprintf("%s =?", params["key"]) + err := Db.Where(query, params["value"]).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } + + } +} + +func UserSmallPublicPlatoonRelationFindByPosition(Db *xorm.Engine, params map[string]interface{}) ([]model.UserSmallPublicPlatoonRelation, error) { + var m []model.UserSmallPublicPlatoonRelation + if params["value"] == nil { + return nil, errors.New("参数有误") + } + var query = fmt.Sprintf("%s >?", params["key"]) + err := Db.Where(query, params["value"]).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return m, nil +} + +func UserSmallPublicPlatoonRelationFindByParamsByPage(Db *xorm.Engine, params map[string]interface{}, page, pageSize int) (*[]model.UserSmallPublicPlatoonRelation, error) { + var m []model.UserSmallPublicPlatoonRelation + if params["value"] == nil { + return nil, errors.New("参数有误") + } + if page == 0 && pageSize == 0 { + page = 1 + pageSize = 10 + } + + if params["key"] == nil { + //查询全部数据 + err := Db.Limit(pageSize, (page-1)*pageSize).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &m, nil + } else { + var query = fmt.Sprintf("%s =?", params["key"]) + err := Db.Where(query, params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } + + } +} diff --git a/db/model/user_small_public_platoon_relation.go b/db/model/user_small_public_platoon_relation.go new file mode 100644 index 0000000..1409bb7 --- /dev/null +++ b/db/model/user_small_public_platoon_relation.go @@ -0,0 +1,21 @@ +package model + +import ( + "time" +) + +type UserSmallPublicPlatoonRelation struct { + Id int `json:"id" xorm:"not null pk autoincr INT(11)"` + Uid int `json:"uid" xorm:"not null default 0 comment('用户id(若为-1,则代表等待新用户填充)') unique INT(11)"` + FatherUid string `json:"father_uid" xorm:"not null default '' comment('父级id(123456-563464-438384)') index VARCHAR(100)"` + Pid int `json:"pid" xorm:"not null default 0 comment('父级id') INT(11)"` + RecommendUid int `json:"recommend_uid" xorm:"not null default 0 comment('推荐人id') INT(11)"` + Level int `json:"level" xorm:"not null default 1 comment('等级(整个系统)') INT(11)"` + Position int `json:"position" xorm:"not null default 1 comment('位置') unique INT(11)"` + UniqueIdentifier string `json:"unique_identifier" xorm:"not null default '' comment('唯一标识符(父级id-uid-等级-位置)') unique CHAR(100)"` + ReturnCommissionNum int `json:"return_commission_num" xorm:"not null default 0 comment('返佣次数') INT(11)"` + JoinAt time.Time `json:"join_at" xorm:"not null default 'CURRENT_TIMESTAMP' comment('加入公排时间') DATETIME"` + WaitForSettlementDate string `json:"wait_for_settlement_date" xorm:"not null default '' comment('待结算时间(0000-00)') CHAR(50)"` + CreateAt time.Time `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` + UpdateAt time.Time `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` +} diff --git a/md/small_public_platoon_relate_commission.go b/md/small_public_platoon_relate_commission.go new file mode 100644 index 0000000..3655733 --- /dev/null +++ b/md/small_public_platoon_relate_commission.go @@ -0,0 +1,37 @@ +package md + +// 公排结构 +type SmallLvGrade struct { + Lv int `json:"lv"` // 会员级别 + LvName string `json:"lv_name"` // 会员名称 + ReturnType []string `json:"return_type"` //返利类型 + CommonWealthSystem map[string]string `json:"common_wealth_system"` //共富制度比例 + SelfRateList map[string]string `json:"self_rate_list"` // 自购比例 + DirectPush map[string]string `json:"direct_push"` // 直推奖励比例 +} + +type SmallPublicPlatoonRelateCommissionReq struct { + Pvd string `json:"pvd"` //平台供应商 (taobao/jd/pdd/mall_goods ...) + Uid string `json:"uid"` + UserLevel string `json:"user_level"` //用户等级 + PendingAmount string `json:"pending_amount"` //待处理金额 + Oid string `json:"oid"` //订单id + PendingIntegral string `json:"pending_integral"` //待处理金额 +} + +type SmallPublicPlatoonRelateCommissionResp struct { + Uid string `json:"uid"` + CommonWealthBenefitUid string `json:"common_wealth_benefit_uid"` //共富奖励给到的uid + DirectPushBenefitUid string `json:"direct_push_benefit_uid"` //直推奖励给到的uid + PendingAmount string `json:"pending_amount"` //处理金额 + Oid string `json:"oid"` + SelfRateList map[string]string `json:"self_rate_list"` // 自购奖励 + CommonWealthSystem map[string]string `json:"common_wealth_system"` // 共富制度奖励 + DirectPush map[string]string `json:"direct_push"` // 直推奖励 + PendingIntegral string `json:"pending_integral"` //待处理金额 +} + +type SmallAddPublicPlatoonRelateCommissionReq struct { + Uid string `json:"uid"` + RecommendUid string `json:"recommend_uid"` //推荐人uid +} diff --git a/rule/public_platoon_relate_commission.go b/rule/public_platoon_relate_commission.go index 1ece6c1..c561677 100644 --- a/rule/public_platoon_relate_commission.go +++ b/rule/public_platoon_relate_commission.go @@ -67,7 +67,7 @@ func AddPublicPlatoonRelateCommission(engine *xorm.Engine, AddPublicPlatoonRelat } /* - publicPlatoon 公排方法 + 公排方法 TODO 相关公式: 1: 每个等级的起始值(1+5^0+5^1+5^2+...+5^x-2), 每个等级的结束值(`5^0+5^1+5^2+...+5^x-1) 2: 根据position查找父级position { (position-1)/5 } diff --git a/rule/small_public_platoon_relate_commission.go b/rule/small_public_platoon_relate_commission.go new file mode 100644 index 0000000..f3ad2d0 --- /dev/null +++ b/rule/small_public_platoon_relate_commission.go @@ -0,0 +1,574 @@ +package rule + +import ( + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db" + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model" + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/md" + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/svc" + 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" + "errors" + "math" + "strconv" + "strings" + "time" + "xorm.io/xorm" +) + +// BatchGetSmallPublicPlatoonRelateCommission 批量分佣 订单显示 +func BatchGetSmallPublicPlatoonRelateCommissionByOrder(engine *xorm.Engine, masterId string, SmallPublicPlatoonRelateCommissionReqList []*md.SmallPublicPlatoonRelateCommissionReq) (map[string]*md.SmallPublicPlatoonRelateCommissionResp, error) { + resp, err := svc.BatchSmallGetPublicPlatoonRelateCommission(engine, masterId, SmallPublicPlatoonRelateCommissionReqList) + if err != nil { + return nil, err + } + return resp, nil +} + +// AddSmallPublicPlatoonRelateCommission 新增小公排用户关系记录 +func AddSmallPublicPlatoonRelateCommission(engine *xorm.Engine, AddSmallPublicPlatoonRelateCommissionReqList []*md.SmallAddPublicPlatoonRelateCommissionReq) (map[string]*model.UserSmallPublicPlatoonRelation, error) { + var resp = map[string]*model.UserSmallPublicPlatoonRelation{} + //查找 `user_public_platoon_setting` 基础设置 + userPublicPlatoonSetting, err := db.UserPublicPlatoonSettingGetOneByParams(engine, map[string]interface{}{ + "key": "is_open", + "value": 1, + }) + if err != nil { + return nil, err + } + for _, param := range AddSmallPublicPlatoonRelateCommissionReqList { + //1、判断是否有推荐人 + if param.RecommendUid != "" { + //2、有推荐人 + //判断是否有uid为-2 (代表等待新用户填充) 的记录 + userSmallPublicPlatoonRelation, err := db.UserSmallPublicPlatoonRelationGetOneByPid(engine, param.RecommendUid, map[string]interface{}{ + "key": "uid", + "value": -1, + }) + if err != nil { + return nil, err + } + if userSmallPublicPlatoonRelation != nil { + userSmallPublicPlatoonRelation.Uid = zhios_order_relate_utils.StrToInt(param.Uid) + updateAffected, err := db.UserSmallPublicPlatoonRelationUpdate(engine.NewSession(), userSmallPublicPlatoonRelation.Id, userSmallPublicPlatoonRelation) + if err != nil { + return nil, err + } + if updateAffected == 0 { + err = errors.New("更新 user_public_platoon_relation 记录失败") + return nil, err + } else { + resp[param.Uid] = userSmallPublicPlatoonRelation + } + continue + } + res, err := smallPublicPlatoon(engine, zhios_order_relate_utils.StrToInt(param.Uid), zhios_order_relate_utils.StrToInt(param.RecommendUid), *userPublicPlatoonSetting) + if err != nil { + return nil, err + } + resp[param.Uid] = &res + } else { + //3、无推荐人 + + //3.1 判断是否有uid为-1 (代表等待新用户填充) 的记录 + userSmallPublicPlatoonRelation, err := db.UserSmallPublicPlatoonRelationGetOneByParams(engine, map[string]interface{}{ + "key": "uid", + "value": -1, + }) + if err != nil { + return nil, err + } + if userSmallPublicPlatoonRelation != nil { + userSmallPublicPlatoonRelation.Uid = zhios_order_relate_utils.StrToInt(param.Uid) + updateAffected, err := db.UserSmallPublicPlatoonRelationUpdate(engine.NewSession(), userSmallPublicPlatoonRelation.Id, userSmallPublicPlatoonRelation) + if err != nil { + return nil, err + } + if updateAffected == 0 { + err = errors.New("更新 user_public_platoon_relation 记录失败") + return nil, err + } else { + resp[param.Uid] = userSmallPublicPlatoonRelation + } + continue + } + + // 查找当前 user_public_platoon_relation 中 `position` 最大的记录 + var m model.UserPublicPlatoonRelation + has, err := engine.Where("recommend_uid = 0").OrderBy("id desc").Get(&m) + if err != nil { + return nil, err + } + if has == false { + return nil, errors.New("查询 user_public_platoon_relation 记录失败") + } + + // 查找当前大于 `position` 的所有记录 + mlist, err := db.UserSmallPublicPlatoonRelationFindByPosition(engine, map[string]interface{}{ + "key": "position", + "value": m.Position, + }) + if err != nil { + return nil, err + } + var mapBigUserSmallPublicPlatoonRelations map[int]interface{} + for _, item := range mlist { + mapBigUserSmallPublicPlatoonRelations[item.Position] = item + } + + res, err := naturalSmallPublicPlatoon(engine, zhios_order_relate_utils.StrToInt(param.Uid), &m.Position, *userPublicPlatoonSetting, mapBigUserSmallPublicPlatoonRelations) + if err != nil { + return nil, err + } + resp[param.Uid] = &res + } + } + return resp, nil +} + +/* + 公排方法 + TODO 相关公式: + 1: 每个等级的起始值(1+5^0+5^1+5^2+...+5^x-2), 每个等级的结束值(`5^0+5^1+5^2+...+5^x-1) + 2: 根据position查找父级position { (position-1)/5 } + 3: 根据position查找等级level {position-5^0-5^1-5^2-...-5^x 是否 <0 ? => x+1 } + 4: 根据最新自增`id` 逆向推导 position {levelFirstPosition + (position-1)%5} +*/ +func smallPublicPlatoon(engine *xorm.Engine, uid, recommendUid int, userPublicPlatoonSetting model.UserPublicPlatoonSetting) (model.UserSmallPublicPlatoonRelation, error) { + var userSmallPublicPlatoonRelation model.UserSmallPublicPlatoonRelation + + //1、 查找当前 user_small_public_platoon_relation 中 recommendUid 的记录 + m, err := db.UserSmallPublicPlatoonRelationGetOneByParams(engine, map[string]interface{}{ + "key": "uid", + "value": recommendUid, + }) + if err != nil { + return model.UserSmallPublicPlatoonRelation{}, err + } + + //2、 查找当前 user_small_public_platoon_relation 中 recommendUid 所有的子记录 + userSmallPublicPlatoonRelations, err := db.UserSmallPublicPlatoonRelationFindByPidLike(engine, strconv.Itoa(recommendUid)) + if err != nil { + return model.UserSmallPublicPlatoonRelation{}, err + } + + var position, position1, position2, pid int + var level float64 + if len(userSmallPublicPlatoonRelations) == 0 { + //证明是第一个 + position = smallSearchPositionFirstSonPosition(m.Position, userPublicPlatoonSetting.SeveralTimes) + level = float64(m.Level) + 1 + pid = m.Position + } else { + var mapUserSmallPublicPlatoonRelations map[int]interface{} + for _, item := range userSmallPublicPlatoonRelations { + mapUserSmallPublicPlatoonRelations[item.Position] = item + } + position1 = userSmallPublicPlatoonRelations[0].Position + userPublicPlatoonSetting.SeveralTimes + position2 = userSmallPublicPlatoonRelations[0].Position + 1 + level = float64(userSmallPublicPlatoonRelations[0].Level) + + //判断 position1 的上级是否还属于 + fatherPosition1 := smallMakeSearchPid(position1, userPublicPlatoonSetting.SeveralTimes) + fatherPosition2 := smallMakeSearchPid(position2, userPublicPlatoonSetting.SeveralTimes) + if mapUserSmallPublicPlatoonRelations[fatherPosition1] != nil { + //属于 + position = position1 + pid = fatherPosition1 + } else { + if mapUserSmallPublicPlatoonRelations[fatherPosition2] != nil { + //同级 + tmpPosition := (userSmallPublicPlatoonRelations[0].Position + 1 + userPublicPlatoonSetting.SeveralTimes) - int(math.Pow(float64(userPublicPlatoonSetting.SeveralTimes), float64(smallSearchPositionSonForLevel(userSmallPublicPlatoonRelations[0])))) + if mapUserSmallPublicPlatoonRelations[tmpPosition] != nil { + position = position2 + pid = fatherPosition2 + } else { + //回归 + position = tmpPosition + pid = smallMakeSearchPid(position, userPublicPlatoonSetting.SeveralTimes) + } + } else { + //新的一级 + tmpPosition := (userSmallPublicPlatoonRelations[0].Position + 1) - int(math.Pow(float64(userPublicPlatoonSetting.SeveralTimes), float64(smallSearchPositionSonForLevel(userSmallPublicPlatoonRelations[0])))) + position = smallSearchPositionFirstSonPosition(m.Position, userPublicPlatoonSetting.SeveralTimes) + smallMakeSearchLevel(&position1, float64(userPublicPlatoonSetting.SeveralTimes), &level) + pid = tmpPosition + } + } + } + + //2、查找对应pid的 user_public_platoon_relation 记录 + var m1 model.UserPublicPlatoonRelation + if has, err := engine.Where("position=?", pid).Get(&m1); err != nil || has == false { + return userSmallPublicPlatoonRelation, err + } + var fatherUid string + if m1.FatherUid == "" { + //TODO::顶级 + fatherUid = zhios_order_relate_utils.IntToStr(m1.Position) + } else { + fatherUids := strings.Split(m1.FatherUid, "-") + if len(fatherUids) > userPublicPlatoonSetting.SeveralRows { + fatherUid = zhios_order_relate_utils.IntToStr(m1.Position) + "-" + strings.Join(fatherUids[0:userPublicPlatoonSetting.SeveralRows:len(fatherUids)], "-") + } else { + fatherUid = zhios_order_relate_utils.IntToStr(m1.Position) + "-" + m1.FatherUid + } + } + + //唯一标识符(父级id-uid-等级-位置) + var uniqueIdentifier = zhios_order_relate_utils.IntToStr(pid) + "-" + zhios_order_relate_utils.IntToStr(uid) + "-" + zhios_order_relate_utils.IntToStr(int(level)) + "-" + zhios_order_relate_utils.IntToStr(position) + + // 3、插入 user_public_platoon_relation 记录 + now := time.Now() + userSmallPublicPlatoonRelation.Uid = uid + userSmallPublicPlatoonRelation.FatherUid = fatherUid + userSmallPublicPlatoonRelation.Pid = pid + userSmallPublicPlatoonRelation.RecommendUid = recommendUid + userSmallPublicPlatoonRelation.Level = int(level) + userSmallPublicPlatoonRelation.Position = position + userSmallPublicPlatoonRelation.UniqueIdentifier = uniqueIdentifier + userSmallPublicPlatoonRelation.WaitForSettlementDate = now.AddDate(0, 0, 30).Format("2006-01-02") + userSmallPublicPlatoonRelation.JoinAt = now + userSmallPublicPlatoonRelation.CreateAt = now + userSmallPublicPlatoonRelation.UpdateAt = now + _, err = db.UserSmallPublicPlatoonRelationInsert(engine, &userSmallPublicPlatoonRelation) + if err != nil { + return model.UserSmallPublicPlatoonRelation{}, err + } + return userSmallPublicPlatoonRelation, nil +} + +func naturalSmallPublicPlatoon(engine *xorm.Engine, uid int, originalPosition *int, userPublicPlatoonSetting model.UserPublicPlatoonSetting, mapBigUserSmallPublicPlatoonRelations map[int]interface{}) (model.UserSmallPublicPlatoonRelation, error) { + var userPublicPlatoonRelation model.UserSmallPublicPlatoonRelation + //TODO::判断 `position + userPublicPlatoonSetting.SeveralTimes(几乘)` OR `position + 1` + var position, position1, position2 int + position1 = *originalPosition + 1 + position2 = *originalPosition + userPublicPlatoonSetting.SeveralTimes + var level, level1, level2 float64 + makeSearchLevel(&position1, float64(userPublicPlatoonSetting.SeveralTimes), &level1) + makeSearchLevel(&position2, float64(userPublicPlatoonSetting.SeveralTimes), &level2) + level = level1 + 1 //TODO::根据公式需要 + 1 + if level > 2 { + if level1 != level2 { + position = reverseDeductionPosition(*originalPosition, getLevelForFirstPosition(int(level), userPublicPlatoonSetting.SeveralTimes), userPublicPlatoonSetting.SeveralTimes) + } else { + if position1 == getLevelForFirstPosition(int(level), userPublicPlatoonSetting.SeveralTimes) { + position = position1 + } else { + position = position2 + } + } + } else { + position = position1 + } + if mapBigUserSmallPublicPlatoonRelations[position] != nil { + return naturalSmallPublicPlatoon(engine, uid, originalPosition, userPublicPlatoonSetting, mapBigUserSmallPublicPlatoonRelations) + } + + pid := makeSearchPid(position, userPublicPlatoonSetting.SeveralTimes) + + //2、查找对应pid的 user_public_platoon_relation 记录 + var m1 model.UserPublicPlatoonRelation + if has, err := engine.Where("position=?", pid).Get(&m1); err != nil || has == false { + return userPublicPlatoonRelation, err + } + var fatherUid string + if m1.FatherUid == "" { + //TODO::顶级 + fatherUid = zhios_order_relate_utils.IntToStr(m1.Position) + } else { + fatherUids := strings.Split(m1.FatherUid, "-") + if len(fatherUids) > userPublicPlatoonSetting.SeveralRows { + fatherUid = zhios_order_relate_utils.IntToStr(m1.Position) + "-" + strings.Join(fatherUids[0:userPublicPlatoonSetting.SeveralRows:len(fatherUids)], "-") + } else { + fatherUid = zhios_order_relate_utils.IntToStr(m1.Position) + "-" + m1.FatherUid + } + } + + //唯一标识符(父级id-uid-等级-位置) + var uniqueIdentifier = zhios_order_relate_utils.IntToStr(pid) + "-" + zhios_order_relate_utils.IntToStr(uid) + "-" + zhios_order_relate_utils.IntToStr(int(level)) + "-" + zhios_order_relate_utils.IntToStr(position) + + // 3、插入 user_public_platoon_relation 记录 + now := time.Now() + userPublicPlatoonRelation.Uid = uid + userPublicPlatoonRelation.FatherUid = fatherUid + userPublicPlatoonRelation.Pid = pid + userPublicPlatoonRelation.RecommendUid = 0 + userPublicPlatoonRelation.Level = int(level) + userPublicPlatoonRelation.Position = position + userPublicPlatoonRelation.UniqueIdentifier = uniqueIdentifier + userPublicPlatoonRelation.WaitForSettlementDate = now.AddDate(0, 0, 30).Format("2006-01-02") + userPublicPlatoonRelation.JoinAt = now + userPublicPlatoonRelation.CreateAt = now + userPublicPlatoonRelation.UpdateAt = now + _, err := db.UserSmallPublicPlatoonRelationInsert(engine, &userPublicPlatoonRelation) + if err != nil { + return model.UserSmallPublicPlatoonRelation{}, err + } + return userPublicPlatoonRelation, nil +} + +// smallReverseDeductionPosition 逆向推导 position +func smallReverseDeductionPosition(calcPosition, levelFirstPosition, severalTimes int) (position int) { + remainder := (calcPosition - 1) % severalTimes + position = levelFirstPosition + remainder + return +} + +// smallGetLevelForFirstPosition 返回当前等级的起始值 +func smallGetLevelForFirstPosition(level, severalTimes int) (position int) { + position = position + 1 + for n := 0; n <= (level - 2); n++ { + position += int(math.Pow(float64(severalTimes), float64(n))) + } + return +} + +//递归查找等级 +func smallMakeSearchLevel(position *int, rows float64, times *float64) (level int) { + difference := *position - int(math.Pow(rows, *times)) + if difference <= 0 { + return int(*times) + } else { + position = &difference + *times++ + return smallMakeSearchLevel(position, rows, times) + } +} + +//查找归属父级id +func smallMakeSearchPid(position int, row int) (pid int) { + divisionValue := (position - 1) / row + if divisionValue == 0 { + pid = 1 + return + } else { + if (divisionValue*row + 1) == position { + pid = divisionValue + return + } else { + pid = divisionValue + 1 + return + } + } +} + +//查找当前位置下的第一个子集位置 +func smallSearchPositionFirstSonPosition(position int, times int) (sonPosition int) { + sonPosition = (position * times) - (times - 2) + return +} + +//查找当前位位置相当于父级的等级 +func smallSearchPositionSonForLevel(m model.UserSmallPublicPlatoonRelation) (level int) { + fatherUids := strings.Split(m.FatherUid, "-") + for key, item := range fatherUids { + if item == strconv.Itoa(m.Pid) { + level = key + 1 + break + } + } + return +} + +// smallFindWaitForDealUsers 查询待处理的用户 +func smallFindWaitForDealUsers(engine *xorm.Engine, page, pageSize int) (err error, resp []int) { + now := time.Now().Format("2006-01-02") + lists, err := db.UserPublicPlatoonRelationFindByParamsByPage(engine, map[string]interface{}{ + "key": "wait_for_settlement_date", + "value": now, + }, page, pageSize) + if err != nil { + return + } + for _, list := range *lists { + resp = append(resp, list.Uid) + } + return +} + +// SmallUpdateWaitForSettlementDate 改变 `wait_for_settlement_date` 待结算时间 +func SmallUpdateWaitForSettlementDate(engine *xorm.Engine, userIds []string) (err error) { + //Todo:: 将 user_public_platoon_relation 中 wait_for_settlement_date 设置为 30天后 + sql := "update user_public_platoon_amount set wait_for_settlement_date = ? where uid in (" + strings.Join(userIds, ",") + ")" + waitForSettlementDate := time.Now().AddDate(0, 0, 30).Format("2006-01-02") + _, err = engine.Exec(sql, waitForSettlementDate) + if err != nil { + return + } + return +} + +// SmallDealCommonWealthReward 处理共富奖励 +func SmallDealCommonWealthReward(engine *xorm.Engine, uid int, isCompleteReward bool) (err error, resp []map[string]string) { + session := engine.NewSession() + defer func() { + session.Close() + if err := recover(); err != nil { + _ = zhios_order_relate_logx.Error(err) + } + }() + session.Begin() + + //1、查询出 `user_public_platoon_amount` 中相关记录 + params, err := db.UserPublicPlatoonAmountFindByParams(engine, map[string]interface{}{ + "key": "uid", + "value": uid, + }) + if err != nil { + _ = session.Rollback() + return + } + + //2、完成共富奖励(插入 user_public_platoon_settlement_records 记录) && 构造返回数据 + var userPublicPlatoonSettlementRecords []*model.UserPublicPlatoonSettlementRecords + var userPublicPlatoonIncomeRecords []*model.UserPublicPlatoonIncomeRecords + + now := time.Now() + for _, param := range *params { + var userPublicPlatoonSettlementRecord = model.UserPublicPlatoonSettlementRecords{ + Uid: param.Uid, + CoinId: param.CoinId, + Amount: param.Amount, + Title: "结算共富奖励", + Date: now.AddDate(0, 0, 30).Format("2006-01-02"), + CreateAt: now, + UpdateAt: now, + } + //流水表 + var userPublicPlatoonIncomeRecord = model.UserPublicPlatoonIncomeRecords{ + Uid: param.Uid, + CoinId: param.CoinId, + Amount: param.Amount, + Date: now.AddDate(0, 0, 30).Format("2006-01-02"), + CreateAt: now, + UpdateAt: now, + } + if isCompleteReward { + userPublicPlatoonIncomeRecord.Title = "共富收益转入余额" + userPublicPlatoonIncomeRecord.Kind = 1 + userPublicPlatoonSettlementRecord.Kind = 1 + resp = append(resp, map[string]string{ + zhios_order_relate_utils.AnyToString(param.CoinId): param.Amount, + }) + } else { + userPublicPlatoonIncomeRecord.Title = "共富收益清零" + userPublicPlatoonIncomeRecord.Kind = 2 + userPublicPlatoonSettlementRecord.Kind = 2 + } + if zhios_order_relate_utils.StrToFloat64(userPublicPlatoonSettlementRecord.Amount) > 0 { + userPublicPlatoonSettlementRecords = append(userPublicPlatoonSettlementRecords, &userPublicPlatoonSettlementRecord) + } + if zhios_order_relate_utils.StrToFloat64(userPublicPlatoonIncomeRecord.Amount) > 0 { + userPublicPlatoonIncomeRecords = append(userPublicPlatoonIncomeRecords, &userPublicPlatoonIncomeRecord) + } + } + affected, err := db.BatchAddUserPublicPlatoonSettlementRecordss(session, userPublicPlatoonSettlementRecords) + if err != nil { + _ = session.Rollback() + return + } + if affected == 0 { + err = errors.New("插入 user_public_platoon_settlement_records 记录失败") + _ = session.Rollback() + return + } + affectedIncome, errIncome := db.BatchAddUserPublicPlatoonIncomeRecordss(session, userPublicPlatoonIncomeRecords) + if errIncome != nil { + _ = session.Rollback() + return + } + if affectedIncome == 0 { + err = errors.New("插入 user_public_platoon_settlement_records 记录失败") + _ = session.Rollback() + return + } + + //3、将 user_public_platoon_amount 相关记录的 amount 置 0 + sql := "update user_public_platoon_amount set amount = ? where uid = ?" + _, err = session.Exec(sql, 0, uid) + if err != nil { + _ = session.Rollback() + return + } + err = session.Commit() + return +} + +// SmallDealCommonWealthPunish 处理共富处罚 +func SmallDealCommonWealthPunish(engine *xorm.Engine, uid int, reason string) (err error, resp []map[string]string) { + session := engine.NewSession() + defer func() { + session.Close() + if err := recover(); err != nil { + _ = zhios_order_relate_logx.Error(err) + } + }() + session.Begin() + + //1、查找 `user_public_platoon_setting` 基础设置 + userPublicPlatoonSetting, err := db.UserPublicPlatoonSettingGetOneByParams(engine, map[string]interface{}{ + "key": "is_open", + "value": 1, + }) + if err != nil { + _ = session.Rollback() + return + } + + //2、查询出 `user_public_platoon_relation` 中相关记录 && 将该记录的uid置为 -1 + params, err := db.UserPublicPlatoonRelationGetOneByParams(engine, map[string]interface{}{ + "key": "uid", + "value": uid, + }) + if err != nil { + _ = session.Rollback() + return + } + if params == nil { + err = errors.New("未查询到公排关系记录") + _ = session.Rollback() + } + params.Uid = -1 + updateAffected, err := db.UserPublicPlatoonRelationUpdate(session, params.Id, params) + if err != nil { + _ = session.Rollback() + return + } + if updateAffected == 0 { + err = errors.New("更新 user_public_platoon_relation 记录失败") + _ = session.Rollback() + return + } + + //3、新增一条 `user_public_platoon_relation` 记录 + res, err := smallPublicPlatoon(engine, params.Uid, params.RecommendUid, *userPublicPlatoonSetting) + if err != nil { + _ = session.Rollback() + return + } + + //4、新增一条 `user_public_platoon_system_punish_records` 记录 + now := time.Now() + insertAffected, err := db.UserPublicPlatoonSystemPunishRecordsInsert(session, &model.UserPublicPlatoonSystemPunishRecords{ + Uid: params.Uid, + OldPostion: params.Position, + NewPostion: res.Position, + Date: now.AddDate(0, 0, 30).Format("2006-01-02"), + Title: "共富收益-系统处罚记录", + Reason: reason, + CreateAt: now, + UpdateAt: now, + }) + if err != nil { + _ = session.Rollback() + return + } + if insertAffected == 0 { + err = errors.New("新增 user_public_platoon_system_punish_records 记录失败") + _ = session.Rollback() + return + } + + err = session.Commit() + return +} diff --git a/svc/small_public_platoon_relate_commission.go b/svc/small_public_platoon_relate_commission.go new file mode 100644 index 0000000..8f90fdd --- /dev/null +++ b/svc/small_public_platoon_relate_commission.go @@ -0,0 +1,128 @@ +package svc + +import ( + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db" + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/md" + 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" + "errors" + "fmt" + "strconv" + "strings" + "xorm.io/xorm" +) + +// 批量分佣 订单显示 +func BatchSmallGetPublicPlatoonRelateCommission(engine *xorm.Engine, masterId string, PublicPlatoonRelateCommissionReqList []*md.SmallPublicPlatoonRelateCommissionReq) (map[string]*md.SmallPublicPlatoonRelateCommissionResp, error) { + var resp = make(map[string]*md.SmallPublicPlatoonRelateCommissionResp) + //userPublicPlatoonSetting, err := db.UserPublicPlatoonSettingGetOneByParams(engine, map[string]interface{}{ + // "key": "is_open", + // "value": 1, + //}) + //if err != nil { + // return nil, err + //} + for _, param := range PublicPlatoonRelateCommissionReqList { + // 根据供应商 + rewardOpt, err := db.DbsPlanRewardByPvd(engine, param.Pvd) + if err != nil { + return nil, err + } + if rewardOpt == nil { + return nil, zhios_order_relate_logx.Warn("找不到方案记录") + } + if rewardOpt.State == 0 { + return nil, zhios_order_relate_logx.Warn("抽成方案未开启") + } + if rewardOpt.PlanCommissionId == 0 { + return nil, zhios_order_relate_logx.Warn("抽成方案未设置佣金方案id") + } + fmt.Println("抽成设置:", zhios_order_relate_utils.SerializeStr(rewardOpt)) + fmt.Println("commission id:", rewardOpt.PlanCommissionId) + + //TODO::计算共富收益 + commissionOpt, err := db.DbsPlanCommissionById(engine, rewardOpt.PlanCommissionId) + if err != nil || commissionOpt == nil || commissionOpt.Id == 0 { + return nil, err + } + var subsidyTmp = make(map[string]*md.LvGrade) + var tmp map[string]*md.LvGrade + if err := json.Unmarshal([]byte(commissionOpt.Data), &tmp); err != nil { + return nil, zhios_order_relate_logx.Warn(fmt.Sprintf("%s:分佣方案数据设置错误", masterId)) + } + for _, v := range tmp { + subsidyTmp[zhios_order_relate_utils.IntToStr(v.Lv)] = v + } + lvGrade := subsidyTmp[param.UserLevel] + var directPush = make(map[string]string) + var selfRateList = make(map[string]string) + var commonWealthSystem = make(map[string]string) + for _, coinId := range lvGrade.ReturnType { + selfRateList[coinId] = zhios_order_relate_utils.Float64ToStr(zhios_order_relate_utils.StrToFloat64(lvGrade.SelfRateList[coinId]) * zhios_order_relate_utils.StrToFloat64(param.PendingAmount) / 100) + commonWealthSystem[coinId] = zhios_order_relate_utils.Float64ToStr(zhios_order_relate_utils.StrToFloat64(lvGrade.CommonWealthSystem[coinId]) * zhios_order_relate_utils.StrToFloat64(param.PendingAmount) / 100) + directPush[coinId] = zhios_order_relate_utils.Float64ToStr(zhios_order_relate_utils.StrToFloat64(lvGrade.DirectPush[coinId]) * zhios_order_relate_utils.StrToFloat64(param.PendingAmount)) + } + + //TODO::本次消费产生的共富收益给到谁 + var nowBenefitUid string + userPublicPlatoonRelation, err := db.UserPublicPlatoonRelationGetOneByParams(engine, map[string]interface{}{ + "key": "uid", + "value": param.Uid, + }) + if err != nil { + return nil, err + } + if userPublicPlatoonRelation == nil { + return nil, errors.New("未查询到公排关系记录") + } + if userPublicPlatoonRelation.FatherUid == "" { + //TODO::原始创始人 + nowBenefitUid = "" + } else { + fatherPositions := strings.Split(userPublicPlatoonRelation.FatherUid, "-") + var fatherPosition string + userPublicPlatoonRelation.ReturnCommissionNum++ + + remainder1 := (userPublicPlatoonRelation.ReturnCommissionNum) % len(fatherPositions) + if remainder1 == 0 { + fatherPosition = fatherPositions[len(fatherPositions)-1] + } else { + fatherPosition = fatherPositions[remainder1-1] + } + + nowBenefitUsers, err := db.UserPublicPlatoonRelationGetOneByParams(engine, map[string]interface{}{ + "key": "position", + "value": fatherPosition, + }) + if err != nil { + return nil, err + } + if nowBenefitUsers == nil { + return nil, errors.New("未查询到父级公排关系记录") + } + nowBenefitUid = zhios_order_relate_utils.AnyToString(nowBenefitUsers.Uid) + + //TODO::更新 公排关系记录 中 `return_commission_num` + affected, err := db.UserPublicPlatoonRelationUpdate(engine.NewSession(), userPublicPlatoonRelation.Id, userPublicPlatoonRelation, "return_commission_num") + if err != nil { + return nil, err + } + if affected == 0 { + return nil, errors.New("更新公排关系记录失败") + } + } + + resp[param.Oid] = &md.SmallPublicPlatoonRelateCommissionResp{ + Uid: param.Uid, + CommonWealthBenefitUid: nowBenefitUid, + DirectPushBenefitUid: strconv.Itoa(userPublicPlatoonRelation.RecommendUid), + PendingAmount: param.PendingAmount, + Oid: param.Oid, + SelfRateList: selfRateList, + CommonWealthSystem: commonWealthSystem, + DirectPush: directPush, + } + } + return resp, nil +}