diff --git a/db/db_green_coin_double_chain.go b/db/db_green_coin_double_chain.go new file mode 100644 index 0000000..38ade81 --- /dev/null +++ b/db/db_green_coin_double_chain.go @@ -0,0 +1,157 @@ +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" +) + +// BatchSelectGreenCoinDoubleChains 批量查询数据 TODO::和下面的方法重复了,建议采用下面的 `GreenCoinDoubleChainFindByParams` 方法 +func BatchSelectGreenCoinDoubleChains(Db *xorm.Engine, params map[string]interface{}) (*[]model.GreenCoinDoubleChain, error) { + var GreenCoinDoubleChainData []model.GreenCoinDoubleChain + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]). + Find(&GreenCoinDoubleChainData); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &GreenCoinDoubleChainData, nil +} + +// GreenCoinDoubleChainInsert 插入单条数据 +func GreenCoinDoubleChainInsert(Db *xorm.Engine, GreenCoinDoubleChain *model.GreenCoinDoubleChain) (int, error) { + _, err := Db.InsertOne(GreenCoinDoubleChain) + if err != nil { + return 0, err + } + return GreenCoinDoubleChain.Id, nil +} + +// BatchAddGreenCoinDoubleChains 批量新增数据 +func BatchAddGreenCoinDoubleChains(Db *xorm.Engine, GreenCoinDoubleChainData []*model.GreenCoinDoubleChain) (int64, error) { + affected, err := Db.Insert(GreenCoinDoubleChainData) + if err != nil { + return 0, err + } + return affected, nil +} + +func GetGreenCoinDoubleChainCount(Db *xorm.Engine) int { + var GreenCoinDoubleChain model.GreenCoinDoubleChain + session := Db.Where("") + count, err := session.Count(&GreenCoinDoubleChain) + if err != nil { + return 0 + } + return int(count) +} + +// GreenCoinDoubleChainDelete 删除记录 +func GreenCoinDoubleChainDelete(Db *xorm.Engine, id interface{}) (int64, error) { + if reflect.TypeOf(id).Kind() == reflect.Slice { + return Db.In("id", id).Delete(model.GreenCoinDoubleChain{}) + } else { + return Db.Where("id = ?", id).Delete(model.GreenCoinDoubleChain{}) + } +} + +// GreenCoinDoubleChainUpdate 更新记录 +func GreenCoinDoubleChainUpdate(session *xorm.Session, id interface{}, GreenCoinDoubleChain *model.GreenCoinDoubleChain, forceColums ...string) (int64, error) { + var ( + affected int64 + err error + ) + if forceColums != nil { + affected, err = session.Where("id=?", id).Cols(forceColums...).Update(GreenCoinDoubleChain) + } else { + affected, err = session.Where("id=?", id).Update(GreenCoinDoubleChain) + } + if err != nil { + return 0, err + } + return affected, nil +} + +// GreenCoinDoubleChainGetOneByParams 通过传入的参数查询数据(单条) +func GreenCoinDoubleChainGetOneByParams(session *xorm.Session, params map[string]interface{}) (*model.GreenCoinDoubleChain, error) { + var m model.GreenCoinDoubleChain + var query = fmt.Sprintf("%s =?", params["key"]) + has, err := session.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 +} + +// GreenCoinDoubleChainFindByParams 通过传入的参数查询数据(多条) +func GreenCoinDoubleChainFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.GreenCoinDoubleChain, error) { + var m []model.GreenCoinDoubleChain + 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 GreenCoinDoubleChainFindByParamsByPage(Db *xorm.Engine, params map[string]interface{}, page, pageSize int) (*[]model.GreenCoinDoubleChain, error) { + var m []model.GreenCoinDoubleChain + 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/db_green_coin_double_chain_exchange_records.go b/db/db_green_coin_double_chain_exchange_records.go new file mode 100644 index 0000000..d7fd20d --- /dev/null +++ b/db/db_green_coin_double_chain_exchange_records.go @@ -0,0 +1,157 @@ +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" +) + +// BatchSelectGreenCoinDoubleChainExchangeRecords 批量查询数据 TODO::和下面的方法重复了,建议采用下面的 `GreenCoinDoubleChainExchangeRecordsFindByParams` 方法 +func BatchSelectGreenCoinDoubleChainExchangeRecords(Db *xorm.Engine, params map[string]interface{}) (*[]model.GreenCoinDoubleChainExchangeRecords, error) { + var GreenCoinDoubleChainExchangeRecordsData []model.GreenCoinDoubleChainExchangeRecords + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]). + Find(&GreenCoinDoubleChainExchangeRecordsData); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &GreenCoinDoubleChainExchangeRecordsData, nil +} + +// GreenCoinDoubleChainExchangeRecordsInsert 插入单条数据 +func GreenCoinDoubleChainExchangeRecordsInsert(Db *xorm.Engine, GreenCoinDoubleChainExchangeRecords *model.GreenCoinDoubleChainExchangeRecords) (int64, error) { + _, err := Db.InsertOne(GreenCoinDoubleChainExchangeRecords) + if err != nil { + return 0, err + } + return GreenCoinDoubleChainExchangeRecords.Id, nil +} + +// BatchAddGreenCoinDoubleChainExchangeRecordss 批量新增数据 +func BatchAddGreenCoinDoubleChainExchangeRecordss(Db *xorm.Engine, GreenCoinDoubleChainExchangeRecordsData []*model.GreenCoinDoubleChainExchangeRecords) (int64, error) { + affected, err := Db.Insert(GreenCoinDoubleChainExchangeRecordsData) + if err != nil { + return 0, err + } + return affected, nil +} + +func GetGreenCoinDoubleChainExchangeRecordsCount(Db *xorm.Engine) int { + var GreenCoinDoubleChainExchangeRecords model.GreenCoinDoubleChainExchangeRecords + session := Db.Where("") + count, err := session.Count(&GreenCoinDoubleChainExchangeRecords) + if err != nil { + return 0 + } + return int(count) +} + +// GreenCoinDoubleChainExchangeRecordsDelete 删除记录 +func GreenCoinDoubleChainExchangeRecordsDelete(Db *xorm.Engine, id interface{}) (int64, error) { + if reflect.TypeOf(id).Kind() == reflect.Slice { + return Db.In("id", id).Delete(model.GreenCoinDoubleChainExchangeRecords{}) + } else { + return Db.Where("id = ?", id).Delete(model.GreenCoinDoubleChainExchangeRecords{}) + } +} + +// GreenCoinDoubleChainExchangeRecordsUpdate 更新记录 +func GreenCoinDoubleChainExchangeRecordsUpdate(session *xorm.Session, id interface{}, GreenCoinDoubleChainExchangeRecords *model.GreenCoinDoubleChainExchangeRecords, forceColums ...string) (int64, error) { + var ( + affected int64 + err error + ) + if forceColums != nil { + affected, err = session.Where("id=?", id).Cols(forceColums...).Update(GreenCoinDoubleChainExchangeRecords) + } else { + affected, err = session.Where("id=?", id).Update(GreenCoinDoubleChainExchangeRecords) + } + if err != nil { + return 0, err + } + return affected, nil +} + +// GreenCoinDoubleChainExchangeRecordsGetOneByParams 通过传入的参数查询数据(单条) +func GreenCoinDoubleChainExchangeRecordsGetOneByParams(session *xorm.Session, params map[string]interface{}) (*model.GreenCoinDoubleChainExchangeRecords, error) { + var m model.GreenCoinDoubleChainExchangeRecords + var query = fmt.Sprintf("%s =?", params["key"]) + has, err := session.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 +} + +// GreenCoinDoubleChainExchangeRecordsFindByParams 通过传入的参数查询数据(多条) +func GreenCoinDoubleChainExchangeRecordsFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.GreenCoinDoubleChainExchangeRecords, error) { + var m []model.GreenCoinDoubleChainExchangeRecords + 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 GreenCoinDoubleChainExchangeRecordsFindByParamsByPage(Db *xorm.Engine, params map[string]interface{}, page, pageSize int) (*[]model.GreenCoinDoubleChainExchangeRecords, error) { + var m []model.GreenCoinDoubleChainExchangeRecords + 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/dbs_user.go b/db/dbs_user.go index 2cdac26..440f088 100644 --- a/db/dbs_user.go +++ b/db/dbs_user.go @@ -32,6 +32,15 @@ func DbsUserRelate(eg *xorm.Engine, uid, level int) (*[]model.UserRelate, error) return &userRelate, nil } +func GetUserParentUserRelate(eg *xorm.Engine, uid int) (*model.UserRelate, error) { + var data model.UserRelate + get, err := eg.Where("level=1 and uid =?", uid).Get(&data) + if get == false || err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &data, nil +} + func DbsUserRelateByParentUid(eg *xorm.Engine, uid, level int) (*[]model.UserRelate, error) { var userRelate []model.UserRelate sess := eg.Where("parent_uid = ?", uid) diff --git a/db/model/green_coin_double_chain.go b/db/model/green_coin_double_chain.go new file mode 100644 index 0000000..8688a9b --- /dev/null +++ b/db/model/green_coin_double_chain.go @@ -0,0 +1,12 @@ +package model + +type GreenCoinDoubleChain struct { + Id int `json:"id" xorm:"not null pk autoincr comment('主键id') INT(11)"` + IsUse int `json:"is_use" xorm:"not null default 0 comment('是否开启(否:0;是:1)') TINYINT(1)"` + Coin1 int `json:"coin_1" xorm:"not null default 0 comment('coinId_1(作用于绿色积分)') INT(11)"` + Coin2 int `json:"coin_2" xorm:"not null default 0 comment('coinId_2(作用于贡献积分)') INT(11)"` + ExchangeRatio1 int `json:"exchange_ratio_1" xorm:"not null default 0 comment('兑换比例(扣除绿色积分)') INT(11)"` + ExchangeRatio2 int `json:"exchange_ratio_2" xorm:"not null default 0 comment('兑换比例(扣除贡献积分)') INT(11)"` + CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' comment('创建时间') TIMESTAMP"` + UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' comment('更新时间') TIMESTAMP"` +} diff --git a/db/model/green_coin_double_chain_exchange_records.go b/db/model/green_coin_double_chain_exchange_records.go new file mode 100644 index 0000000..7d64ee8 --- /dev/null +++ b/db/model/green_coin_double_chain_exchange_records.go @@ -0,0 +1,19 @@ +package model + +type GreenCoinDoubleChainExchangeRecords struct { + Id int64 `json:"id" xorm:"pk autoincr BIGINT(20)"` + Uid int `json:"uid" xorm:"not null default 0 comment('兑换用户id') INT(11)"` + ContributeUid1 int `json:"contribute_uid_1" xorm:"not null default 0 comment('第1个贡献用户id') INT(11)"` + ContributeUid2 int `json:"contribute_uid_2" xorm:"not null default 0 comment('第2个贡献用户id') INT(11)"` + CoinId1 int `json:"coin_id_1" xorm:"not null default 0 comment('coinId_1(作用于绿色积分)') INT(11)"` + CoinId2 int `json:"coin_id_2" xorm:"not null default 0 comment('coinId_2(作用于贡献积分)') INT(11)"` + Amount string `json:"amount" xorm:"not null default 0.00 comment('兑换金额') DECIMAL(8,2)"` + BeforeUserCoinAmount string `json:"before_user_coin_amount" xorm:"not null default 0.00 comment('用户兑换前金额') DECIMAL(8,2)"` + AfterUserCoinAmount string `json:"after_user_coin_amount" xorm:"not null default 0.00 comment('用户兑换后金额') DECIMAL(8,2)"` + BeforeCoinAmountContributeUser1 string `json:"before_coin_amount_contribute_user_1" xorm:"not null default 0.00 comment('第1个贡献用户兑换前金额') DECIMAL(8,2)"` + AfterCoinAmountContributeUser1 string `json:"after_coin_amount_contribute_user_1" xorm:"not null default 0.00 comment('第1个贡献用户兑换后金额') DECIMAL(8,2)"` + BeforeCoinAmountContributeUser2 string `json:"before_coin_amount_contribute_user_2" xorm:"not null default 0.00 comment('第2个贡献用户兑换前金额') DECIMAL(8,2)"` + AfterCoinAmountContributeUser2 string `json:"after_coin_amount_contribute_user_2" xorm:"not null default 0.00 comment('第2个贡献用户兑换后金额') DECIMAL(8,2)"` + CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' comment('创建时间') DATETIME"` + UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' comment('更新时间') DATETIME"` +} diff --git a/enum/fin_user_flow.go b/enum/fin_user_flow.go index e69dfb4..610c8dc 100644 --- a/enum/fin_user_flow.go +++ b/enum/fin_user_flow.go @@ -14,6 +14,8 @@ func FinUserFlowOrderActionString(kind int) string { return "green_energy_exchange_for_balance" case md.BalanceExchangeForGreenEnergyForFinUserFlow: return "balance_exchange_for_green_energy" + case md.GreenCoinDoubleChainExchangeForBalanceForFinUserFlow: + return "green_coin_double_chain_exchange_for_balance" default: return "unknown" } diff --git a/md/block_star_chain.go b/md/block_star_chain.go index a4e2563..b0fe91b 100644 --- a/md/block_star_chain.go +++ b/md/block_star_chain.go @@ -74,6 +74,9 @@ const ( OneCirclesTeamActiveCoinExchangeToBeGreenEnergy = "T兑换绿色能量" OneCirclesSettlementGreenEnergyExchangeTobeGreenEnergy = "绿色能量释放" OneCirclesSettlementStarLevelDividends = "绿色能量分红" + + GreenCoinDoubleChainExchangeByCoin1 = "绿色积分双链兑换账户余额-减少绿色积分" + GreenCoinDoubleChainExchangeByCoin2 = "绿色积分双链兑换账户余额-减少贡献积分" ) const ( @@ -145,11 +148,14 @@ const ( OneCirclesPersonalActiveCoinExchangeToBeGreenEnergyForUserVirtualCoinFlow = 165 //B兑换绿色能量 OneCirclesTeamActiveCoinExchangeToBeGreenEnergyForUserVirtualCoinFlow = 166 //T兑换绿色能量 OneCirclesSettlementGreenEnergyExchangeTobeGreenEnergyForUserVirtualCoinFlow = 167 //绿色能量释放 - OneCirclesSettlementStarLevelDividendsForUserVirtualCoinFlow = 168 //结算星级冯弘-得到结算绿色能量 + OneCirclesSettlementStarLevelDividendsForUserVirtualCoinFlow = 168 //结算星级分红-得到结算绿色能量 + + GreenCoinDoubleChainExchangeByCoin1ForForUserVirtualCoinFlow = 169 //绿色积分双链兑换账户余额-减少绿色积分 + GreenCoinDoubleChainExchangeByCoin2ForForUserVirtualCoinFlow = 170 //绿色积分双链兑换账户余额-减少贡献积分 ) -const DealUserCoinRequestIdPrefix = "%s:block_star_chain_deal_user_coin:%d:uid:%d" +const DealUserCoinRequestIdPrefix = "%s:deal_user_coin:%d:uid:%d" const DealUserCoinForGreenRequestIdPrefix = "%s:block_star_chain_deal_user_coin_for_green:%d:uid:%d" const DealConsumeIntegralRequestIdPrefix = "consume_integral:%s:uid:%d" diff --git a/md/fin_user_flow.go b/md/fin_user_flow.go index 932460b..34d7e2f 100644 --- a/md/fin_user_flow.go +++ b/md/fin_user_flow.go @@ -11,12 +11,13 @@ const ( ) const ( - IntegralReleaseServiceRevenueTitleForFinUserFlow = "积分释放-服务收益" - IntegralReleaseServiceRevenueRefundTitleForFinUserFlow = "订单退款-服务收益扣除" - ConsumeSubsidyTitleForFinUserFlow = "消费补贴-收益" - ExperienceSubsidyTitleForFinUserFlow = "体验补贴-收益" - GreenEnergyExchangeForBalanceTitleForFinUserFlow = "兑换账户余额" - BalanceExchangeForGreenEnergyTitleForFinUserFlow = "账户余额兑换" + IntegralReleaseServiceRevenueTitleForFinUserFlow = "积分释放-服务收益" + IntegralReleaseServiceRevenueRefundTitleForFinUserFlow = "订单退款-服务收益扣除" + ConsumeSubsidyTitleForFinUserFlow = "消费补贴-收益" + ExperienceSubsidyTitleForFinUserFlow = "体验补贴-收益" + GreenEnergyExchangeForBalanceTitleForFinUserFlow = "兑换账户余额" + BalanceExchangeForGreenEnergyTitleForFinUserFlow = "账户余额兑换" + GreenCoinDoubleChainExchangeForBalanceTitleForFinUserFlow = "绿色积分双链兑换账户余额" ) const ( @@ -26,6 +27,7 @@ const ( ExperienceSubsidyOrdActionForFinUserFlow = 111 // 体验补贴-收益 GreenEnergyExchangeForBalanceForFinUserFlow = 112 // 兑换账户余额 BalanceExchangeForGreenEnergyForFinUserFlow = 113 // 账户余额兑换 + GreenCoinDoubleChainExchangeForBalanceForFinUserFlow = 114 // 绿色积分双链兑换账户余额 ) const DealUserAmountRequestIdPrefix = "%s:deal_user_amount:%d" diff --git a/rule/block_star_chain_settlement.go b/rule/block_star_chain_settlement.go index 179b009..04bdd61 100644 --- a/rule/block_star_chain_settlement.go +++ b/rule/block_star_chain_settlement.go @@ -13,7 +13,6 @@ import ( "errors" "fmt" "github.com/shopspring/decimal" - "strconv" "time" "xorm.io/xorm" ) @@ -821,82 +820,6 @@ func DealDestroyCoin(session *xorm.Session, kind int, amount float64, title stri return nil } -// DealUserCoin 处理给用户虚拟币积分 -func DealUserCoin(session *xorm.Session, req md.DealUserCoinReq) (err error) { - if req.Amount < 0 { - req.Amount = 0 - } - //1、分布式锁阻拦 - requestIdPrefix := fmt.Sprintf(md.DealUserCoinRequestIdPrefix, req.Mid, req.CoinId, req.Uid) - cb, err := svc.HandleDistributedLock(req.Mid, strconv.Itoa(req.Uid), requestIdPrefix) - if err != nil { - return err - } - if cb != nil { - defer cb() // 释放锁 - } - - //2、计算&&组装数据 - now := time.Now() - coinAmount, err := svc.GetUserCoinAmount(session, req.Mid, req.CoinId, req.Uid) - if err != nil { - return err - } - coinAmountValue := decimal.NewFromFloat(zhios_order_relate_utils.StrToFloat64(coinAmount)) - amountValue := decimal.NewFromFloat(req.Amount).RoundFloor(4) - - var userVirtualCoinFlow model.UserVirtualCoinFlow - userVirtualCoinFlow.CoinId = req.CoinId - userVirtualCoinFlow.Title = req.Title - userVirtualCoinFlow.TransferType = req.TransferType - userVirtualCoinFlow.Uid = req.Uid - userVirtualCoinFlow.ToUid = req.ToUid - userVirtualCoinFlow.OrdId = req.OrdId - userVirtualCoinFlow.BeforeAmout = coinAmount - userVirtualCoinFlow.Amout = amountValue.String() - userVirtualCoinFlow.CreateTime = now - - if req.Kind == "add" { - userVirtualCoinFlow.Direction = 1 - userVirtualCoinFlow.AfterAmout = coinAmountValue.Add(amountValue).RoundFloor(4).String() - } else if req.Kind == "sub" { - userVirtualCoinFlow.Direction = 2 - userVirtualCoinFlow.AfterAmout = coinAmountValue.Sub(amountValue).RoundFloor(4).String() - } else { - err = errors.New("错误的kind类型") - return err - } - if zhios_order_relate_utils.StrToFloat64(userVirtualCoinFlow.AfterAmout) < 0 { - var coin model.VirtualCoin - _, err = session.Where("id = ?", req.CoinId).Get(&coin) - if err != nil { - return err - } - zhios_order_relate_utils.FilePutContents("virtual_coin_not", zhios_order_relate_utils.SerializeStr(map[string]interface{}{ - "uid": userVirtualCoinFlow.Uid, - "amount": userVirtualCoinFlow.Amout, - "before_amount": userVirtualCoinFlow.BeforeAmout, - "after_amount": userVirtualCoinFlow.AfterAmout, - "coin_id": userVirtualCoinFlow.CoinId, - })) - return errors.New("用户" + zhios_order_relate_utils.IntToStr(userVirtualCoinFlow.Uid) + "的" + coin.Name + "不足") - //userVirtualCoinFlow.AfterAmout = "0" - } - //3、插入 `user_virtual_coin_flow` 记录 - _, err = db.UserVirtualCoinFlowInsert(session, &userVirtualCoinFlow) - if err != nil { - return err - } - - //4、修改 `user_virtual_amount`的amount值 && 及缓存 - err = svc.SetCacheUserVirtualAmount(session, req.Mid, userVirtualCoinFlow.AfterAmout, req.CoinId, req.Uid, true) - if err != nil { - return err - } - - return nil -} - // DealLotteryDraw 处理抽奖 func DealLotteryDraw(session *xorm.Session, req md.DealLotteryDrawReq) (err error) { defer func() { diff --git a/rule/green_coin_double_chain_settlement.go b/rule/green_coin_double_chain_settlement.go new file mode 100644 index 0000000..afd4a7c --- /dev/null +++ b/rule/green_coin_double_chain_settlement.go @@ -0,0 +1,211 @@ +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/enum" + "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" + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/cache" + zhios_order_relate_logx "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/logx" + "errors" + "github.com/shopspring/decimal" + "time" + "xorm.io/xorm" +) + +func InitForGreenCoinDoubleChainIntegral(redisAddr string) (err error) { + if redisAddr != "" { + cache.NewRedis(redisAddr) + } + _, err = cache.SelectDb(md.RedisDataBase) + return +} + +func DealUserGreenCoinDoubleChainIntegral(Db *xorm.Engine, uid int, amount, ordId, masterId string) (isExchange bool, err error) { + amountValue, _ := decimal.NewFromString(amount) + session := Db.NewSession() + defer func() { + session.Close() + if err := recover(); err != nil { + _ = zhios_order_relate_logx.Error(err) + } + }() + session.Begin() + //1、查找 `green_coin_double_chain` 基础设置 + greenCoinDoubleChain, err := db.GreenCoinDoubleChainGetOneByParams(session, map[string]interface{}{ + "key": "is_use", + "value": 1, + }) + if err != nil { + return + } + + //2、查找对应直推上级用户 + parentUserRelate, err := db.GetUserParentUserRelate(Db, uid) + if err != nil { + return + } + if parentUserRelate == nil { + err = errors.New("未查询到直推上级") + return + } + + //3、查询用户和对应上级的虚拟币余额 + userAmount, err := svc.GetUserCoinAmount(session, masterId, greenCoinDoubleChain.Coin2, uid) + if err != nil { + return + } + parentAmount, err := svc.GetUserCoinAmount(session, masterId, greenCoinDoubleChain.Coin1, parentUserRelate.ParentUid) + if err != nil { + return + } + userAmountValue, _ := decimal.NewFromString(userAmount) + parentAmountValue, _ := decimal.NewFromString(parentAmount) + if parentAmountValue.LessThan(amountValue) { + //TODO::上级绿色积分小于当前需要兑换积分金额 + return + } + if userAmountValue.LessThan(amountValue) { + err = errors.New("当前用户金额有误,不足以进行兑换") + return + } + + //4、查询上级直推的所有下级用户 + sonUserRelates, err := db.DbsUserRelateByParentUid(Db, parentUserRelate.ParentUid, 1) + if err != nil { + return + } + if sonUserRelates == nil { + err = errors.New("未查询到直推下级") + return + } + var sonUserIds []int + for _, v := range *sonUserRelates { + sonUserIds = append(sonUserIds, v.Uid) + } + + //5、查询上级直推的所有下级用户的虚拟币金额是否有大于当前用户的 + var sonUserVirtualWallet model.UserVirtualAmount + isHas, err := session.Where(" coin_id = ? and amount >=", greenCoinDoubleChain.Coin2, amount).In("uid", sonUserIds).Get(&sonUserVirtualWallet) + if err != nil { + return + } + if isHas == false { + //TODO::没有符合匹配的下级用户 + return + } + + /* + TODO::6、进行“数据变更” + */ + //6.1、上级减少amount 绿色积分 + err = DealUserCoin(session, md.DealUserCoinReq{ + Kind: "sub", + Mid: masterId, + Title: md.GreenCoinDoubleChainExchangeByCoin1, + TransferType: md.GreenCoinDoubleChainExchangeByCoin1ForForUserVirtualCoinFlow, + OrdId: ordId, + CoinId: greenCoinDoubleChain.Coin1, + Uid: parentUserRelate.ParentUid, + Amount: zhios_order_relate_utils.StrToFloat64(amount), + }) + if err != nil { + session.Rollback() + return + } + //6.2、用户减少amount 贡献积分 + err = DealUserCoin(session, md.DealUserCoinReq{ + Kind: "sub", + Mid: masterId, + Title: md.GreenCoinDoubleChainExchangeByCoin2, + TransferType: md.GreenCoinDoubleChainExchangeByCoin2ForForUserVirtualCoinFlow, + OrdId: ordId, + CoinId: greenCoinDoubleChain.Coin2, + Uid: uid, + Amount: zhios_order_relate_utils.StrToFloat64(amount), + }) + //6.3、另一下级减少amount 贡献积分 + err = DealUserCoin(session, md.DealUserCoinReq{ + Kind: "sub", + Mid: masterId, + Title: md.GreenCoinDoubleChainExchangeByCoin2, + TransferType: md.GreenCoinDoubleChainExchangeByCoin2ForForUserVirtualCoinFlow, + OrdId: ordId, + CoinId: greenCoinDoubleChain.Coin2, + Uid: sonUserVirtualWallet.Uid, + Amount: zhios_order_relate_utils.StrToFloat64(amount), + }) + if err != nil { + session.Rollback() + return + } + //6.4上级余额增加 amount + var coin model.VirtualCoin + _, err = session.Where("id = ?", greenCoinDoubleChain.Coin1).Get(&coin) + if err != nil { + session.Rollback() + return + } + coinExchangeRatioValue, _ := decimal.NewFromString(coin.ExchangeRatio) + exchangeAmount, _ := amountValue.Div(coinExchangeRatioValue).Float64() + orderType := enum.FinUserFlowOrderActionString(md.GreenCoinDoubleChainExchangeForBalanceForFinUserFlow) + err = svc.DealUserAmount(session, md.DealUserAmount{ + Kind: "add", + Mid: masterId, + Title: md.GreenCoinDoubleChainExchangeForBalanceTitleForFinUserFlow, + OrderType: orderType, + OrdAction: md.GreenCoinDoubleChainExchangeForBalanceForFinUserFlow, + OrdId: ordId, + Uid: parentUserRelate.ParentUid, + Amount: exchangeAmount, + Num: "", + }) + if err != nil { + session.Rollback() + return + } + + //7、新增 green_coin_double_chain_exchange_records 记录 + afterUserCoinAmount, err := svc.GetUserCoinAmount(session, masterId, greenCoinDoubleChain.Coin1, parentUserRelate.ParentUid) + if err != nil { + session.Rollback() + return + } + afterCoinAmountContributeUser1, err := svc.GetUserCoinAmount(session, masterId, greenCoinDoubleChain.Coin2, uid) + if err != nil { + session.Rollback() + return + } + afterCoinAmountContributeUser2, err := svc.GetUserCoinAmount(session, masterId, greenCoinDoubleChain.Coin2, sonUserVirtualWallet.Uid) + if err != nil { + session.Rollback() + return + } + now := time.Now() + _, err = db.GreenCoinDoubleChainExchangeRecordsInsert(Db, &model.GreenCoinDoubleChainExchangeRecords{ + Uid: parentUserRelate.ParentUid, + ContributeUid1: uid, + ContributeUid2: sonUserVirtualWallet.Uid, + CoinId1: greenCoinDoubleChain.Coin1, + CoinId2: greenCoinDoubleChain.Coin2, + Amount: amount, + BeforeUserCoinAmount: parentAmount, + AfterUserCoinAmount: afterUserCoinAmount, + BeforeCoinAmountContributeUser1: userAmount, + AfterCoinAmountContributeUser1: afterCoinAmountContributeUser1, + BeforeCoinAmountContributeUser2: sonUserVirtualWallet.Amount, + AfterCoinAmountContributeUser2: afterCoinAmountContributeUser2, + CreateAt: now.Format("2006-01-02 15:04:05"), + UpdateAt: now.Format("2006-01-02 15:04:05"), + }) + if err != nil { + session.Rollback() + return + } + + session.Commit() + isExchange = true + return +} diff --git a/rule/user_amount.go b/rule/user_amount.go new file mode 100644 index 0000000..16e6615 --- /dev/null +++ b/rule/user_amount.go @@ -0,0 +1,91 @@ +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" + "errors" + "fmt" + "github.com/shopspring/decimal" + "strconv" + "time" + "xorm.io/xorm" +) + +// DealUserCoin 处理给用户虚拟币积分 +func DealUserCoin(session *xorm.Session, req md.DealUserCoinReq) (err error) { + if req.Amount < 0 { + req.Amount = 0 + } + //1、分布式锁阻拦 + requestIdPrefix := fmt.Sprintf(md.DealUserCoinRequestIdPrefix, req.Mid, req.CoinId, req.Uid) + cb, err := svc.HandleDistributedLock(req.Mid, strconv.Itoa(req.Uid), requestIdPrefix) + if err != nil { + return err + } + if cb != nil { + defer cb() // 释放锁 + } + + //2、计算&&组装数据 + now := time.Now() + coinAmount, err := svc.GetUserCoinAmount(session, req.Mid, req.CoinId, req.Uid) + if err != nil { + return err + } + coinAmountValue := decimal.NewFromFloat(zhios_order_relate_utils.StrToFloat64(coinAmount)) + amountValue := decimal.NewFromFloat(req.Amount).RoundFloor(4) + + var userVirtualCoinFlow model.UserVirtualCoinFlow + userVirtualCoinFlow.CoinId = req.CoinId + userVirtualCoinFlow.Title = req.Title + userVirtualCoinFlow.TransferType = req.TransferType + userVirtualCoinFlow.Uid = req.Uid + userVirtualCoinFlow.ToUid = req.ToUid + userVirtualCoinFlow.OrdId = req.OrdId + userVirtualCoinFlow.BeforeAmout = coinAmount + userVirtualCoinFlow.Amout = amountValue.String() + userVirtualCoinFlow.CreateTime = now + + if req.Kind == "add" { + userVirtualCoinFlow.Direction = 1 + userVirtualCoinFlow.AfterAmout = coinAmountValue.Add(amountValue).RoundFloor(4).String() + } else if req.Kind == "sub" { + userVirtualCoinFlow.Direction = 2 + userVirtualCoinFlow.AfterAmout = coinAmountValue.Sub(amountValue).RoundFloor(4).String() + } else { + err = errors.New("错误的kind类型") + return err + } + if zhios_order_relate_utils.StrToFloat64(userVirtualCoinFlow.AfterAmout) < 0 { + var coin model.VirtualCoin + _, err = session.Where("id = ?", req.CoinId).Get(&coin) + if err != nil { + return err + } + zhios_order_relate_utils.FilePutContents("virtual_coin_not", zhios_order_relate_utils.SerializeStr(map[string]interface{}{ + "uid": userVirtualCoinFlow.Uid, + "amount": userVirtualCoinFlow.Amout, + "before_amount": userVirtualCoinFlow.BeforeAmout, + "after_amount": userVirtualCoinFlow.AfterAmout, + "coin_id": userVirtualCoinFlow.CoinId, + })) + return errors.New("用户" + zhios_order_relate_utils.IntToStr(userVirtualCoinFlow.Uid) + "的" + coin.Name + "不足") + //userVirtualCoinFlow.AfterAmout = "0" + } + //3、插入 `user_virtual_coin_flow` 记录 + _, err = db.UserVirtualCoinFlowInsert(session, &userVirtualCoinFlow) + if err != nil { + return err + } + + //4、修改 `user_virtual_amount`的amount值 && 及缓存 + err = svc.SetCacheUserVirtualAmount(session, req.Mid, userVirtualCoinFlow.AfterAmout, req.CoinId, req.Uid, true) + if err != nil { + return err + } + + return nil +}