diff --git a/app/db/db_appreciation_base.go b/app/db/db_appreciation_base.go new file mode 100644 index 0000000..479ee09 --- /dev/null +++ b/app/db/db_appreciation_base.go @@ -0,0 +1,23 @@ +package db + +import ( + "applet/app/db/model" + "xorm.io/xorm" +) + +func GetAppreciationBase(sess *xorm.Session) *model.AppreciationBase { + var data model.AppreciationBase + get, err := sess.Where("is_use=1").Get(&data) + if get == false || err != nil { + return nil + } + return &data +} +func GetAppreciationBaseEg(eg *xorm.Engine) *model.AppreciationBase { + var data model.AppreciationBase + get, err := eg.Where("is_use=1").Get(&data) + if get == false || err != nil { + return nil + } + return &data +} diff --git a/app/db/db_appreciation_day_list.go b/app/db/db_appreciation_day_list.go new file mode 100644 index 0000000..170caed --- /dev/null +++ b/app/db/db_appreciation_day_list.go @@ -0,0 +1,29 @@ +package db + +import ( + "applet/app/db/model" + "applet/app/utils" + "xorm.io/xorm" +) + +func DayList(eg *xorm.Engine, today int64) map[string]string { + var chartList = make([]model.AppreciationDayList, 0) + var chartDateMap = make(map[string]string) + err := eg.Where("time>=?", today-6*86400).Find(&chartList) + if err != nil { + return chartDateMap + } + for _, v := range chartList { + chartDateMap[v.Date] = v.Value + } + return chartDateMap +} + +func DayListByToday(eg *xorm.Engine) bool { + timeRange := utils.GetTimeRange("today") + count, _ := eg.Where("time>=?", timeRange).Count(&model.AppreciationDayList{}) + if count > 0 { + return true + } + return false +} diff --git a/app/db/db_user_virtual_coin_flow.go b/app/db/db_user_virtual_coin_flow.go new file mode 100644 index 0000000..e42fcdf --- /dev/null +++ b/app/db/db_user_virtual_coin_flow.go @@ -0,0 +1,106 @@ +package db + +import ( + "applet/app/db/model" + "applet/app/utils" + "applet/app/utils/logx" + "xorm.io/xorm" +) + +func GetUserVirtualAmountFlow(eg *xorm.Engine, args map[string]string) *[]model.UserVirtualCoinFlow { + var data []model.UserVirtualCoinFlow + sess := eg.Where("uid=?", args["uid"]) + if args["date"] != "" { + sess.And("date=?", args["date"]) + } + if args["coin_id"] != "" { + sess.And("coin_id=?", args["coin_id"]) + } + if args["type"] != "" { + sess.And("transfer_type=?", args["type"]) + } + err := sess.Limit(utils.StrToInt(args["p"]), (utils.StrToInt(args["p"])-1)*utils.StrToInt(args["size"])).OrderBy("id desc").Find(&data) + if err != nil { + return nil + } + return &data +} + +func UserVirtualAmountFindByIdWithSession(session *xorm.Session, uid, coinId int) (*model.UserVirtualAmount, error) { + var m model.UserVirtualAmount + has, err := session.Where("uid = ? AND coin_id = ?", uid, coinId).Get(&m) + if err != nil { + return nil, logx.Warn(err) + } + if has == false { + m.Amount = "0" + m.CoinId = coinId + m.Uid = uid + one, err := session.InsertOne(&m) + if err != nil || one == 0 { + return nil, logx.Warn(err) + } + } + return &m, nil +} + +func UserVirtualAmountFindById(eg *xorm.Engine, uid, coinId int) (*model.UserVirtualAmount, error) { + var m model.UserVirtualAmount + has, err := eg.Where("uid = ? AND coin_id = ?", uid, coinId).Get(&m) + if err != nil { + return nil, logx.Warn(err) + } + if has == false { + m.Amount = "0" + m.CoinId = coinId + m.Uid = uid + one, err := eg.InsertOne(&m) + if err != nil || one == 0 { + return nil, logx.Warn(err) + } + } + return &m, nil +} + +// 在事务中更新用户信息 +func UserVirtualAmountUpdateWithSession(session *xorm.Session, uid, coinId interface{}, userVirtualAmount *model.UserVirtualAmount, forceCols ...string) (int64, error) { + var ( + affected int64 + err error + ) + if forceCols != nil { + affected, err = session.Where("uid = ? AND coin_id = ?", uid, coinId).Cols(forceCols...).Update(userVirtualAmount) + } else { + affected, err = session.Where("uid = ? AND coin_id = ?", uid, coinId).Update(userVirtualAmount) + } + if err != nil { + return 0, logx.Warn(err) + } + return affected, nil +} + +// 在事务中更新用户信息 +func UserVirtualFlowUpdate(eg *xorm.Engine, id int, userVirtualCoinFlow *model.UserVirtualCoinFlow, forceCols ...string) (int64, error) { + var ( + affected int64 + err error + ) + if forceCols != nil { + affected, err = eg.Where("id = ? ", id).Cols(forceCols...).Update(userVirtualCoinFlow) + } else { + affected, err = eg.Where("id = ? ", id).Update(userVirtualCoinFlow) + } + if err != nil { + return 0, logx.Warn(err) + } + return affected, nil +} + +// UserVirtualCoinFlowInsertOneWithSession 在事务中使用,插入一条流水记录 +func UserVirtualCoinFlowInsertOneWithSession(session *xorm.Session, m *model.UserVirtualCoinFlow) error { + _, err := session.InsertOne(m) + if err != nil { + return err + } + return nil +} diff --git a/app/db/db_virtual_coin.go b/app/db/db_virtual_coin.go new file mode 100644 index 0000000..61278b7 --- /dev/null +++ b/app/db/db_virtual_coin.go @@ -0,0 +1,146 @@ +package db + +import ( + "applet/app/db/model" + "applet/app/md" + "applet/app/utils" + "applet/app/utils/cache" + "applet/app/utils/logx" + "fmt" + "reflect" + "strings" + "xorm.io/xorm" +) + +// VirtualCoinGetOneByParams 通过参数查询数据(单条) +func VirtualCoinGetOneByParams(Db *xorm.Engine, params map[string]interface{}) (*model.VirtualCoin, error) { + var m model.VirtualCoin + var query = fmt.Sprintf("%s =?", params["key"]) + if has, err := Db.Where(query, params["value"]).Get(&m); err != nil || has == false { + return nil, logx.Error(err) + } + return &m, nil +} +func VirtualCoinGetOneByParamsSess(sess *xorm.Session, params map[string]interface{}) (*model.VirtualCoin, error) { + var m model.VirtualCoin + var query = fmt.Sprintf("%s =?", params["key"]) + if has, err := sess.Where(query, params["value"]).Get(&m); err != nil || has == false { + return nil, logx.Error(err) + } + return &m, nil +} +func VirtualCoinGetOneById(Db *xorm.Engine, id int) (*model.VirtualCoin, error) { + var m model.VirtualCoin + if has, err := Db.Where("id=?", id).Get(&m); err != nil || has == false { + return nil, logx.Error(err) + } + return &m, nil +} + +// VirtualCoinFindByParams 通过传入的参数查询数据(多条) +func VirtualCoinFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.VirtualCoin, error) { + var m []model.VirtualCoin + if params["key"] == nil { + //查询全部数据 + err := Db.Find(&m) + if err != nil { + return nil, logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(utils.AnyToString(params["key"]), params["value"]).Find(&m); err != nil { + return nil, 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, logx.Error(err) + } + return &m, nil + } + + } +} + +// VirtualCoinListInUseAndNoBlockCoin 查询正在使用中的虚拟币(排除区块币) +func VirtualCoinListInUseAndNoBlockCoin(Db *xorm.Engine, masterId string) ([]*model.VirtualCoin, error) { + var m []*model.VirtualCoin + cacheKey := fmt.Sprintf(md.VirtualCoinCfgCacheKey, masterId) + + err := cache.GetJson(cacheKey, &m) + if err != nil || len(m) == 0 { + // is_block=0 非作为区块币的才能用与返利 + err := Db.Where("is_use=1 AND is_block=0").Find(&m) + if err != nil { + return nil, err + } + cache.SetJson(cacheKey, m, md.CfgCacheTime) + } + + return m, nil +} + +// VirtualCoinListInUse 查询正在使用中的虚拟币 +func VirtualCoinListInUse(Db *xorm.Engine, masterId, isFreeze string) ([]*model.VirtualCoin, error) { + var m []*model.VirtualCoin + cacheKey := fmt.Sprintf(md.VirtualCoinCfgCacheKey, masterId) + + err := cache.GetJson(cacheKey, &m) + if err != nil || len(m) == 0 { + err := Db.Where("is_use=1").Asc("id").Find(&m) + if err != nil { + return nil, err + } + cache.SetJson(cacheKey, m, md.CfgCacheTime) + } + if masterId == "88164961" { + for k, v := range m { + if v.Id == 2 { + if strings.Contains(v.CanExchange, "{\"id\":") { + m[k].CanExchange = strings.ReplaceAll(v.CanExchange, "{\"id\":", "{\"id\":\"4\",\"name\":\"购物积分\",\"fee\":\"0\",\"coin_id\":\"4\"},{\"id\":") + } + if v.CanExchange == "[]" { + m[k].CanExchange = "[{\"id\":\"4\",\"name\":\"购物积分\",\"fee\":\"0\",\"coin_id\":\"4\"}]" + } + } + } + if isFreeze == "1" { + var tmp = &model.VirtualCoin{ + Id: 4, Name: "购物积分", IsUse: 1, ExchangeRatio: "1", + } + m = append(m, tmp) + } + + } + + return m, nil +} + +func VirtualCoinMapInUse(Db *xorm.Engine, masterId, isFreeze string) (map[string]model.VirtualCoin, error) { + virtualCoinMap := make(map[string]model.VirtualCoin) + listInUse, err := VirtualCoinListInUse(Db, masterId, isFreeze) + if err != nil { + return nil, err + } + for _, coin := range listInUse { + virtualCoinMap[utils.AnyToString(coin.Id)] = *coin + } + return virtualCoinMap, nil +} + +func VirtualCoinByIds(eg *xorm.Engine, ids []string) map[string]model.VirtualCoin { + var data []model.VirtualCoin + virtualCoinMap := make(map[string]model.VirtualCoin) + err := eg.In("id", ids).Find(&data) + if err != nil { + return nil + } + for _, coin := range data { + virtualCoinMap[utils.AnyToString(coin.Id)] = coin + } + return virtualCoinMap +} diff --git a/app/db/model/appreciation_base.go b/app/db/model/appreciation_base.go new file mode 100644 index 0000000..ff3a55f --- /dev/null +++ b/app/db/model/appreciation_base.go @@ -0,0 +1,7 @@ +package model + +type AppreciationBase struct { + Id int64 `json:"id" xorm:"pk autoincr BIGINT(20)"` + Sum string `json:"sum" xorm:"default 0.0000 DECIMAL(20,4)"` + FlowSum string `json:"flow_sum" xorm:"default 0.0000 DECIMAL(20,4)"` +} diff --git a/app/db/model/appreciation_day_list.go b/app/db/model/appreciation_day_list.go new file mode 100644 index 0000000..f885f04 --- /dev/null +++ b/app/db/model/appreciation_day_list.go @@ -0,0 +1,12 @@ +package model + +import "time" + +type AppreciationDayList struct { + Id int `json:"id" xorm:"not null pk autoincr INT(11)"` + Date string `json:"date" xorm:"VARCHAR(255)"` + Value string `json:"value" xorm:"default 0.0000 DECIMAL(20,4)"` + Sum string `json:"sum" xorm:"default 0.0000 DECIMAL(20,4)"` + FlowSum string `json:"flow_sum" xorm:"default 0.0000 DECIMAL(20,4)"` + Time time.Time `json:"time" xorm:"not null comment('结束时间') DATETIME"` +} diff --git a/app/db/model/user_virtual_amount.go b/app/db/model/user_virtual_amount.go new file mode 100644 index 0000000..056bb33 --- /dev/null +++ b/app/db/model/user_virtual_amount.go @@ -0,0 +1,10 @@ +package model + +type UserVirtualAmount struct { + Id int64 `json:"id" xorm:"pk autoincr BIGINT(20)"` + Uid int `json:"uid" xorm:"index INT(11)"` + CoinId int `json:"coin_id" xorm:"INT(11)"` + Amount string `json:"amount" xorm:"DECIMAL(16,6)"` + FreezeAmount string `json:"freeze_amount" xorm:"DECIMAL(16,6)"` + WaitAmount string `json:"wait_amount" xorm:"DECIMAL(16,6)"` +} diff --git a/app/db/model/user_virtual_coin_flow.go b/app/db/model/user_virtual_coin_flow.go new file mode 100644 index 0000000..b63e328 --- /dev/null +++ b/app/db/model/user_virtual_coin_flow.go @@ -0,0 +1,27 @@ +package model + +import ( + "time" +) + +type UserVirtualCoinFlow struct { + Id int64 `json:"id" xorm:"pk autoincr BIGINT(20)"` + Uid int `json:"uid" xorm:"not null comment('用户id') index INT(11)"` + CoinId int `json:"coin_id" xorm:"not null comment('虚拟币id') INT(11)"` + Direction int `json:"direction" xorm:"not null comment('方向:1收入 2支出') TINYINT(255)"` + Title string `json:"title" xorm:"comment('标题') VARCHAR(255)"` + OrdId string `json:"ord_id" xorm:"comment('相关的订单id') VARCHAR(255)"` + Date string `json:"date" xorm:"comment('相关的订单id') VARCHAR(255)"` + Amout string `json:"amout" xorm:"not null comment('变更数量') DECIMAL(16,6)"` + BeforeAmout string `json:"before_amout" xorm:"not null comment('变更前数量') DECIMAL(16,6)"` + AfterAmout string `json:"after_amout" xorm:"not null comment('变更后数量') DECIMAL(16,6)"` + SysFee string `json:"sys_fee" xorm:"not null default 0.000000 comment('手续费') DECIMAL(16,6)"` + CoinTransferData string `json:"coin_transfer_data" xorm:"not null comment('虚拟币转赠信息') TEXT"` + CreateTime time.Time `json:"create_time" xorm:"created default 'CURRENT_TIMESTAMP' comment('创建时间') DATETIME"` + TransferType int `json:"transfer_type" xorm:"comment('转账类型:1全球分红,2管理员修改,3消费,4退回,5虚拟币兑换') TINYINT(100)"` + CoinIdTo int `json:"coin_id_to" xorm:"not null default 0 comment('兑换时目标币种id') INT(11)"` + IsRevoke int `json:"is_revoke" xorm:"not null default 0 comment('转赠是否撤回') INT(1)"` + TransferId int `json:"transfer_id" xorm:"not null default 0 comment('转赠关联id') INT(11)"` + ToUid int `json:"to_uid" xorm:"not null default 0 comment('转赠的用户id') INT(11)"` + TransferMoney string `json:"transfer_money" xorm:"not null default '0.000000' comment('转赠已撤回金额') INT(11)"` +} diff --git a/app/db/model/virtual_coin.go b/app/db/model/virtual_coin.go new file mode 100644 index 0000000..69b9db3 --- /dev/null +++ b/app/db/model/virtual_coin.go @@ -0,0 +1,19 @@ +package model + +type VirtualCoin struct { + Id int `json:"id" xorm:"not null pk autoincr INT(11)"` + Name string `json:"name" xorm:"not null default '' comment('名称') VARCHAR(255)"` + ExchangeRatio string `json:"exchange_ratio" xorm:"not null comment('兑换比例(与金额)') DECIMAL(5,2)"` + IsUse int `json:"is_use" xorm:"comment('是否开启:0否 1是') TINYINT(1)"` + CanExchange string `json:"can_exchange" xorm:"comment('能兑换的虚拟币id和手续费列表json') VARCHAR(255)"` + CanExchangeMoney int `json:"can_exchange_money" xorm:"not null default 0 comment('现金能否兑换:0否 1是') TINYINT(1)"` + CanExchangeLvList string `json:"can_exchange_lv_list" xorm:"comment('兑换等级') VARCHAR(255)"` + IsBlock int `json:"is_block" xorm:"not null default 0 comment('是否区块币:0否 1是') TINYINT(1)"` + FunctionType string `json:"function_type" xorm:"comment('功能类型') VARCHAR(255)"` + CanCny int `json:"can_cny" xorm:"not null default 0 comment('是否能兑换余额:0否 1是') TINYINT(1)"` + CanTransfer int `json:"can_transfer" xorm:"not null default 0 comment('是否能支持转账:0否 1是') TINYINT(1)"` + CanBackout int `json:"can_backout" xorm:"not null default 0 comment('是否能支持转账撤回:0否 1是') TINYINT(1)"` + LimitLevelTransfer string `json:"limit_level_transfer" xorm:"default '' comment('能支持转账的用户等级') VARCHAR(600)"` + LimitLevelBackout string `json:"limit_level_backout" xorm:"comment('能支持撤回的用户等级') VARCHAR(600)"` + TransferRatio string `json:"transfer_ratio" xorm:"not null comment('转赠比例(与金额)') DECIMAL(5,2)"` +} diff --git a/app/svc/svc_user_flow.go b/app/svc/svc_user_flow.go index 9ae1d0f..98eb4d9 100644 --- a/app/svc/svc_user_flow.go +++ b/app/svc/svc_user_flow.go @@ -45,6 +45,35 @@ func UpdateUserFinValidAndInterFlow(engine *xorm.Engine, money, Title, ordType s } return session.Commit() } +func UpdateUserFinValidAndInterFlowSess(session *xorm.Session, money, Title, ordType string, types, orderAction, uid, id int, ordId, otherId int64) error { + userProfile, err := db.UserProfileFindByIdWithSession(session, uid) + if err != nil || userProfile == nil { + if err == nil { + err = errors.New("获取用户余额信息失败") + } + return err + } + beforeAmount := userProfile.FinValid + if types == 0 { + userProfile.FinValid = utils.AnyToString(utils.AnyToFloat64(userProfile.FinValid) + utils.StrToFloat64(money)) + } else if types == 1 { + userProfile.FinValid = utils.AnyToString(utils.AnyToFloat64(userProfile.FinValid) - utils.StrToFloat64(money)) + } + afterAmount := userProfile.FinValid + userProfile.FinTotal = userProfile.FinTotal + utils.StrToFloat32(money) + affected, err := db.UserProfileUpdateWithSession(session, uid, userProfile, "fin_valid,fin_total") + if err != nil || affected == 0 { + if err == nil { + err = errors.New("更新用户余额信息失败") + } + return err + } + err = flowInsertSess(session, uid, money, orderAction, ordId, otherId, id, Title, ordType, types, beforeAmount, afterAmount) + if err != nil { + return err + } + return nil +} func flowInsertSess(session *xorm.Session, uid int, paidPrice string, orderAction int, ordId int64, id int64, goodsId int, ItemTitle string, ordType string, types int, beforeAmount string, afterAmount string) error { now := time.Now() diff --git a/app/svc/svc_user_virtual_coin_flow.go b/app/svc/svc_user_virtual_coin_flow.go new file mode 100644 index 0000000..bd9ddaa --- /dev/null +++ b/app/svc/svc_user_virtual_coin_flow.go @@ -0,0 +1,76 @@ +package svc + +import ( + "applet/app/db" + "applet/app/db/model" + "applet/app/utils" + "applet/app/utils/logx" + "errors" + "time" + "xorm.io/xorm" +) + +func ExchangeUserVirFinValidAndInterFlowWithSession(session *xorm.Session, money float64, Title, fee string, types, transferType, uid, coinId, coinIdTo int, ordId int64, coinTransferJson string, transferId, toUid int64) (int64, error) { + UserVirtualAmount, err := db.UserVirtualAmountFindByIdWithSession(session, uid, coinId) + if err != nil || UserVirtualAmount == nil { + if err == nil { + err = errors.New("获取用户余额信息失败") + } + return 0, err + } + beforeAmount := UserVirtualAmount.Amount + afterAmount := "" + if types == 1 { + afterAmount = utils.Float64ToStrByPrec(utils.AnyToFloat64(UserVirtualAmount.Amount)+money, 6) + UserVirtualAmount.Amount = utils.GetPrec(utils.Float64ToStrByPrec(utils.AnyToFloat64(UserVirtualAmount.Amount)+money, 5), "4") + } else if types == 2 { + afterAmount = utils.Float64ToStrByPrec(utils.AnyToFloat64(UserVirtualAmount.Amount)-money, 6) + UserVirtualAmount.Amount = utils.GetPrec(utils.Float64ToStrByPrec(utils.AnyToFloat64(UserVirtualAmount.Amount)-money, 5), "4") + if utils.StrToInt64(UserVirtualAmount.Amount) < 0 { + _ = session.Rollback() + err = errors.New("余额不足") + return 0, err + } + + } + affected, err := db.UserVirtualAmountUpdateWithSession(session, uid, coinId, UserVirtualAmount, "amount") + if err != nil || affected == 0 { + if err == nil { + err = errors.New("更新用户余额信息失败") + } + return 0, err + } + id, err := virtualCoinFlowInsert(session, uid, coinId, coinIdTo, utils.Float64ToStrByPrec(money, 8), fee, ordId, Title, types, transferType, beforeAmount, afterAmount, coinTransferJson, transferId, toUid) + if err != nil { + return 0, err + } + return id, nil +} + +func virtualCoinFlowInsert(session *xorm.Session, uid, coinId, coinIdTo int, money, SysFee string, ordId int64, ItemTitle string, types, transferType int, beforeAmount string, afterAmount, coinTransferJson string, transferId, toUid int64) (int64, error) { + now := time.Now() + data := &model.UserVirtualCoinFlow{ + Uid: uid, + OrdId: utils.Int64ToStr(ordId), + CoinId: coinId, + CoinIdTo: coinIdTo, + Direction: types, + Title: ItemTitle, + Amout: money, + BeforeAmout: beforeAmount, + AfterAmout: afterAmount, + SysFee: SysFee, + CreateTime: now, + TransferType: transferType, + CoinTransferData: coinTransferJson, + TransferId: int(transferId), + ToUid: int(toUid), + Date: now.Format("2006-01"), + } + if err := db.UserVirtualCoinFlowInsertOneWithSession( + session, data); err != nil { + _ = logx.Warn(err) + return 0, err + } + return data.Id, nil +} diff --git a/app/utils/string.go b/app/utils/string.go index e7142ef..766cbdf 100644 --- a/app/utils/string.go +++ b/app/utils/string.go @@ -25,6 +25,56 @@ func InArr(target string, str_array []string) bool { } return false } +func StrToFormat(s string, prec int) string { + ex := strings.Split(s, ".") + if len(ex) == 2 { + if StrToFloat64(ex[1]) == 0 { //小数点后面为空就是不要小数点了 + return ex[0] + } + //看取多少位 + str := ex[1] + str1 := str + if prec < len(str) { + str1 = str[0:prec] + } else { + for i := 0; i < prec-len(str); i++ { + str1 += "0" + } + } + if prec > 0 { + return ex[0] + "." + str1 + } else { + return ex[0] + } + } + return s +} + +func GetPrec(sum, commPrec string) string { + if sum == "" { + sum = "0" + } + sum = StrToFormat(sum, StrToInt(commPrec)) + ex := strings.Split(sum, ".") + if len(ex) == 2 { + if StrToFloat64(ex[1]) == 0 { + sum = ex[0] + } else { + val := Float64ToStrByPrec(StrToFloat64(ex[1]), 0) + keyMax := 0 + for i := 0; i < len(val); i++ { + ch := string(val[i]) + fmt.Println(StrToInt(ch)) + if StrToInt(ch) > 0 { + keyMax = i + } + } + valNew := val[0 : keyMax+1] + sum = ex[0] + "." + strings.ReplaceAll(ex[1], val, valNew) + } + } + return sum +} //把数组的值放到key里 func ArrayColumn(array interface{}, key string) (result map[string]interface{}, err error) { diff --git a/consume/init.go b/consume/init.go index f44df3c..edb5612 100644 --- a/consume/init.go +++ b/consume/init.go @@ -17,6 +17,8 @@ func Init() { // 增加消费任务队列 func initConsumes() { + //jobs[consumeMd.ZhiosAppreciationFunName] = ZhiosAppreciation + jobs[consumeMd.ZhiosValidUserFunName] = ZhiosValidUser //jobs[consumeMd.ZhiosAcquisitionConditionDevFunName] = ZhiosAcquisitionCondition diff --git a/consume/md/consume_key.go b/consume/md/consume_key.go index e2147ad..75613a9 100644 --- a/consume/md/consume_key.go +++ b/consume/md/consume_key.go @@ -236,6 +236,15 @@ var RabbitMqQueueKeyList = []*MqQueue{ BindKey: "", ConsumeFunName: "ZhiosValidUser", }, + { + ExchangeName: "zhios.appreciation.exchange", + Name: "zhios_appreciation_dev", + Type: DirectQueueType, + IsPersistent: false, + RoutKey: "appreciation_dev", + BindKey: "", + ConsumeFunName: "ZhiosAppreciation", + }, } const ( @@ -263,5 +272,6 @@ const ( CloudIssuanceAsyncMLoginFunName = "CloudIssuanceAsyncMLoginConsume" ZhiosAcquisitionConditionFunName = "ZhiosAcquisitionCondition" ZhiosValidUserFunName = "ZhiosValidUser" + ZhiosAppreciationFunName = "ZhiosAppreciation" ZhiosAcquisitionConditionDevFunName = "ZhiosAcquisitionConditionDev" ) diff --git a/consume/md/md_zhios_capital_pool_order_total.go b/consume/md/md_zhios_capital_pool_order_total.go index 9d726ee..7c742ae 100644 --- a/consume/md/md_zhios_capital_pool_order_total.go +++ b/consume/md/md_zhios_capital_pool_order_total.go @@ -18,3 +18,11 @@ type ZhiosWithdraw struct { Id string `json:"id"` Mid string `json:"mid"` } + +type ZhiosAppreciation struct { + Uid string `json:"uid"` + Mid string `json:"mid"` + Oid string `json:"oid"` + Type string `json:"type"` + Ext string `json:"ext"` +} diff --git a/consume/zhios_appreciation.go b/consume/zhios_appreciation.go new file mode 100644 index 0000000..26903c4 --- /dev/null +++ b/consume/zhios_appreciation.go @@ -0,0 +1,234 @@ +package consume + +import ( + "applet/app/db" + "applet/app/svc" + "applet/app/utils" + "applet/app/utils/logx" + "applet/consume/md" + "code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit" + "encoding/json" + "errors" + "fmt" + "github.com/streadway/amqp" + "xorm.io/xorm" +) + +func ZhiosAppreciation(queue md.MqQueue) { + fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>") + ch, err := rabbit.Cfg.Pool.GetChannel() + if err != nil { + logx.Error(err) + return + } + defer ch.Release() + //1、将自己绑定到交换机上 + ch.Bind(queue.Name, queue.ExchangeName, queue.RoutKey) + //2、取出数据进行消费 + ch.Qos(1) + delivery := ch.Consume(queue.Name, false) + + var res amqp.Delivery + var ok bool + for { + res, ok = <-delivery + if ok == true { + //fmt.Println(string(res.Body)) + fmt.Println(">>>>>>>>>>>>>>>>CanalOrderConsume<<<<<<<<<<<<<<<<<<<<<<<<<") + err = handleZhiosAppreciation(res.Body) + //_ = res.Reject(false) + if err == nil { + _ = res.Ack(true) + } + } else { + panic(errors.New("error getting message")) + } + } + fmt.Println("get msg done") +} + +func handleZhiosAppreciation(msg []byte) error { + //1、解析canal采集至mq中queue的数据结构体 + var canalMsg *md.ZhiosAppreciation + fmt.Println(string(msg)) + var tmpString string + err := json.Unmarshal(msg, &tmpString) + if err != nil { + fmt.Println("===with", err.Error()) + return err + } + fmt.Println(tmpString) + err = json.Unmarshal([]byte(tmpString), &canalMsg) + if err != nil { + fmt.Println("===with", err.Error()) + return err + } + mid := canalMsg.Mid + eg := db.DBs[mid] + if eg == nil { + return nil + } + + //类型 转入 exchange + if canalMsg.Type == "exchange" { + err := exchange(eg, canalMsg) + if err != nil { + return err + } + } + //类型 提现 withdraw 到余额 + if canalMsg.Type == "withdraw" { + err := withdraw(eg, canalMsg) + if err != nil { + return err + } + } + //类型 购物销毁 + if canalMsg.Type == "destroy" { + err := destroy(eg, canalMsg) + if err != nil { + return err + } + } + + return nil +} + +//转入 操作加入资金池和加入积分 +func exchange(eg *xorm.Engine, msg *md.ZhiosAppreciation) error { + + sess := eg.NewSession() + defer sess.Close() + sess.Begin() + //计算出当前的价值 + args := make(map[string]string) + json.Unmarshal([]byte(msg.Ext), &args) + biliMap := caleBili(eg, sess, msg.Mid, args) + ordId := utils.OrderUUID(utils.StrToInt(msg.Uid)) + coinMapInUse, _ := db.VirtualCoinMapInUse(eg, msg.Mid, "") + //积分加入 + title := coinMapInUse[args["id"]].Name + "-转入" + appreciationCoinId := db.SysCfgGetWithDb(eg, msg.Mid, "appreciation_coin_id") + _, err := svc.ExchangeUserVirFinValidAndInterFlowWithSession(sess, + utils.StrToFloat64(biliMap["in_coin"]), title, "0", 1, 109, utils.StrToInt(msg.Uid), utils.StrToInt(appreciationCoinId), 0, utils.StrToInt64(ordId), "", 0, 0) + if err != nil { + sess.Rollback() + return err + } + //加入资金池 + sql := `UPDATE appreciation_base SET sum=sum+?,flow_sum=flow_sum+? WHERE is_use=1;` + _, err = sess.Exec(sql, biliMap["coin"], biliMap["in_coin"]) + if err != nil { + sess.Rollback() + return err + } + sess.Commit() + return nil +} + +//提现 +func withdraw(eg *xorm.Engine, msg *md.ZhiosAppreciation) error { + sess := eg.NewSession() + defer sess.Close() + sess.Begin() + args := make(map[string]string) + json.Unmarshal([]byte(msg.Ext), &args) + coinMap := coinPriceEg(eg) + appreciationWithdrawFee := db.SysCfgGetWithDb(eg, msg.Mid, "appreciation_withdraw_fee") + appreciationWithdrawBack := db.SysCfgGetWithDb(eg, msg.Mid, "appreciation_withdraw_back") + //实际到账的 + amount := utils.StrToFloat64(args["amount"]) * (1 - (utils.StrToFloat64(appreciationWithdrawFee) / 100)) + newAmount := utils.GetPrec(utils.Float64ToStrByPrec(amount*utils.StrToFloat64(coinMap["price"]), 5), "4") + //扣的 + coinSum := utils.StrToFloat64(args["amount"]) * (1 - (utils.StrToFloat64(appreciationWithdrawFee) / 100) - (utils.StrToFloat64(appreciationWithdrawBack) / 100)) + err := svc.UpdateUserFinValidAndInterFlowSess(sess, + newAmount, args["amount"]+"个积分转余额", "appreciation", 0, 56, utils.StrToInt(msg.Uid), utils.StrToInt(msg.Oid), utils.StrToInt64(msg.Oid), utils.StrToInt64(msg.Oid)) + if err != nil { + sess.Rollback() + return err + } + sql := `UPDATE appreciation_base SET sum=sum-?,flow_sum=flow_sum-? WHERE is_use=1;` + _, err = eg.Exec(sql, coinSum, args["amount"]) + if err != nil { + sess.Rollback() + return err + } + sess.Commit() + return err +} + +//购物销毁 +func destroy(eg *xorm.Engine, msg *md.ZhiosAppreciation) error { + args := make(map[string]string) + json.Unmarshal([]byte(msg.Ext), &args) + sql := `UPDATE appreciation_base SET sum=sum-?,flow_sum=flow_sum-? WHERE is_use=1;` + _, err := eg.Exec(sql, args["amount"], args["amount"]) + if err != nil { + return err + } + return err +} + +func caleBili(eg *xorm.Engine, sess *xorm.Session, dbName string, args map[string]string) map[string]string { + appreciationCoinId := db.SysCfgGetWithDb(eg, dbName, "appreciation_coin_id") + bCoinStr := "" + bcoin := "" + if args["id"] == "cny" { + bCoinStr = args["amount"] + } else { + ids := []string{args["id"], appreciationCoinId} + coin := db.VirtualCoinByIds(eg, ids) + aCoinBili := coin[args["id"]].ExchangeRatio + //1:5=X:money X= 1:5*money + amoney := (1 / utils.StrToFloat64(aCoinBili)) * utils.StrToFloat64(args["amount"]) + bcoin = utils.GetPrec(utils.Float64ToStrByPrec(amoney, 5), "4") + //这是只返70% + appreciationCoinFee := db.SysCfgGetWithDb(eg, dbName, "appreciation_coin_fee") + bCoins := amoney * (utils.StrToFloat64(appreciationCoinFee) / 100) + coinPriceMap := coinPrice(sess) + //除以当前的资产价值 + bCoins = bCoins / utils.StrToFloat64(coinPriceMap["price"]) + bCoinStr = utils.GetPrec(utils.Float64ToStrByPrec(bCoins, 5), "4") + } + res := map[string]string{ + "in_coin": bCoinStr, + "coin": bcoin, + } + return res +} +func coinPrice(sess *xorm.Session) map[string]string { + base := db.GetAppreciationBase(sess) + sum := "0" + flowSum := "0" + price := "1" + if base != nil { + sum = base.Sum + flowSum = base.FlowSum + } + if utils.StrToFloat64(base.Sum) > 0 { + price = utils.GetPrec(utils.Float64ToStrByPrec(utils.StrToFloat64(sum)/utils.StrToFloat64(flowSum), 5), "4") + } + res := map[string]string{ + "price": price, + "sum": sum, + "flow_sum": flowSum, + } + return res +} +func coinPriceEg(eg *xorm.Engine) map[string]string { + base := db.GetAppreciationBaseEg(eg) + sum := "0" + flowSum := "0" + price := "1" + if base != nil { + sum = base.Sum + flowSum = base.FlowSum + } + price = utils.GetPrec(utils.Float64ToStrByPrec(utils.StrToFloat64(sum)/utils.StrToFloat64(flowSum), 5), "4") + res := map[string]string{ + "price": price, + "sum": sum, + "flow_sum": flowSum, + } + return res +} diff --git a/consume/zhios_recharge_order_fail.go b/consume/zhios_recharge_order_fail.go index 12fe5c8..487d983 100644 --- a/consume/zhios_recharge_order_fail.go +++ b/consume/zhios_recharge_order_fail.go @@ -74,7 +74,6 @@ func handleZhiosRechargeOrderFail(msg []byte) error { return err } mid := canalMsg.Mid - mid = "123456" eg := db.DBs[mid] uid := utils.StrToInt(canalMsg.Uid) oid := canalMsg.Oid