首页数据

pull/1/head
mofangmin 1 year ago
parent de4371e81c
commit 9a1cd35812
  1. 10
      bin/conf/backend/conf.toml
  2. 12
      bin/conf/baseConf.toml
  3. 17
      bin/conf/pay/conf.toml
  4. 2
      bin/conf/web/conf.toml
  5. 3
      call/config.go
  6. 49
      call/game.go
  7. 24
      call/pay.go
  8. 3
      call/share.go
  9. 45
      call/task.go
  10. 6
      call/user.go
  11. 5
      common/config.go
  12. 2
      common/currency.go
  13. 2
      common/platform.go
  14. 11
      common/share.go
  15. 54
      common/task.go
  16. 9
      config/config.go
  17. 1
      go.mod
  18. 2
      go.sum
  19. 11
      main.go
  20. 55
      modules/backend/handler/common/common.go
  21. 4
      modules/backend/handler/examine/examine.go
  22. 10
      modules/backend/handler/guser/getGameUserList.go
  23. 1
      modules/backend/routers/routers_common.go
  24. 12
      modules/backend/values/protocol.go
  25. 59
      modules/web/app/activity.go
  26. 9
      modules/web/handler/activity.go
  27. 90
      modules/web/handler/firstpage.go
  28. 10
      modules/web/handler/game.go
  29. 7
      modules/web/handler/share.go
  30. 3
      modules/web/handler/vip.go
  31. 11
      modules/web/handler/withdraw.go
  32. 17
      modules/web/values/firstpage.go
  33. 1
      modules/web/values/share.go
  34. 121
      util/util.go

@ -1,10 +1,18 @@
[Backend]
Addr=":7616"
Release=false
DB="root:d47a98e748ccaf1f@tcp(172.105.117.6:3306)/backend"
DB="root:123456@tcp(192.168.10.101:3306)/backend"
[Web.ZYPay]
ZYPayURL="https://in.zyhws.com/tablegames/singleton/orderPay"
ZYWithdrawURL="https://in.zyhws.com/tablegames/singleton/orderdraw"
PayNotifyURL="http://192.168.1.141:7615/balance/recharge/ZYPayCallback"
WithdrawNotifyURL="http://192.168.1.141:7615/balance/withdraw/ZYWithdrawCallback"
WhiteIPs = ["47.241.254.165","8.214.46.27"]
[Backend.Oss]
Endpoint="oss-ap-south-1.aliyuncs.com"
AccessKeyId="LTAI5tLaYWuRVz7BiQ7m666Z"
AccessKeySecret="6s7mMexYbVmZSLXEv3kdJwxXThMN4T"
BucketName="xpggame"
ObjectName="res/"

@ -1,23 +1,23 @@
[net]
registry="127.0.0.1:8500" # consul 地址
nats="nats://127.0.0.1:4222" # nats地址
registry="192.168.10.101:8500" # consul 地址
nats="nats://192.168.10.101:4222" # nats地址
[redis]
addr="127.0.0.1:6379"
addr="192.168.10.101:6379"
name=""
passwd=""
tls=false
db=0
db=2
cluster=false
[es]
#urls=["http://127.0.0.1:9200"]
urls=["http://elastic:joyyu7XRwlpJtXFEIw80@47.112.119.250:9400"]
urls=["http://elastic:ZyepQWx5QRO2oGzSJCz5@47.106.150.32:9400"]
sniff=false
[mysql]
#dsn="xh_rwuser:!Xhwlkj2018@tcp(127.0.0.1:3306)/game"
dsn="root:d9JaXnG5QuuZLIrY@tcp(47.112.119.250:3306)/slotsgame"
dsn="root:123456@tcp(192.168.10.101:3306)/brl_game"
debug=true
[facebook]

@ -14,18 +14,21 @@ PaySuccessWeight = 50
BaseSuccess = 10
WithdrawScanTime = 10
[Pay.IGeek]
APIURL = "http://api.test.igeekpay.com/gateway"
APPID = "H4RIKR"
MID = "RSRV686X"
Key = "2YHPVB8DZKTALVVI"
#APIURL = "https://api.test.payasaan.com/gateway"
APIURL = "https://api.igeekpay.com/gateway"
APPID = "TJ7V2H"
MID = "Z61CRKK2"
Key = "29AR9288DULM53QD"
[Web.Adjust]
URL = "https://s2s.adjust.com/event"
APIURL = "https://api.adjust.com/device_service/api/v1/inspect_device"
APIToken = "_2ZGYezfdZ7yD2he-zWx"
[Web.FB]
APIURL = "https://graph.facebook.com/v18.0/"
[Pay.BestPay]
APIURL = "https://very.goodrummy.co.in"
[Pay.GrePay]
Key = ""
WithdrawAccount = ""
MIDAmount = 3000
Key = "FF5D557F6AC9EF26212B482B23AD7F07"
WithdrawAccount = "2208100000250402110"
MIDAmount = 50000
BigChannel = "0452"

@ -13,7 +13,7 @@ TestWithdraw=-1
TestPay=3
FetchTime = 60
OldChannels = []
FreeSpinFirst = 500000000
FreeSpinFirst = 2000
TotalWithdrawPer = 50
BreakLimit = 100000000
SelectID = 2

@ -710,6 +710,7 @@ func GetConfigGameList(num int, cond ...int) []*common.ConfigGameList {
return ret
}
}
GetGameInfo(ret)
return ret
}
@ -1072,7 +1073,7 @@ func GetConfigTaskByTaskID(taskID int) *common.ConfigTask {
func GetConfigTaskByTaskType(t int) (ret []*common.ConfigTask) {
for _, v := range configTask {
if v.Type == t {
if int(v.Type) == t {
ret = append(ret, v)
}
}

@ -1,11 +1,15 @@
package call
import (
"context"
"errors"
"fmt"
"server/common"
"server/db"
"server/util"
"time"
"github.com/go-redis/redis/v8"
"github.com/liangdas/mqant/log"
"gorm.io/gorm"
)
@ -44,3 +48,48 @@ func UpdateGameSort(provider, gameID int) {
db.Mysql().Update(&common.ConfigGameList{GameProvider: provider, GameID: gameID}, map[string]interface{}{"sort": gorm.Expr("sort + 1")})
})
}
// GetGameInfo 获取游戏信息
func GetGameInfo(gameInfos []*common.ConfigGameList) {
ctx := context.Background()
rdb := db.Redis().GetRedis()
pipeline := rdb.Pipeline()
maxRewardField := "maxReward"
rtpField := "rtp"
maxRewardTimeField := "maxRewardTime"
for _, game := range gameInfos {
key := fmt.Sprintf("firstpage:games:%d_%d", game.GameProvider, game.GameID)
pipeline.HGet(ctx, key, maxRewardField)
pipeline.HGet(ctx, key, maxRewardTimeField)
pipeline.HGet(ctx, key, rtpField)
}
cmds, err := pipeline.Exec(ctx)
now := time.Now()
for i := 0; i < 2*len(gameInfos); i = i + 2 {
game := gameInfos[i/2]
maxRewardCmd := cmds[i]
maxRewardTimeCmd := cmds[i+1]
key := fmt.Sprintf("firstpage:games:%d_%d", game.GameProvider, game.GameID)
game.MaxReward, err = maxRewardCmd.(*redis.StringCmd).Int64()
if errors.Is(err, redis.Nil) {
val := util.RandBetween64(100, 9999)
rtp := util.RandBetween64(93, 104)
game.RTP = rtp
game.MaxReward = val
pipeline.HSet(ctx, key, maxRewardField, val, maxRewardTimeField, time.Now(), rtpField, rtp)
} else {
maxRewardTime, _ := maxRewardTimeCmd.(*redis.StringCmd).Time()
if now.Sub(maxRewardTime).Hours() >= 1 {
val := util.RandBetween64(game.MaxReward, 9999)
rtp := util.RandBetween64(93, 104)
game.RTP = rtp
game.MaxReward = val
pipeline.HSet(ctx, key, maxRewardField, val, maxRewardTimeField, time.Now(), rtpField, rtp)
}
}
}
_, err = pipeline.Exec(ctx)
if err != nil {
log.Error("GetGameInfo err:%v", err)
}
}

@ -502,7 +502,7 @@ func PayActivity(r *common.RechargeOrder, notCharge bool, user *common.PlayerDBI
// VIP
UpdateVip(r.UID, r.Amount, 0, 0)
// 检查任务
CheckTask(r)
CheckTask(Task{Uid: r.UID, Value: r.Amount, Types: []common.TaskType{common.TaskTypeOnceRecharge}})
// 检查所有活动
CheckAllActivity(r)
@ -515,28 +515,6 @@ func PayActivity(r *common.RechargeOrder, notCharge bool, user *common.PlayerDBI
return nil
}
func CheckTask(r *common.RechargeOrder) {
now := time.Now().Unix()
con := GetConfigTask()
for _, v := range con {
if (v.Type == common.TaskTypeOnceRecharge || v.Type == common.TaskTypeFirstRecharge) && r.Amount >= v.Target { // 单次充值任务 || 首次充值任务
data := GetUserTaskDataByTaskID(r.UID, v.TaskID)
if data.ID == 0 {
db.Mysql().Create(&common.TaskData{UID: r.UID, TaskID: v.TaskID, Time: now, Progress: v.Target})
} else if data.Progress == 0 {
db.Mysql().Update(&common.TaskData{UID: r.UID, TaskID: v.TaskID}, map[string]interface{}{"progress": v.Target, "time": now})
}
} else if v.Type == common.TaskTypeTotalRecharge { // 累充任务
data := GetUserTaskDataByTaskID(r.UID, v.TaskID)
if data.ID == 0 {
db.Mysql().Create(&common.TaskData{UID: r.UID, TaskID: v.TaskID, Time: now, Progress: r.Amount})
} else if data.Progress >= 0 {
db.Mysql().Update(&common.TaskData{UID: r.UID, TaskID: v.TaskID}, map[string]interface{}{"progress": gorm.Expr("progress + ?", r.Amount), "time": now})
}
}
}
}
func ActivityFirstRechargeBack(r *common.RechargeOrder) {
now := time.Now().Unix()
if IsActivityValid(common.ActivityIDFirstRechargeBack) {

@ -57,6 +57,9 @@ func ShareBind(share string, isOld bool, uid, cid int) {
// 更新上级邀请玩家数
db.Mysql().Update(&common.ShareInfo{UID: upInfo.UID}, map[string]interface{}{"invites": gorm.Expr("invites + 1")})
// 完成邀请任务
CheckTask(Task{Uid: uid, Value: 1, Types: []common.TaskType{common.TaskTypeInvite}})
}
// 判断分享,发放有效用户奖励

@ -0,0 +1,45 @@
package call
import (
"server/common"
"server/db"
"time"
"github.com/liangdas/mqant/log"
"gorm.io/gorm"
)
type Task struct {
Uid int // uid
Types []common.TaskType // 任务类型
Value int64 // 进度值
}
func CheckTask(task Task) {
log.Info("checkTask task:%v", task)
now := time.Now().Unix()
con := GetConfigTask()
uid := task.Uid
for _, v := range con {
for _, t := range task.Types {
if (t == common.TaskTypeOnceRecharge || t == common.TaskTypeInvite || t == common.TaskTypePlayGame) && v.Type == t { // 单次充值任务 || 首次充值任务 || v.Type == common.TaskTypeFirstRecharge)
data := GetUserTaskDataByTaskID(task.Uid, v.TaskID)
if data.ID == 0 {
db.Mysql().Create(&common.TaskData{UID: uid, TaskID: v.TaskID, Time: now, Progress: v.Target})
} else if data.Progress == 0 {
db.Mysql().Update(&common.TaskData{UID: uid, TaskID: v.TaskID}, map[string]interface{}{"progress": v.Target, "time": now})
}
break
} else if (t == common.TaskTypeBet1000 || t == common.TaskTypeBet10000) && v.Type == t {
data := GetUserTaskDataByTaskID(task.Uid, v.TaskID)
if data.ID == 0 {
db.Mysql().Create(&common.TaskData{UID: uid, TaskID: v.TaskID, Time: now, Progress: task.Value})
} else {
db.Mysql().Update(&common.TaskData{UID: uid, TaskID: v.TaskID}, map[string]interface{}{"progress": gorm.Expr("progress + ?", task.Value), "time": now})
}
break
}
}
}
}

@ -171,7 +171,6 @@ func NewUser(info *common.PlayerDBInfo, ip, share, fbc, fbp, agent string) error
initPlayer(uid, cid)
UploadAdjust(common.AdjustEventNewPlayer, info, nil)
ShareBind(share, isOld, uid, cid)
// 新手赠送
first := config.GetConfig().Web.FreeSpinFirst
if first > 0 {
@ -589,6 +588,8 @@ func UpdatePlayerProfile(data *common.ESGameData) error {
util.Go(func() {
// 更新vip
UpdateVip(uid, 0, bet, settle)
// 检查任务
CheckTask(Task{Uid: uid, Value: bet / 100, Types: []common.TaskType{common.TaskTypePlayGame, common.TaskTypeBet1000, common.TaskTypeBet10000}})
})
// 写入es
@ -635,7 +636,7 @@ func GetUserTaskData(uid int) (ret []common.TaskData) {
func GetUserTaskDataByTaskID(uid, taskID int) *common.TaskData {
data := &common.TaskData{UID: uid, TaskID: taskID}
db.Mysql().Get(data)
db.Mysql().GetLast(data)
return data
}
@ -709,7 +710,6 @@ func GetGameRecord(uid int) (gameList []*common.ConfigGameList) {
if gameConf != nil {
gameList = append(gameList, gameConf)
}
}
}
return

@ -347,8 +347,9 @@ type ConfigGameList struct {
Demo int `gorm:"column:demo;type:int(11);default:1;comment:是否支持demo 1支持 2不支持" web:"demo"`
SubID string `gorm:"column:subid;type:varchar(255);default:'';comment:一些游戏有子id" web:"subid"`
Jackpot int64 `gorm:"-" web:"-"`
MaxReward int64 `gorm:"-" web:"-" json:"max_reward"` // 最大奖励
Number int64 `gorm:"-" web:"-" json:"number"` // 游玩人数
MaxReward int64 `gorm:"-" web:"-" redis:"maxReward"` // 最大奖励
PlayerNumber int64 `gorm:"-" web:"-" redis:"number"` // 游玩人数
RTP int64 `gorm:"-" web:"-" redis:"rtp"` // rtp
}
func (c *ConfigGameList) TableName() string {

@ -197,7 +197,7 @@ func GetGameOutEvents() []interface{} {
func RoundCurrency(t CurrencyType, amount int64) int64 {
switch t {
case CurrencyINR:
return amount / 100 * 100
return amount
case CurrencyUSDT:
return amount / 100 * 100
default:

@ -45,7 +45,7 @@ const (
)
const (
DecimalDigits = 100000000 // 计算时精确到小数点后8
DecimalDigits = 100 // 计算时精确到小数点后2
)
var (

@ -15,11 +15,11 @@ func (c *ConfigShare) TableName() string {
// 分享配置
type ConfigShareSys struct {
ID int `gorm:"primarykey"`
WithdrawLimit int64 `gorm:"column:withdraw_limit;type:bigint(20);default:100000000;comment:最低领取数额" web:"withdraw_limit"`
ShareRecharge int64 `gorm:"column:share_recharge;type:bigint(20);default:2000000000;comment:有效玩家充值需求" web:"share_recharge"`
ShareReward int64 `gorm:"column:share_reward;type:bigint(20);default:1000000000;comment:分享有效玩家奖励" web:"share_reward"`
FakeInviteReward int64 `gorm:"column:fake_invite_reward;type:bigint(20);default:1250000000000000;comment:虚拟邀请奖励" web:"fake_invite_reward"`
FakeBetReward int64 `gorm:"column:fake_bet_reward;type:bigint(20);default:980000000000000;comment:虚拟投注奖励" web:"fake_bet_reward"`
WithdrawLimit int64 `gorm:"column:withdraw_limit;type:bigint(20);default:100;comment:最低领取数额" web:"withdraw_limit"`
ShareRecharge int64 `gorm:"column:share_recharge;type:bigint(20);default:2000;comment:有效玩家充值需求" web:"share_recharge"`
ShareReward int64 `gorm:"column:share_reward;type:bigint(20);default:1000;comment:分享有效玩家奖励" web:"share_reward"`
FakeInviteReward int64 `gorm:"column:fake_invite_reward;type:bigint(20);default:1250000000;comment:虚拟邀请奖励" web:"fake_invite_reward"`
FakeBetReward int64 `gorm:"column:fake_bet_reward;type:bigint(20);default:980000000;comment:虚拟投注奖励" web:"fake_bet_reward"`
}
func (c *ConfigShareSys) TableName() string {
@ -84,6 +84,7 @@ type ShareActivityCode struct {
ShareCode string `gorm:"column:share_code;type:varchar(255);index:idx_share;comment:分享码" json:"share_code"`
ActivityId int `gorm:"column:activity_id;type:int(11);index:idx_share;comment:关联活动ID" json:"activity_id"`
Reward string `gorm:"column:reward;type:varchar(255);index:idx_share;comment:分享码" json:"reward"`
ValidNum int `gorm:"column:valid_num;type:int(11);index:idx_share;comment:有效次数" json:"valid_num"`
CreateAt int64 `gorm:"column:create_at;type:bigint(20);comment:创建时间" json:"create_at"`
ExpireAt int64 `gorm:"column:expire_at;type:bigint(20);comment:过期时间" json:"expire_at"`
}

@ -1,18 +1,36 @@
package common
type TaskType int
const (
TaskTypeZero = iota
TaskTypeRegist // 注册任务
TaskTypeDownload // 下载app任务
TaskTypeTotalRecharge // 累充任务
TaskTypeOnceRecharge // 单次充值任务
TaskTypeFirstRecharge // 首次充值任务
TaskTypeZero TaskType = iota
TaskTypeOnceRecharge // 单次充值任务
TaskTypeInvite // 邀请好友
TaskTypePlayGame // 参与一次牌局
TaskTypeBet1000 // 累计下注1000
TaskTypeBet10000 // 累计下注10000
TaskTypeAll
)
// TaskTypeFirstRecharge // 首次充值任务
// TaskTypeRegist // 注册任务
// TaskTypeDownload // 下载app任务
// TaskTypeTotalRecharge // 累充任务
// 完成任意一次充值
// (每日重置一次)
// 完成一次好友邀请
// (每日重置一次,这里要有效好友才可完成,有效好友意思是只邀请的玩家充值了200卢比)
// 参与一次牌局
// (任务每日重置一次)
// 累记下注到1000
// (每日任务重置一次)
// 累记下注到10000
// (每日任务重置一次)
// 判读任务的目标是否是次数
func IsNumTaskType(t int) bool {
return t == TaskTypeRegist || t == TaskTypeDownload
// return t == TaskTypeOnceRecharge || t == TaskTypeInvite || t == TaskTypePlayGame
return false
}
func GetTaskTitle(task *ConfigTask) string {
@ -36,17 +54,17 @@ const (
// Kind 1单次 2循环
// Type 1注册 2下载 3累充 4单次充
type ConfigTask struct {
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"`
TaskID int `gorm:"column:task_id;type:int(11);default:0;uniqueIndex:task_id;comment:任务id" web:"task_id"`
Target int64 `gorm:"column:target;type:bigint(20);default:0;comment:任务目标" web:"target"`
Reward int64 `gorm:"column:reward;type:bigint(20);default:0;comment:奖励" web:"reward"`
Open int `gorm:"column:open;type:int(11);default:1;comment:开关 1打开" web:"open"`
Kind int `gorm:"column:kind;type:int(11);default:1;comment:1单次 2循环" web:"kind"`
Type int `gorm:"column:type;type:int(11);default:1;comment:1注册 2下载" web:"type"`
Title string `gorm:"column:title;type:varchar(256);default:'';comment:标题" web:"title"`
Icon string `gorm:"column:icon;type:varchar(256);default:'';comment:图标" web:"icon"`
Sort int `gorm:"column:sort;type:int(11);default:0;comment:排序" web:"sort"`
Action int `gorm:"column:action;type:int(11);default:1;comment:跳转类型" web:"action"`
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"`
TaskID int `gorm:"column:task_id;type:int(11);default:0;uniqueIndex:task_id;comment:任务id" web:"task_id"`
Target int64 `gorm:"column:target;type:bigint(20);default:0;comment:任务目标" web:"target"`
Reward int64 `gorm:"column:reward;type:bigint(20);default:0;comment:奖励" web:"reward"`
Open int `gorm:"column:open;type:int(11);default:1;comment:开关 1打开" web:"open"`
Kind int `gorm:"column:kind;type:int(11);default:1;comment:1单次 2循环" web:"kind"`
Type TaskType `gorm:"column:type;type:int(11);default:1;comment:1注册 2下载" web:"type"`
Title string `gorm:"column:title;type:varchar(256);default:'';comment:标题" web:"title"`
Icon string `gorm:"column:icon;type:varchar(256);default:'';comment:图标" web:"icon"`
Sort int `gorm:"column:sort;type:int(11);default:0;comment:排序" web:"sort"`
Action int `gorm:"column:action;type:int(11);default:1;comment:跳转类型" web:"action"`
}
func (c *ConfigTask) TableName() string {

@ -1,5 +1,13 @@
package config
type OssParams struct {
Endpoint string
AccessKeyId string
AccessKeySecret string
BucketName string
ObjectName string
}
type FacebookParams struct {
Prefix string
AppKey string
@ -118,6 +126,7 @@ type Configure struct {
Backend struct {
Addr string
DB string
Oss OssParams
}
Rummy struct {
SettleTime int

@ -4,6 +4,7 @@ go 1.16
require (
github.com/BurntSushi/toml v1.1.0
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible // indirect
github.com/bwmarrin/snowflake v0.3.0
github.com/fbsobreira/gotron-sdk v0.0.0-20230418195951-b7bfbf1c0ade
github.com/gin-gonic/gin v1.7.4

@ -33,6 +33,8 @@ github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBA
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0=

@ -36,7 +36,6 @@ func main() {
log.Info("启动游戏服务器 ...")
rand.Seed(time.Now().UTC().UnixNano())
runtime.GOMAXPROCS(runtime.NumCPU())
modulefile := flag.String("module", "module.json", "module configure file")
logdir := flag.String("log", "logs", "log file directory")
wddir := flag.String("wd", ".", "Server work directory")
@ -47,7 +46,7 @@ func main() {
conf := flag.String("conf", "conf.toml", "server configure file")
//flag.String("rule", "rule.toml", "rule config toml file")
// flag.String("rule", "rule.toml", "rule config toml file")
// flag.String("Game_config", "Game_config.xlsx", "excel game configure file")
// flag.String("robot_config", "robot_config.xlsx", "excel robot configure file")
@ -106,16 +105,16 @@ func main() {
module.ProcessID(*processID),
module.BILogDir(*bidir),
module.KillWaitTTL(1*time.Minute),
module.Debug(*debug), //只有是在调试模式下才会在控制台打印日志, 非调试模式下只在日志文件中输出日志
module.Nats(nc), //指定nats rpc
module.Registry(rs), //指定服务发现
module.Debug(*debug), // 只有是在调试模式下才会在控制台打印日志, 非调试模式下只在日志文件中输出日志
module.Nats(nc), // 指定nats rpc
module.Registry(rs), // 指定服务发现
module.RegisterTTL(20*time.Second),
module.RegisterInterval(10*time.Second),
module.Selector(selector.NewSelector(selector.Registry(rs))),
)
err = app.Run(
//已实现的模块都应该在此处传入
// 已实现的模块都应该在此处传入
hall.Module(),
common.Module(),
mgate.Module(),

@ -1,17 +1,24 @@
package handler
import (
"fmt"
"server/call"
"server/common"
"server/config"
"server/modules/backend/app"
"server/modules/backend/bdb"
"server/modules/backend/values"
"server/util"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
var (
bucket *oss.Bucket
)
func ProductList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
@ -66,7 +73,7 @@ func AccountList(c *gin.Context) {
}
resp := &values.AccountListResp{}
a.Data = resp
list := []values.User{}
var list []values.User
if err := bdb.BackDB.C().Find(&list).Error; err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
@ -76,3 +83,49 @@ func AccountList(c *gin.Context) {
resp.List = append(resp.List, v.Account)
}
}
func UploadOSS(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
ossConf := config.GetConfig().Backend.Oss
req := new(values.UploadOSSReq)
req.ObjectName = c.PostForm("ObjectName")
rsp := new(values.UploadOSSResp)
a.Data = rsp
file, err := c.FormFile("file")
if err != nil {
a.Code = values.CodeRetry
log.Error("UploadOSS err:%v", err)
return
}
f, err := file.Open()
if err != nil {
a.Code = values.CodeRetry
log.Error("UploadOSS err:%v", err)
return
}
defer f.Close()
if bucket == nil {
client, err := oss.New(ossConf.Endpoint, ossConf.AccessKeyId, ossConf.AccessKeySecret)
if err != nil {
a.Code = values.CodeRetry
log.Error("UploadOSS New err:%v", err)
return
}
bucket, err = client.Bucket(ossConf.BucketName)
if err != nil {
a.Code = values.CodeRetry
log.Error("UploadOSS Bucket err:%v", err)
return
}
}
err = bucket.PutObject(ossConf.ObjectName+file.Filename, f)
if err != nil {
a.Code = values.CodeRetry
log.Error("UploadOSS PutObject err:%v", err)
return
}
rsp.Url = fmt.Sprintf("https://%s.%s/%s", ossConf.BucketName, ossConf.Endpoint, ossConf.ObjectName+file.Filename)
}

@ -30,7 +30,7 @@ func WithdrawList(c *gin.Context) {
table1 := `(SELECT id,uid,channel_id,pay_channel,orderid,apipayid,payaccount,amount,create_time,callback_time,status,operator from withdraw_order %s)a`
table2 := `(SELECT id,platform,mobile,tag from users %s)b`
table3 := `(SELECT uid,brl from player_currency)c`
table3 := `(SELECT uid,inr from player_currency)c`
table4 := `(SELECT uid,total_recharge,total_recharge_count,total_withdraw,total_withdraw_count FROM recharge_info)d`
// 表1的查询条件
@ -76,7 +76,7 @@ func WithdrawList(c *gin.Context) {
sqlCount := " SELECT COUNT(*) AS count from"
sqlList := `SELECT a.id,a.uid,a.channel_id,a.pay_channel,a.orderid as OrderID,a.apipayid as APIPayID,a.payaccount,a.amount,a.create_time,a.callback_time,
a.status,a.operator,b.platform,b.mobile,b.tag,c.brl,d.total_recharge,d.total_recharge_count,d.total_withdraw,d.total_withdraw_count from `
a.status,a.operator,b.platform,b.mobile,b.tag,c.inr,d.total_recharge,d.total_recharge_count,d.total_withdraw,d.total_withdraw_count from `
querySql := fmt.Sprintf(table1, table1Condition) + " inner join " + fmt.Sprintf(table2, table2Condition) + " on a.uid = b.id inner join " +
table3 + " on a.uid = c.uid inner join " + table4 + " on a.uid = d.uid "

@ -87,9 +87,9 @@ func GetGameUserList(c *gin.Context) {
}
}
if len(req.Cash) > 0 {
cashSql = append(cashSql, fmt.Sprintf("brl >= %d", req.Cash[0]))
cashSql = append(cashSql, fmt.Sprintf("inr >= %d", req.Cash[0]))
if len(req.Cash) > 1 {
cashSql = append(cashSql, fmt.Sprintf("brl <= %d", req.Cash[1]))
cashSql = append(cashSql, fmt.Sprintf("inr <= %d", req.Cash[1]))
}
}
@ -118,7 +118,7 @@ func GetGameUserList(c *gin.Context) {
(SELECT uid,total_recharge,total_recharge_count,total_withdraw,total_withdraw_count,total_recharge-total_withdraw as diff from recharge_info %s)d
on a.id = d.uid
INNER JOIN
(SELECT uid,brl from player_currency %s)e
(SELECT uid,inr from player_currency %s)e
on a.id = e.uid
`, models.LinkMysqlCondi(userSql), linkB, models.LinkMysqlCondi(shareInfoSql), linkC, models.LinkMysqlCondi(vipSql),
linkD, models.LinkMysqlCondi(rechargeInfoSql), models.LinkMysqlCondi(cashSql))
@ -126,7 +126,7 @@ func GetGameUserList(c *gin.Context) {
// 拉列表语句
sql := `SELECT a.id as UID,a.channel_id as ChannelID,a.country as Country,c.level as Level,a.mobile as Mobile,b.up1 as Up,a.status as Status,
a.platform as Platform,a.online as Online,d.total_recharge as TotalRecharge,d.total_recharge_count as TotalRechargeCount,d.total_withdraw as TotalWithdraw,
d.total_withdraw_count as TotalWithdrawCount,e.brl as Brl,d.diff as Diff,a.last_login as LastLogin,a.birth as Birth,a.tag as Tag From ` + baseSql
d.total_withdraw_count as TotalWithdrawCount,e.inr as Brl,d.diff as Diff,a.last_login as LastLogin,a.birth as Birth,a.tag as Tag From ` + baseSql
// 求和语句
sqlCount := `SELECT count(*) From ` + baseSql
@ -143,7 +143,7 @@ func GetGameUserList(c *gin.Context) {
case 3:
orderSql += " d.total_withdraw"
case 4:
orderSql += " e.brl"
orderSql += " e.inr"
case 5:
orderSql += " d.diff"
case 6:

@ -14,4 +14,5 @@ func common(e *gin.Engine) {
e.GET("/common/userInfo", handler.UserInfo)
// e.GET("/common/getGameInfo", handler.GameInfo)
e.GET("/common/accountList", handler.AccountList)
e.POST("/common/uploadOSS", handler.UploadOSS)
}

@ -264,3 +264,15 @@ type UserInfoResp struct {
type AccountListResp struct {
List []string
}
type UploadOSSReq struct {
Endpoint string
AccessKeyId string
AccessKeySecret string
BucketName string
ObjectName string
}
type UploadOSSResp struct {
Url string
}

@ -5,8 +5,11 @@ import (
"server/common"
"server/db"
"server/modules/web/values"
"server/util"
"sort"
"time"
"github.com/liangdas/mqant/log"
)
// 从数据库中读取数据
@ -24,6 +27,7 @@ func (g *Gin) CheckActivityExpire(id int) (pass bool) {
return
}
// GetUserTaskStatus 获取任务状态
func (a *Gin) GetUserTaskStatus() (ret []*values.OneTask) {
tasks := call.GetConfigTask()
for _, v := range tasks {
@ -33,49 +37,47 @@ func (a *Gin) GetUserTaskStatus() (ret []*values.OneTask) {
Target: v.Target,
Reward: v.Reward,
Kind: v.Kind,
Type: v.Type,
Type: int(v.Type),
Icon: v.Icon,
Title: common.GetTaskTitle(v),
Action: v.Action,
}
// 非次数任务,需转换目标数值
if !common.IsNumTaskType(v.Type) {
one.Target /= common.DecimalDigits
}
// if !common.IsNumTaskType(v.Type) {
// one.Target /= common.DecimalDigits
// }
ret = append(ret, one)
}
if a.UID <= 0 {
return
}
now := time.Now()
task := call.GetUserTaskData(a.UID)
now := time.Now().Unix()
for _, v := range ret {
tag := false
for _, k := range task {
if v.TaskID == k.TaskID {
v.Progess = k.Progress
tag = true
break
}
}
if !tag {
if v.Type == common.TaskTypeRegist { // 已注册且注册任务还没标记完成
db.Mysql().Create(&common.TaskData{UID: a.UID, TaskID: v.TaskID, Progress: v.Target, Time: now})
v.Progess = v.Target
} else if v.Type == common.TaskTypeDownload { // 已下载直接标记为完成
if a.DeviceType == common.DeviceTypeWebview || a.DeviceType == common.DeviceTypePWA {
db.Mysql().Create(&common.TaskData{UID: a.UID, TaskID: v.TaskID, Progress: v.Target, Time: now})
v.Progess = v.Target
taskTime := time.Unix(k.Time, 0)
// 跨天清空数据
if !util.IsSameDay(now, taskTime) {
v.Status = 0
v.Progess = 0
err := db.Mysql().Update(&k, map[string]interface{}{
"status": 0,
"progress": 0,
"time": now.Unix(),
})
if err != nil {
log.Error("GetUserTaskStatus err:%v", err)
}
}
break
}
}
// 非次数任务,需转换目标数值
if !common.IsNumTaskType(v.Type) && v.Progess > 0 {
v.Progess /= common.DecimalDigits
}
// if !common.IsNumTaskType(v.Type) && v.Progess > 0 {
// v.Progess /= common.DecimalDigits
// }
if v.Progess < 0 {
v.Progess = v.Target
v.Status = 2
@ -87,14 +89,5 @@ func (a *Gin) GetUserTaskStatus() (ret []*values.OneTask) {
sort.SliceStable(ret, func(i, j int) bool {
return ret[i].Status > ret[j].Status
})
// 完成的任务隐藏
index := 0
for i := range ret {
if ret[i].Status != 2 {
index = i
break
}
}
ret = ret[index:]
return
}

@ -453,8 +453,14 @@ func ActivityFreeSpinInfo(c *gin.Context) {
// data.LastSpin = now
// }
db.Mysql().Create(data)
resp.Count = data.SpinNum
} else if !util.IsSameDayTimeStamp(time.Now().Unix(), freeSpin.LastSpin) {
resp.Count = common.DefaultFreeSpinNum
_, err := db.Mysql().UpdateRes(&common.ActivityFreeSpinData{UID: a.UID, LastSpin: freeSpin.LastSpin},
map[string]interface{}{"spin_num": common.DefaultFreeSpinNum})
if err != nil {
log.Error("ActivityFreeSpinInfo err:%v", err)
}
} else {
resp.Count = freeSpin.SpinNum
}
@ -472,8 +478,7 @@ func ActivityFreeSpinDraw(c *gin.Context) {
return
}
freeSpin := call.GetUserFreeSpinData(a.UID)
now := time.Now().Unix()
if util.IsSameDayTimeStamp(now, freeSpin.LastSpin) && freeSpin.SpinNum <= 0 {
if freeSpin.SpinNum <= 0 {
a.Code = values.CodeRetry
return
}

@ -1,8 +1,9 @@
package handler
import (
"context"
"errors"
"fmt"
"math/rand"
"server/call"
"server/common"
"server/db"
@ -13,6 +14,8 @@ import (
"time"
"github.com/gin-gonic/gin"
"github.com/go-redis/redis/v8"
"github.com/liangdas/mqant/log"
"github.com/olivere/elastic/v7"
)
@ -80,15 +83,84 @@ func FirstPage(c *gin.Context) {
if len(list) > 0 {
resp.Esport = list[0]
}
task := call.GetConfigTaskByTaskType(common.TaskTypeDownload)
if len(task) > 0 {
resp.DownloadAppReward = task[0].Reward
// task := call.GetConfigTaskByTaskType(common.TaskTypeDownload)
// if len(task) > 0 {
// resp.DownloadAppReward = task[0].Reward
// }
resp.ShowData = GetFirstShowData()
}
// GetFirstShowData 首页展示数据
func GetFirstShowData() values.ShowInfo {
ctx := context.Background()
// step: 平均提现时长
now := time.Now()
currentHour := now.Format("2006-01-02-15") // 年-月-日-小时
rdb := db.Redis().GetRedis()
pipeline := db.Redis().GetRedis().Pipeline()
keyPrefix := "firstpage:showdata:"
// 使用哈希存储平均提现时长
key := keyPrefix + "average_withdrawal_time:" + currentHour
averageWithdrawalTime, err := rdb.HGet(ctx, key, "value").Int64()
if errors.Is(err, redis.Nil) {
averageWithdrawalTime = util.RandBetween64(15, 30) // 15-30之间
pipeline.HSet(ctx, key, "value", averageWithdrawalTime)
pipeline.Expire(ctx, key, time.Hour) // 设置过期时间为1小时
}
// step: 今日平台提现总额
withdrawalKey := keyPrefix + "withdrawal_info"
startTime, err := rdb.HGet(ctx, withdrawalKey, "start_time").Time()
withdrawal := int64(999*10 + 1000)
if err != nil || now.Day() != startTime.Day() {
startTime = now
pipeline.HSet(ctx, withdrawalKey, "start_time", startTime)
pipeline.HSet(ctx, withdrawalKey, "total_withdrawal", withdrawal)
} else {
elapsed := int(now.Sub(startTime).Hours())
withdrawal = int64(elapsed * (999*10 + 1000))
pipeline.HSet(ctx, withdrawalKey, "total_withdrawal", withdrawal)
}
resp.ShowData = values.ShowInfo{
Reward: rand.Int63n(1000000),
AverWithdraw: rand.Int63n(1000000),
MaxBet: rand.Int63n(1000000),
WithdrawCount: rand.Int63n(1000000),
// step: 当前累计奖金
bonusKey := keyPrefix + "bonus_info"
totalBonus, err := rdb.HGet(ctx, bonusKey, "total_bonus").Int64()
if errors.Is(err, redis.Nil) {
totalBonus = 1549661
pipeline.HSet(ctx, bonusKey, "total_bonus", totalBonus)
pipeline.HSet(ctx, bonusKey, "last_bonus_update_time", now)
} else {
lastUpdate, _ := rdb.HGet(ctx, bonusKey, "last_bonus_update_time").Time()
intervals := (now.Unix() - lastUpdate.Unix()) / 10
totalBonus += util.RandBetween64(10, 2000) * intervals
pipeline.HSet(ctx, bonusKey, "total_bonus", totalBonus)
pipeline.HSet(ctx, bonusKey, "last_bonus_update_time", now)
}
// step: 下注总额
maxBetKey := keyPrefix + "max_bet_info"
maxBetStartTime, err := rdb.HGet(ctx, maxBetKey, "start_time").Time()
maxBet := int64(500)
if err != nil || now.Sub(maxBetStartTime) > 24*time.Hour {
maxBetStartTime = now
pipeline.HSet(ctx, maxBetKey, "start_time", maxBetStartTime)
pipeline.HSet(ctx, maxBetKey, "max_bet_amount", maxBet)
} else {
elapsed := now.Sub(startTime).Minutes() / 10 * 3
maxBet = int64(500 * elapsed)
pipeline.HSet(ctx, maxBetKey, "max_bet_amount", maxBet)
}
// 执行Pipeline
_, err = pipeline.Exec(ctx)
if err != nil {
log.Error("Pipeline exec error: %v", err)
}
// 返回结果
return values.ShowInfo{
AverWithdraw: averageWithdrawalTime,
WithdrawCount: withdrawal,
Reward: totalBonus * 100,
MaxBet: maxBet * 100,
}
}

@ -29,8 +29,16 @@ func GameList(c *gin.Context) {
resp := &values.GameListResp{Provider: req.Provider}
a.Data = resp
var list, tmp []*common.ConfigGameList
if req.Provider == -1 {
req.Provider = 0
}
if req.Mark == -1 {
req.Mark = 0
}
if req.Type == -1 || req.Type == 1 {
req.Type = 0
}
tmp = call.GetConfigGameList(0, req.Provider, req.Mark, req.Type)
if len(req.Name) > 0 {
reqName := strings.ToLower(req.Name)
for _, v := range tmp {

@ -84,6 +84,12 @@ func ShareInfo(c *gin.Context) {
channel := call.GetChannelByID(a.Channel)
if channel != nil {
resp.ShareLink += channel.URL + "?code=" + "xxxxxx"
if a.Prefix != "" {
resp.ShareLink = a.Prefix + "." + resp.ShareLink
} else {
resp.ShareLink = "www." + resp.ShareLink
}
resp.ShareLink = "https://" + resp.ShareLink
}
a.GetUID()
if a.UID <= 0 {
@ -105,6 +111,7 @@ func ShareInfo(c *gin.Context) {
} else {
resp.ShareLink = "www." + resp.ShareLink
}
resp.ShareLink = "https://" + resp.ShareLink
}
}

@ -93,6 +93,9 @@ func GetVipInfo(c *gin.Context) {
resp.NextCashback = util.GetNext5MinUnix() - now.Unix()
}
}
if resp.Info.Cashback < 0 {
resp.Info.Cashback = 0
}
resp.CashbackList = []common.CurrencyBalance{}
q := elastic.NewBoolQuery()
q.Filter(elastic.NewTermQuery("uid", a.UID))

@ -183,7 +183,7 @@ func PlayerWithdrawBlock(c *gin.Context) {
}
}
orderID := "USDT" + util.NewOrderID(int(uid))
orderID := "USDT" + util.NewOrderID(uid)
// 第一步,先扣钱
err := call.MineCurrencyProReal(&common.UpdateCurrency{
CurrencyBalance: &common.CurrencyBalance{
@ -210,7 +210,7 @@ func PlayerWithdrawBlock(c *gin.Context) {
}
order := &common.WithdrawOrder{
UID: int(uid),
UID: uid,
OrderID: orderID,
APIPayID: "",
// ProductID: one.ID,
@ -329,7 +329,7 @@ func PlayerWithdraw(c *gin.Context) {
}
}
orderID := util.NewOrderID(int(uid))
orderID := util.NewOrderID(uid)
// 第一步,先扣钱
pro := call.MineCurrencyProReal(&common.UpdateCurrency{
CurrencyBalance: &common.CurrencyBalance{
@ -350,7 +350,7 @@ func PlayerWithdraw(c *gin.Context) {
con := call.GetVipCon(uid)
realAmount := need // 实际打款
if con != nil && con.Fee > 0 {
realAmount = common.RoundCurrency(req.CurrencyType, con.Fee) * realAmount
realAmount = common.RoundCurrency(req.CurrencyType, (1000-int64(con.Fee))*realAmount/1000)
}
var shouldAuto = false
@ -371,7 +371,7 @@ func PlayerWithdraw(c *gin.Context) {
}
order := &common.WithdrawOrder{
UID: int(uid),
UID: uid,
OrderID: orderID,
APIPayID: "",
// ProductID: one.ID,
@ -414,6 +414,7 @@ func NewWithdraw(req *values.WithdrawReq, uid int, ip string, uuid string) (stri
log.Error("NewWithdrawImp err:%v,one:%+v", err, one)
return "", values.CodeParam
}
one.PayType = common.PayTypeBank
if one.PayType == common.PayTypeUPI {
return "The UPI channel is closed, please use the bank channel to withdraw cash.", values.CodeParam
}

@ -1,6 +1,9 @@
package values
import "server/common"
import (
"server/common"
"time"
)
// GameNum 子项游戏请求个数
type FirstPageReq struct {
@ -20,10 +23,14 @@ type FirstPageResp struct {
}
type ShowInfo struct {
Reward int64 // 奖金
AverWithdraw int64 // 平均提现市场
MaxBet int64 // 今日最大下注
WithdrawCount int64 // 今日提现总额
Reward int64 `redis:"Reward"` // 奖金
RewardTime time.Time `redis:"RewardTime"`
AverWithdraw int64 `redis:"AverWithdraw"` // 平均提现时间
AverWithdrawTime time.Time `redis:"AverWithdrawTime"`
MaxBet int64 `redis:"MaxBet"` // 今日最大下注
MaxBetTime time.Time `redis:"MaxBetTime"`
WithdrawCount int64 `redis:"WithdrawCount"` // 今日提现总额
WithdrawCountTime int64 `redis:"WithdrawCountTime"`
}
type OneCurrency struct {
ID common.CurrencyType

@ -28,6 +28,7 @@ type ShareInfoResp struct {
PlatformBetReward int64
PlatformTotalReward int64
Rank []*OneShareRank
Msg string // 后台配置消息
}
type SharePlatformResp struct {

@ -844,3 +844,124 @@ func RandomOneEleFromSlice(slice interface{}, name string) int {
}
return 0
}
func RandBetween64(min, max int64) int64 {
return rand.Int63n(max-min+1) + min
}
func RandBetween(min, max int) int {
return rand.Intn(max-min+1) + min
}
// HashMarshal 用于将结构体序列化为Redis哈希
func HashMarshal(v interface{}) (map[string]interface{}, error) {
result := make(map[string]interface{})
vType := reflect.TypeOf(v)
vValue := reflect.ValueOf(v)
if vType.Kind() != reflect.Struct {
return nil, fmt.Errorf("HashMarshal: expected a struct type, got %v", vType.Kind())
}
for i := 0; i < vType.NumField(); i++ {
field := vType.Field(i)
fieldValue := vValue.Field(i)
redisTag := field.Tag.Get("redis")
if redisTag == "" || redisTag == "-" {
continue
}
var value interface{}
switch fieldValue.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
value = fieldValue.Int()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
value = fieldValue.Uint()
case reflect.Float32, reflect.Float64:
value = fieldValue.Float()
case reflect.String:
value = fieldValue.String()
case reflect.Bool:
value = fieldValue.Bool()
case reflect.Struct:
if t, ok := fieldValue.Interface().(time.Time); ok {
value = t.Format(time.RFC3339)
} else {
return nil, fmt.Errorf("HashMarshal: unsupported struct type %v for field %s", fieldValue.Kind(), field.Name)
}
default:
return nil, fmt.Errorf("HashMarshal: unsupported type %v for field %s", fieldValue.Kind(), field.Name)
}
result[redisTag] = value
}
return result, nil
}
// HashUnmarshal 用于从Redis哈希反序列化为结构体
func HashUnmarshal(data map[string]string, v interface{}) error {
vType := reflect.TypeOf(v).Elem()
vValue := reflect.ValueOf(v).Elem()
if vType.Kind() != reflect.Struct {
return fmt.Errorf("HashUnmarshal: expected a struct type, got %v", vType.Kind())
}
for i := 0; i < vType.NumField(); i++ {
field := vType.Field(i)
fieldValue := vValue.Field(i)
redisTag := field.Tag.Get("redis")
if redisTag == "" || redisTag == "-" {
continue
}
strValue, ok := data[redisTag]
if !ok {
continue
}
switch fieldValue.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
intValue, err := strconv.ParseInt(strValue, 10, 64)
if err != nil {
return err
}
fieldValue.SetInt(intValue)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
uintValue, err := strconv.ParseUint(strValue, 10, 64)
if err != nil {
return err
}
fieldValue.SetUint(uintValue)
case reflect.Float32, reflect.Float64:
floatValue, err := strconv.ParseFloat(strValue, 64)
if err != nil {
return err
}
fieldValue.SetFloat(floatValue)
case reflect.String:
fieldValue.SetString(strValue)
case reflect.Bool:
boolValue, err := strconv.ParseBool(strValue)
if err != nil {
return err
}
fieldValue.SetBool(boolValue)
case reflect.Struct:
if fieldValue.Type() == reflect.TypeOf(time.Time{}) {
t, err := time.Parse(time.RFC3339, strValue)
if err != nil {
return err
}
fieldValue.Set(reflect.ValueOf(t))
} else {
return fmt.Errorf("HashUnmarshal: unsupported struct type %v for field %s", fieldValue.Kind(), field.Name)
}
default:
return fmt.Errorf("HashUnmarshal: unsupported type %v for field %s", fieldValue.Kind(), field.Name)
}
}
return nil
}

Loading…
Cancel
Save