@@ -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() | 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 { | 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() | 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 | 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里 | //把数组的值放到key里 | ||||
func ArrayColumn(array interface{}, key string) (result map[string]interface{}, err error) { | func ArrayColumn(array interface{}, key string) (result map[string]interface{}, err error) { | ||||
@@ -17,6 +17,8 @@ func Init() { | |||||
// 增加消费任务队列 | // 增加消费任务队列 | ||||
func initConsumes() { | func initConsumes() { | ||||
//jobs[consumeMd.ZhiosAppreciationFunName] = ZhiosAppreciation | |||||
jobs[consumeMd.ZhiosValidUserFunName] = ZhiosValidUser | jobs[consumeMd.ZhiosValidUserFunName] = ZhiosValidUser | ||||
//jobs[consumeMd.ZhiosAcquisitionConditionDevFunName] = ZhiosAcquisitionCondition | //jobs[consumeMd.ZhiosAcquisitionConditionDevFunName] = ZhiosAcquisitionCondition | ||||
@@ -236,6 +236,15 @@ var RabbitMqQueueKeyList = []*MqQueue{ | |||||
BindKey: "", | BindKey: "", | ||||
ConsumeFunName: "ZhiosValidUser", | ConsumeFunName: "ZhiosValidUser", | ||||
}, | }, | ||||
{ | |||||
ExchangeName: "zhios.appreciation.exchange", | |||||
Name: "zhios_appreciation_dev", | |||||
Type: DirectQueueType, | |||||
IsPersistent: false, | |||||
RoutKey: "appreciation_dev", | |||||
BindKey: "", | |||||
ConsumeFunName: "ZhiosAppreciation", | |||||
}, | |||||
} | } | ||||
const ( | const ( | ||||
@@ -263,5 +272,6 @@ const ( | |||||
CloudIssuanceAsyncMLoginFunName = "CloudIssuanceAsyncMLoginConsume" | CloudIssuanceAsyncMLoginFunName = "CloudIssuanceAsyncMLoginConsume" | ||||
ZhiosAcquisitionConditionFunName = "ZhiosAcquisitionCondition" | ZhiosAcquisitionConditionFunName = "ZhiosAcquisitionCondition" | ||||
ZhiosValidUserFunName = "ZhiosValidUser" | ZhiosValidUserFunName = "ZhiosValidUser" | ||||
ZhiosAppreciationFunName = "ZhiosAppreciation" | |||||
ZhiosAcquisitionConditionDevFunName = "ZhiosAcquisitionConditionDev" | ZhiosAcquisitionConditionDevFunName = "ZhiosAcquisitionConditionDev" | ||||
) | ) |
@@ -18,3 +18,11 @@ type ZhiosWithdraw struct { | |||||
Id string `json:"id"` | Id string `json:"id"` | ||||
Mid string `json:"mid"` | 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 | return err | ||||
} | } | ||||
mid := canalMsg.Mid | mid := canalMsg.Mid | ||||
mid = "123456" | |||||
eg := db.DBs[mid] | eg := db.DBs[mid] | ||||
uid := utils.StrToInt(canalMsg.Uid) | uid := utils.StrToInt(canalMsg.Uid) | ||||
oid := canalMsg.Oid | oid := canalMsg.Oid | ||||