@@ -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 | |||
} |
@@ -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 | |||
} |
@@ -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 | |||
} |
@@ -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 | |||
} |
@@ -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)"` | |||
} |
@@ -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"` | |||
} |
@@ -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)"` | |||
} |
@@ -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)"` | |||
} |
@@ -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)"` | |||
} |
@@ -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() | |||
@@ -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 | |||
} |
@@ -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) { | |||
@@ -17,6 +17,8 @@ func Init() { | |||
// 增加消费任务队列 | |||
func initConsumes() { | |||
//jobs[consumeMd.ZhiosAppreciationFunName] = ZhiosAppreciation | |||
jobs[consumeMd.ZhiosValidUserFunName] = ZhiosValidUser | |||
//jobs[consumeMd.ZhiosAcquisitionConditionDevFunName] = ZhiosAcquisitionCondition | |||
@@ -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" | |||
) |
@@ -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"` | |||
} |
@@ -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 | |||
} |
@@ -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 | |||