commit
4403d9284c
448 changed files with 59020 additions and 0 deletions
@ -0,0 +1,27 @@ |
||||
# Binaries for programs and plugins |
||||
*.exe |
||||
*.exe~ |
||||
*.dll |
||||
*.so |
||||
*.dylib |
||||
*.log |
||||
.vs/ |
||||
|
||||
# Test binary, built with `go test -c` |
||||
*.test |
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE |
||||
*.out |
||||
|
||||
# Dependency directories (remove the comment below to include it) |
||||
# vendor/ |
||||
|
||||
.idea |
||||
|
||||
*test* |
||||
|
||||
/pb/*.pb.go |
||||
/docs/backend/swagger.json |
||||
/docs/web/swagger.json |
||||
|
||||
gameserver* |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=5000 |
||||
MaxPlayerCount=10000 |
||||
[Andarbahar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game5000":[ |
||||
{ |
||||
"Id":"game5000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,10 @@ |
||||
[Backend] |
||||
Addr=":7616" |
||||
Release=false |
||||
DB="root:d47a98e748ccaf1f@tcp(172.105.117.6: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"] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"backend":[ |
||||
{ |
||||
"Id":"backend001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,59 @@ |
||||
[net] |
||||
registry="127.0.0.1:8500" # consul 地址 |
||||
nats="nats://127.0.0.1:4222" # nats地址 |
||||
|
||||
[redis] |
||||
addr="127.0.0.1:6379" |
||||
name="" |
||||
passwd="" |
||||
tls=false |
||||
db=0 |
||||
cluster=false |
||||
|
||||
[es] |
||||
#urls=["http://127.0.0.1:9200"] |
||||
urls=["http://elastic:joyyu7XRwlpJtXFEIw80@47.112.119.250: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" |
||||
debug=true |
||||
|
||||
[facebook] |
||||
prefix="fb" |
||||
appKey="" |
||||
appSecret="" |
||||
authURL="https://graph.facebook.com" |
||||
|
||||
[google] |
||||
prefix="gp" |
||||
authURL="oauth2.googleapis.com/tokeninfo?id_token=" |
||||
|
||||
[common] |
||||
savePicPath="" |
||||
avatarURL="" |
||||
|
||||
[server] |
||||
IsExamine=true |
||||
ExamineURL="172.105.117.6:7615" |
||||
GameURL="172.105.117.6:7615" |
||||
|
||||
[warn] |
||||
URL = "http://smsapi.5taogame.com/sms/httpSmsInterface2" |
||||
ID = "xlk168888" |
||||
Account = "xlk168888" |
||||
Password = "xlk168888" |
||||
Sign = "【章鱼游戏】" |
||||
Action = "sendhy" |
||||
|
||||
[mails] |
||||
Accounts = ["lila48w4@gmail.com"] |
||||
Pass = ["eqqpmbabzihirygu"] |
||||
|
||||
[newPacks] |
||||
PIDs = [117,116,102,157,121,141,162] |
||||
|
||||
[ad] |
||||
FBAPIURL = "https://graph.facebook.com/v18.0/" |
||||
KwaiAPIURL = "http://www.adsnebula.com/log/common/api" |
||||
@ -0,0 +1,2 @@ |
||||
WorkID=9000 |
||||
MaxPlayerCount=10000 |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game9000":[ |
||||
{ |
||||
"Id":"game9000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
[BlockPay] |
||||
[BlockPay.Tron] |
||||
Addrs = [] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"blockpay":[ |
||||
{ |
||||
"Id":"blockpay001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,2 @@ |
||||
WorkID=16000 |
||||
MaxPlayerCount=10000 |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game16000":[ |
||||
{ |
||||
"Id":"game16000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,2 @@ |
||||
WorkID=1 |
||||
Release=true |
||||
@ -0,0 +1,18 @@ |
||||
{ |
||||
"Module":{ |
||||
"common":[ |
||||
{ |
||||
"Id":"common001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,4 @@ |
||||
[Customer] |
||||
Addr=":9616" |
||||
Release=false |
||||
DB="root:d9JaXnG5QuuZLIrY@tcp(47.112.119.250:3306)/customer" |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"customer":[ |
||||
{ |
||||
"Id":"customer001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=8000 |
||||
MaxPlayerCount=10000 |
||||
[Dragon] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game8000":[ |
||||
{ |
||||
"Id":"game8000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,2 @@ |
||||
WorkID=15000 |
||||
MaxPlayerCount=10000 |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game15000":[ |
||||
{ |
||||
"Id":"game15000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,8 @@ |
||||
[Gate] |
||||
WSAddr="172.105.117.6" |
||||
WSPort=":6615" |
||||
HeartBeat=20 |
||||
BufSize=4096 |
||||
TLS=false |
||||
cert_file="" |
||||
key_file="" |
||||
@ -0,0 +1,18 @@ |
||||
{ |
||||
"Module":{ |
||||
"gate":[ |
||||
{ |
||||
"Id":"gate001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,8 @@ |
||||
[Hall] |
||||
AvatarURL="" |
||||
SavePath="" |
||||
[Hall.FacebookParams] |
||||
Prefix="" |
||||
AppKey="" |
||||
AppScrect="" |
||||
AuthURL="" |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"hall":[ |
||||
{ |
||||
"Id":"hall001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=10000 |
||||
MaxPlayerCount=10000 |
||||
[Andarbahar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game10000":[ |
||||
{ |
||||
"Id":"game10000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
Binary file not shown.
@ -0,0 +1,3 @@ |
||||
WorkID=11000 |
||||
MaxPlayerCount=10000 |
||||
[JhandiMunda] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game11000":[ |
||||
{ |
||||
"Id":"game11000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1 @@ |
||||
WorkID=1 |
||||
@ -0,0 +1,18 @@ |
||||
{ |
||||
"Module":{ |
||||
"matching":[ |
||||
{ |
||||
"Id":"matching001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,31 @@ |
||||
[Pay] |
||||
Addr=":8615" |
||||
Release=true |
||||
TLS=false |
||||
CertFile="" |
||||
KeyFile="" |
||||
CallbackURL = "http://47.112.119.250" |
||||
CheckLimit = 20 |
||||
RootChannel = [12,14] |
||||
SelectPayWay = true |
||||
PayCheckTime = 2 |
||||
PayFailWeight = 20 |
||||
PaySuccessWeight = 50 |
||||
BaseSuccess = 10 |
||||
WithdrawScanTime = 10 |
||||
[Pay.IGeek] |
||||
APIURL = "http://api.test.igeekpay.com/gateway" |
||||
APPID = "H4RIKR" |
||||
MID = "RSRV686X" |
||||
Key = "2YHPVB8DZKTALVVI" |
||||
[Web.Adjust] |
||||
URL = "https://s2s.adjust.com/event" |
||||
APIURL = "https://api.adjust.com/device_service/api/v1/inspect_device" |
||||
APIToken = "_2ZGYezfdZ7yD2he-zWx" |
||||
[Pay.BestPay] |
||||
APIURL = "https://very.goodrummy.co.in" |
||||
[Pay.GrePay] |
||||
Key = "" |
||||
WithdrawAccount = "" |
||||
MIDAmount = 3000 |
||||
BigChannel = "0452" |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"pay":[ |
||||
{ |
||||
"Id":"pay001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,4 @@ |
||||
WorkID=22000 |
||||
MaxPlayerCount=10000 |
||||
[Rummy] |
||||
SettleTime=3 |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game22000":[ |
||||
{ |
||||
"Id":"game22000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=6000 |
||||
MaxPlayerCount=10000 |
||||
[Seven] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game6000":[ |
||||
{ |
||||
"Id":"game6000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=18000 |
||||
MaxPlayerCount=10000 |
||||
[TeenpattiWar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game18000":[ |
||||
{ |
||||
"Id":"game18000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=58000 |
||||
MaxPlayerCount=10000 |
||||
[TeenpattiWar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game58000":[ |
||||
{ |
||||
"Id":"game58000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=53000 |
||||
MaxPlayerCount=10000 |
||||
[TeenpattiWar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game53000":[ |
||||
{ |
||||
"Id":"game53000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=50000 |
||||
MaxPlayerCount=10000 |
||||
[TeenpattiWar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game50000":[ |
||||
{ |
||||
"Id":"game50000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=55000 |
||||
MaxPlayerCount=10000 |
||||
[TeenpattiWar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game55000":[ |
||||
{ |
||||
"Id":"game55000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=52000 |
||||
MaxPlayerCount=10000 |
||||
[TeenpattiWar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game52000":[ |
||||
{ |
||||
"Id":"game52000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=56000 |
||||
MaxPlayerCount=10000 |
||||
[TeenpattiWar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game56000":[ |
||||
{ |
||||
"Id":"game56000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=57000 |
||||
MaxPlayerCount=10000 |
||||
[TeenpattiWar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game57000":[ |
||||
{ |
||||
"Id":"game57000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=51000 |
||||
MaxPlayerCount=10000 |
||||
[TeenpattiWar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game51000":[ |
||||
{ |
||||
"Id":"game51000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
WorkID=54000 |
||||
MaxPlayerCount=10000 |
||||
[TeenpattiWar] |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"game54000":[ |
||||
{ |
||||
"Id":"game54000001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,39 @@ |
||||
[Web] |
||||
Addr=":7615" |
||||
Release=true |
||||
TLS=false |
||||
CertFile="" |
||||
KeyFile="" |
||||
MaxPlayerAccountIP=2 |
||||
MaxBankCardCount=1 |
||||
PassRegion=["阿萨姆","奥里萨","锡金","那加兰","特伦甘纳","泰米尔纳德"] |
||||
BlackRegion=["马哈拉施特拉"] |
||||
IFSCURL="https://ifsc.razorpay.com" |
||||
TestWithdraw=-1 |
||||
TestPay=3 |
||||
FetchTime = 60 |
||||
OldChannels = [] |
||||
FreeSpinFirst = 500000000 |
||||
TotalWithdrawPer = 50 |
||||
BreakLimit = 100000000 |
||||
SelectID = 2 |
||||
[Web.OTP] |
||||
AntgstSmsReqURL="https://api.antgst.com/sms/txt/3/send/json" |
||||
AntgstAccessKey="5ac944dc65924f3dbfa1da2556a0f91b" |
||||
AntgstAccessSecret="f35a5d8b324d43a9be629a1f0dc62604" |
||||
AntgstModel="[TERFTE] Your OTP is {%v}. Valid for only 10 minutes." |
||||
AliSmsReqURL="http://smsapi.5taogame.com/sms/httpSmsInterface?action=sendhy" |
||||
AliSmsAccount="zygj6688" |
||||
AliSmsPass="zygj6688" |
||||
AliSmsModel="【Rummy Gold Mango】Your Verification code is %v.The verification code is valid within %v minutes.Don't share it to other people." |
||||
BukaUrl = "https://api.onbuka.com/v3/sendSms" |
||||
BukaAppID = "7g8gVTyL" |
||||
BukaAPIKey = "KFN1IKOd" |
||||
BukaAPISecret = "hX80mNh2" |
||||
BukaModel="Your Verification code is %v." |
||||
[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/" |
||||
@ -0,0 +1,29 @@ |
||||
{ |
||||
"Module":{ |
||||
"web":[ |
||||
{ |
||||
"Id":"web001", |
||||
"ProcessID":"development" |
||||
} |
||||
] |
||||
}, |
||||
"Mqtt":{ |
||||
"WirteLoopChanNum": 10, |
||||
"ReadPackLoop": 1, |
||||
"ReadTimeout": 60, |
||||
"WriteTimeout": 60 |
||||
}, |
||||
"Rpc":{ |
||||
"MaxCoroutine":10000, |
||||
"RpcExpired": 1, |
||||
"LogSuccess":false |
||||
}, |
||||
"Log": { |
||||
"file":{ |
||||
"daily":true, |
||||
"level":7, |
||||
"maxsize":1024000000, |
||||
"maxlines":10000000 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,103 @@ |
||||
#!/bin/bash |
||||
|
||||
#nohup ./gameserver-blitz21 -module=conf/modules.json -log=logs/ -conf=conf/config.json -rule=conf/rule.toml >/dev/null 2>&1 & |
||||
|
||||
#nohup ./gameserver -module=conf/blitz21/modules.json -log=logs/blitz21 -conf=conf/blitz21/config.json -rule=conf/blitz21/rule.toml >/dev/null 2>&1 & |
||||
|
||||
#source ./stop.sh |
||||
|
||||
echo "start gameserver..." |
||||
|
||||
if [[ $# -gt 0 ]] |
||||
then |
||||
echo "stop $1..." |
||||
for f in `ls conf/$1` |
||||
do |
||||
if [[ $f =~ ^gameserver ]] |
||||
then |
||||
array=(`echo $f | tr '.' ' '` ) |
||||
echo "stop $array" |
||||
tmp=$(ps -ef | grep $array | grep -v "grep" | awk '{print $2}') |
||||
#echo $tmp |
||||
if [ "$tmp" = "" ];then |
||||
echo "$array not running" |
||||
else |
||||
kill $tmp |
||||
fi |
||||
break |
||||
fi |
||||
done |
||||
#source ./stop.sh $1 |
||||
|
||||
cp gameserver gameserver-$1 |
||||
mv gameserver-$1 conf/$1 |
||||
echo "start $1..." |
||||
tmp="-log=../../logs/$1 -baseConf=../baseConf.toml -debug=true" |
||||
for c in `ls conf/$1` |
||||
do |
||||
if [[ $c =~ ^gameserver ]] |
||||
then continue |
||||
fi |
||||
|
||||
array=(`echo $c | tr '.' ' '` ) |
||||
#echo $array |
||||
if [[ ${#array[@]} -ne 2 ]] || [[ $c =~ ^ip ]] |
||||
then continue |
||||
fi |
||||
|
||||
tmp="$tmp -$array=$c" |
||||
#echo $tmp |
||||
done |
||||
echo $tmp |
||||
cd conf/$1 |
||||
nohup ./gameserver-$1 $tmp >/dev/null 2>&1 & |
||||
exit 0 |
||||
fi |
||||
|
||||
source ./stop.sh |
||||
#cd conf/ |
||||
for f in `ls conf` |
||||
do |
||||
#echo "start $f..." |
||||
if [[ $f =~ ^_ ]] || [[ $f = *.toml ]] || [[ -f $f ]] || [[ $f = *.db ]] |
||||
then |
||||
echo "pass $f..." |
||||
continue |
||||
fi |
||||
echo "start $f..." |
||||
cp gameserver gameserver-$f |
||||
mv gameserver-$f conf/$f |
||||
|
||||
tmp="-log=../../logs/$f -baseConf=../baseConf.toml -debug=true" |
||||
for c in `ls conf/$f` |
||||
do |
||||
if [[ $c =~ ^gameserver|bi ]] |
||||
then continue |
||||
fi |
||||
array=(`echo $c | tr '.' ' '` ) |
||||
#echo $array |
||||
if [[ ${#array[@]} -ne 2 ]] || [[ $c =~ ^ip ]] |
||||
then continue |
||||
fi |
||||
tmp="$tmp -$array=$c" |
||||
#echo $tmp |
||||
done |
||||
#echo $tmp |
||||
#tmp="-module=conf/$f/modules.json -log=logs/$f -conf=conf/$f/config.json -rule=conf/$f/rule.toml" |
||||
#mv gameserver gameserver1 |
||||
#nohup ./gameserver -module=conf/$f/modules.json -log=logs/$f -conf=conf/$f/config.json -rule=conf/$f/rule.toml >/dev/null 2>&1 & |
||||
cd conf/$f |
||||
nohup ./gameserver-$f $tmp >/dev/null 2>&1 & |
||||
cd ../../ |
||||
done |
||||
|
||||
#for f in `ls` |
||||
#do |
||||
# if [[ $f =~ ^arena.*(.exe)?$ && -x $f ]] |
||||
# then |
||||
# echo "start $f" |
||||
# nohup ./$f -module=conf/modules.json -log=logs/ -conf=conf/config.json -rule=conf/rule.toml >/dev/null 2>&1 & |
||||
# fi |
||||
#done |
||||
|
||||
echo 'finish ...' |
||||
@ -0,0 +1,46 @@ |
||||
#!/bin/bash |
||||
|
||||
echo 'stop server...' |
||||
|
||||
if [[ $# -gt 0 ]] |
||||
then |
||||
echo "stop $1..." |
||||
for f in `ls conf/$1` |
||||
do |
||||
if [[ $f =~ ^gameserver ]] |
||||
then |
||||
array=(`echo $f | tr '.' ' '` ) |
||||
#echo $array |
||||
echo "stop $array" |
||||
tmp=$(ps -ef | grep $array | grep -v "grep" | awk '{print $2}') |
||||
#echo $tmp |
||||
if [ "$tmp" = "" ];then |
||||
echo "$array not running" |
||||
else |
||||
kill $tmp |
||||
fi |
||||
break |
||||
fi |
||||
done |
||||
exit 0 |
||||
fi |
||||
|
||||
for f in `ls` |
||||
do |
||||
if [[ $f =~ ^.*robot(.exe)?|gameserver.*(.exe)?$ && -x $f ]] |
||||
then |
||||
array=(`echo $f | tr '.' ' '` ) |
||||
echo "stop $array" |
||||
tmp=$(ps -ef | grep $array | grep -v "grep" | awk '{print $2}') |
||||
#echo $tmp |
||||
if [ "$tmp" = "" ];then |
||||
echo "$array not running" |
||||
else |
||||
kill $tmp |
||||
fi |
||||
fi |
||||
done |
||||
|
||||
#ps -ef | grep "gateway_server\ -port" | grep -v "grep" | awk '{print $2}' | xargs kill -9 |
||||
|
||||
echo 'stop ok' |
||||
@ -0,0 +1,9 @@ |
||||
#!/bin/bash |
||||
set -e |
||||
cd pb/proto |
||||
./gener.sh |
||||
# cd ../../ |
||||
# cd tools |
||||
# go generate |
||||
cd ../.. |
||||
go build main.go |
||||
@ -0,0 +1,22 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"github.com/bwmarrin/snowflake" |
||||
) |
||||
|
||||
var ( |
||||
snowNode *snowflake.Node |
||||
) |
||||
|
||||
func NewSnowflake(id int64) { |
||||
id = id % 1023 |
||||
var err error |
||||
snowNode, err = snowflake.NewNode(id) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
} |
||||
|
||||
func SnowNode() *snowflake.Node { |
||||
return snowNode |
||||
} |
||||
@ -0,0 +1,328 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"fmt" |
||||
"server/common" |
||||
"server/config" |
||||
"server/db" |
||||
"server/pb" |
||||
"server/util" |
||||
"time" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
"github.com/olivere/elastic/v7" |
||||
"gorm.io/gorm" |
||||
) |
||||
|
||||
func IsActivityValid(actID int) bool { |
||||
act := GetConfigActivityByID(actID) |
||||
if act == nil { |
||||
return false |
||||
} |
||||
return act.IsValid() |
||||
} |
||||
|
||||
// NotifyActivityItem 通知客户端获得活动物品
|
||||
func NotifyActivityItem(uid, activityID int, items []*pb.ActivityItem) { |
||||
activityNotify := &pb.ActivityResp{ |
||||
ActivityID: int64(activityID), |
||||
ActivityItems: items, |
||||
} |
||||
SendNR(uid, int(pb.ServerCommonResp_CommonActivityItemResp), activityNotify, "common") |
||||
} |
||||
|
||||
func GetAcitivityPddData(uid int) *common.PddData { |
||||
pddData := &common.PddData{UID: uid} |
||||
db.Mysql().Get(pddData) |
||||
con := GetConfigActivityPdd() |
||||
if con == nil { |
||||
return nil |
||||
} |
||||
now := time.Now().Unix() |
||||
if now-pddData.Time < con.Expire*60 { |
||||
// 每天有一次免费旋转
|
||||
if !util.IsSameDayTimeStamp(now, pddData.FreeSpinTime) { |
||||
pddData.Spin++ |
||||
} |
||||
return pddData |
||||
} |
||||
resetSpinCount := 1 |
||||
if !config.GetBase().Release { |
||||
resetSpinCount = 100 |
||||
} |
||||
if pddData.ID == 0 { |
||||
pddData.Time = now |
||||
pddData.Spin = resetSpinCount |
||||
db.Mysql().Create(pddData) |
||||
} else { |
||||
db.Mysql().Update(&common.PddData{UID: pddData.UID, Time: pddData.Time}, |
||||
map[string]interface{}{"amount": 0, "time": now, "Spin": resetSpinCount, "free_spin_time": 0, "new_record_time": 0}) |
||||
pddData.Amount = 0 |
||||
pddData.Time = now |
||||
pddData.Spin = resetSpinCount |
||||
pddData.FreeSpinTime = 0 |
||||
pddData.NewRecordTime = 0 |
||||
} |
||||
return pddData |
||||
} |
||||
|
||||
// 是否有新邀请
|
||||
func HasNewAcitivityPddShare(uid int) bool { |
||||
if !IsActivityValid(common.ActivityIDPDD) { |
||||
return false |
||||
} |
||||
pddData := GetAcitivityPddData(uid) |
||||
if pddData.NewRecordTime <= 0 { |
||||
return false |
||||
} |
||||
q := elastic.NewBoolQuery() |
||||
q.Filter(elastic.NewTermQuery("Referer", uid)) |
||||
q.Filter(elastic.NewRangeQuery("Time").Gte(pddData.NewRecordTime)) |
||||
return db.ES().Count(common.ESIndexBackPddRecord, q) > 0 |
||||
} |
||||
|
||||
func GetUserFreeSpinData(uid int) *common.ActivityFreeSpinData { |
||||
data := &common.ActivityFreeSpinData{UID: uid} |
||||
db.Mysql().Get(data) |
||||
return data |
||||
} |
||||
|
||||
func GetUserFirstRechargeBackData(uid int) *common.ActivityFirstRechargeBackData { |
||||
data := &common.ActivityFirstRechargeBackData{UID: uid} |
||||
db.Mysql().Get(data) |
||||
return data |
||||
} |
||||
|
||||
func ShouldShowActivityFirstRechargeBack(uid int) bool { |
||||
if !IsActivityValid(common.ActivityIDFirstRechargeBack) { |
||||
return false |
||||
} |
||||
if uid == 0 { |
||||
return true |
||||
} |
||||
now := time.Now().Unix() |
||||
data := GetUserFirstRechargeBackData(uid) |
||||
if data.RechargeTime == 0 { |
||||
return true |
||||
} |
||||
if now-data.RechargeTime > 2*common.ActivityFirstRechargeBackTime { |
||||
return false |
||||
} |
||||
if now-data.RechargeTime > common.ActivityFirstRechargeBackTime && data.Lost == 0 { |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
|
||||
func UploadActivityData(uid, activityID, t int, amount int64) { |
||||
db.ES().InsertToESGO(common.ESIndexBackActivity, &common.ESActivity{ |
||||
ActivityID: activityID, |
||||
UID: uid, |
||||
Time: time.Now().Unix(), |
||||
Type: t, |
||||
Amount: amount, |
||||
}) |
||||
} |
||||
|
||||
func ShouldShowActivitySign(uid int) bool { |
||||
if !IsActivityValid(common.ActivityIDSign) { |
||||
return false |
||||
} |
||||
if uid == 0 { |
||||
return true |
||||
} |
||||
p, _ := GetUserXInfo(uid, "birth") |
||||
now := util.GetZeroTime(time.Now()).Unix() |
||||
birth := util.GetZeroTime(time.Unix(p.Birth, 0)).Unix() |
||||
return now-birth <= 6*common.OneDay |
||||
} |
||||
|
||||
func GetUserWeekCard(uid, level int) *common.ActivityWeekCardData { |
||||
data := &common.ActivityWeekCardData{UID: uid, Level: level} |
||||
db.Mysql().Get(data) |
||||
return data |
||||
} |
||||
|
||||
func GetUserWeekCards(uid int) []*common.ActivityWeekCardData { |
||||
list := []*common.ActivityWeekCardData{} |
||||
db.Mysql().QueryAll(fmt.Sprintf("uid = %d", uid), "", &common.ActivityWeekCardData{}, &list) |
||||
return list |
||||
} |
||||
|
||||
func ShouldShowActivityWeekCard(uid int) bool { |
||||
if !IsActivityValid(common.ActivityIDWeekCard) { |
||||
return false |
||||
} |
||||
if uid == 0 { |
||||
return true |
||||
} |
||||
cards := GetUserWeekCards(uid) |
||||
for _, v := range cards { |
||||
if v.Day > 0 { |
||||
return false |
||||
} |
||||
} |
||||
return true |
||||
} |
||||
|
||||
func GetUserActivitySlotsData(uid int) *common.ActivitySlotsData { |
||||
data := &common.ActivitySlotsData{UID: uid} |
||||
db.Mysql().Get(data) |
||||
now := time.Now().Unix() |
||||
isSingle := IsActivitySingleDay(common.ActivityIDSlots) |
||||
t := data.Time2 |
||||
if isSingle { |
||||
t = data.Time1 |
||||
} |
||||
if !util.IsSameDayTimeStamp(now, t) { |
||||
data.Spin = 0 |
||||
} |
||||
if data.ID == 0 { |
||||
if isSingle { |
||||
data.Time1 = now |
||||
} else { |
||||
data.Time2 = now |
||||
} |
||||
p, _ := GetUserXInfo(uid, "mobile", "avatar") |
||||
data.Avatar = p.Avatar |
||||
data.Nick = p.Nick |
||||
db.Mysql().Create(data) |
||||
} |
||||
return data |
||||
} |
||||
|
||||
func UpdateUserActivitySlotsData(uid int, count int) { |
||||
data := &common.ActivitySlotsData{UID: uid} |
||||
db.Mysql().Get(data) |
||||
now := time.Now().Unix() |
||||
isSingle := IsActivitySingleDay(common.ActivityIDSlots) |
||||
if data.ID == 0 { |
||||
if isSingle { |
||||
data.Time1 = now |
||||
} else { |
||||
data.Time2 = now |
||||
} |
||||
data.Spin = count |
||||
db.Mysql().Create(data) |
||||
return |
||||
} |
||||
update := map[string]interface{}{} |
||||
t := data.Time2 |
||||
str := "time2" |
||||
if isSingle { |
||||
t = data.Time1 |
||||
str = "time1" |
||||
} |
||||
if !util.IsSameDayTimeStamp(now, t) { |
||||
update["spin"] = count |
||||
update[str] = now |
||||
} else { |
||||
update["spin"] = gorm.Expr("spin + ?", count) |
||||
} |
||||
log.Debug("UpdateUserActivitySlotsData uid:%v,count:%v,isSingle:%v,update:%v", uid, count, isSingle, update) |
||||
db.Mysql().Update(&common.ActivitySlotsData{UID: uid}, update) |
||||
} |
||||
|
||||
func ShouldShowActivityLuckShop(uid int) bool { |
||||
if !IsActivityValid(common.ActivityIDLuckyShop) { |
||||
return false |
||||
} |
||||
if uid == 0 { |
||||
return true |
||||
} |
||||
return GetShowActivityLuckShopData(uid) != nil |
||||
} |
||||
|
||||
func GetShowActivityLuckShopData(uid int) *common.ActivityLuckyShopData { |
||||
if uid == 0 { |
||||
return nil |
||||
} |
||||
re := GetRechargeInfo(uid) |
||||
if re.TotalRecharge == 0 { |
||||
return nil |
||||
} |
||||
datas := []*common.ActivityLuckyShopData{} |
||||
db.Mysql().QueryAll(fmt.Sprintf("uid = %d", uid), "type asc", &common.ActivityLuckyShopData{}, &datas) |
||||
now := time.Now().Unix() |
||||
// 先判断首充礼包,两种礼包互斥,弹了其中一种,另一种不会弹了
|
||||
var rechargeData *common.ActivityLuckyShopData |
||||
for i, v := range datas { |
||||
if v.Type == common.ActivityLuckyShopTypeRechargeLess || v.Type == common.ActivityLuckyShopTypeRechargeMore { |
||||
rechargeData = datas[i] |
||||
break |
||||
} |
||||
} |
||||
if rechargeData != nil && rechargeData.IsValid() { |
||||
return rechargeData |
||||
} |
||||
|
||||
for i := common.ActivityLuckyShopType + 1; i < common.ActivityLuckyShopTypeAll; i++ { |
||||
// 如果已有首充礼包,那么直接跳过后续判断
|
||||
if rechargeData != nil { |
||||
if i == common.ActivityLuckyShopTypeRechargeLess || i == common.ActivityLuckyShopTypeRechargeMore { |
||||
continue |
||||
} |
||||
} |
||||
con := GetConfigActivityLuckShop(i) |
||||
var tmp *common.ActivityLuckyShopData |
||||
for i, v := range datas { |
||||
if con.Type == v.Type { |
||||
tmp = datas[i] |
||||
break |
||||
} |
||||
} |
||||
if tmp == nil { |
||||
if con.Type == common.ActivityLuckyShopTypeRechargeLess { |
||||
if re.TotalRecharge < con.Recharge { |
||||
return &common.ActivityLuckyShopData{UID: uid, Type: con.Type, Push: now, ProductID: con.ProductID} |
||||
} |
||||
continue |
||||
} |
||||
if con.Type == common.ActivityLuckyShopTypeRechargeMore { |
||||
if re.TotalRecharge >= con.Recharge { |
||||
return &common.ActivityLuckyShopData{UID: uid, Type: con.Type, Push: now, ProductID: con.ProductID} |
||||
} |
||||
continue |
||||
} |
||||
p, _ := GetUserXInfo(uid, "birth") |
||||
tmp := p.Birth + 3*24*3600 |
||||
if util.IsSameDayTimeStamp(now, tmp) || now > tmp { |
||||
return &common.ActivityLuckyShopData{UID: uid, Type: con.Type, Push: now, ProductID: con.ProductID} |
||||
} |
||||
} else if tmp.IsValid() { |
||||
return tmp |
||||
} |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// IsActivitySingleDay 返回活动是否是单数天
|
||||
func IsActivitySingleDay(id int) bool { |
||||
act := GetConfigActivityByID(id) |
||||
if act == nil || !act.IsValid() { |
||||
return false |
||||
} |
||||
// if config.GetBase().Release {
|
||||
diff := int((util.GetZeroTime(time.Now()).Unix() - util.GetZeroTime(time.Unix(act.Start, 0)).Unix()) / (24 * 60 * 60)) |
||||
return util.IsSingle(diff) |
||||
// }
|
||||
// now := time.Now()
|
||||
// _, m, _ := now.Clock()
|
||||
// return util.IsSingle(m / 5)
|
||||
} |
||||
|
||||
func GetUserActivitySuperData(uid int) *common.ActivitySuperData { |
||||
p, _ := GetUserXInfo(uid, "birth") |
||||
data := &common.ActivitySuperData{UID: uid} |
||||
db.Mysql().Get(data) |
||||
if util.GetZeroTime(time.Now()).Unix()-util.GetZeroTime(time.Unix(p.Birth, 0)).Unix() < 5*common.OneDay { |
||||
data.Type = 1 |
||||
} else { |
||||
data.Type = 2 |
||||
} |
||||
data.CanBuy = !util.IsSameDayTimeStamp(time.Now().Unix(), data.Time) |
||||
if data.ID == 0 { |
||||
db.Mysql().Create(data) |
||||
} |
||||
return data |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,388 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"errors" |
||||
"fmt" |
||||
"io/ioutil" |
||||
"net/http" |
||||
"runtime" |
||||
"server/common" |
||||
"server/db" |
||||
"server/natsClient" |
||||
"server/pb" |
||||
"server/util" |
||||
"time" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
"gorm.io/gorm" |
||||
) |
||||
|
||||
var ( |
||||
ErrNotEnoughBalance = errors.New("not enough balance") |
||||
) |
||||
|
||||
const ( |
||||
ProTypeSettle = iota |
||||
ProTypeMineCash // 扣除可退出余额,判断余额是否足够
|
||||
ProTypeAll |
||||
) |
||||
|
||||
// BaseCurrency 更新玩家字段的基本对象
|
||||
type BaseCurrency struct { |
||||
subCurrency subCurrency |
||||
tx *gorm.DB |
||||
*common.CurrencyBalance |
||||
|
||||
notNotify bool // 是否需要通知客户端
|
||||
notifyChan chan *ProRes |
||||
ProType int |
||||
// IsMine bool // 是否判断玩家余额是否充足
|
||||
// IsRecharge bool // 是否更新充值账户
|
||||
} |
||||
|
||||
// NewCurrency 创建一个更新玩家字段对象
|
||||
func NewCurrency(data *common.UpdateCurrency) *BaseCurrency { |
||||
b := new(BaseCurrency) |
||||
if data.CurrencyBalance.Type <= 0 || data.CurrencyBalance.Type >= common.CurrencyAll { |
||||
return nil |
||||
} |
||||
if data.Value == 0 { |
||||
return nil |
||||
} |
||||
b.notNotify = data.NotNotify |
||||
b.tx = data.Tx |
||||
b.CurrencyBalance = data.CurrencyBalance |
||||
b.Time = time.Now().Unix() |
||||
if b.ChannelID == 0 { |
||||
playerInfo, _ := GetUserXInfo(data.UID, "channel_id") |
||||
b.ChannelID = playerInfo.ChannelID |
||||
} |
||||
log.Debug("new update:%+v", *b.CurrencyBalance) |
||||
return b |
||||
} |
||||
|
||||
// UpdateCurrency 更新玩家数据并通知客户端
|
||||
func UpdateCurrency(data *common.UpdateCurrency, tx *gorm.DB) error { |
||||
b := NewCurrency(data) |
||||
if b == nil { |
||||
return errors.New("invalid update") |
||||
} |
||||
b.tx = tx |
||||
err := b.UpdateCurrency() |
||||
if err != nil { |
||||
return err |
||||
} |
||||
b.Notify() |
||||
return nil |
||||
} |
||||
|
||||
func (b *BaseCurrency) Notify() { |
||||
if err := Publish(natsClient.TopicInnerRefreshGold, &pb.InnerRefreshGold{UID: uint32(b.UID), Pair: []*pb.CurrencyPair{{Type: int64(b.Type), Value: b.Value}}, |
||||
Event: uint32(b.Event)}); err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
if b.notNotify { |
||||
return |
||||
} |
||||
var resp pb.PlayerBalanceResp |
||||
resp.Type = int64(b.Type) |
||||
resp.Balance = b.Balance |
||||
resp.Value = b.Value |
||||
resp.Event = int64(b.Event) |
||||
|
||||
if caller != nil { |
||||
SendNR(b.UID, int(pb.ServerCommonResp_CommonPlayerBalanceResp), &resp, "common") |
||||
} |
||||
} |
||||
|
||||
func Notify(uid int, bal, changeVal int64, t common.CurrencyType, event common.CurrencyEvent, exs1, exs2 string) { |
||||
var resp pb.PlayerBalanceResp |
||||
resp.Balance = bal |
||||
resp.Type = int64(t) |
||||
resp.Event = int64(event) |
||||
resp.Exs1 = exs1 |
||||
resp.Exs2 = exs2 |
||||
resp.Value = changeVal |
||||
|
||||
if caller != nil { |
||||
SendNR(uid, int(pb.ServerCommonResp_CommonPlayerBalanceResp), &resp, "common") |
||||
} |
||||
} |
||||
|
||||
// ProRes 存储过程返回结构
|
||||
type ProRes struct { |
||||
Result int |
||||
Type common.CurrencyType |
||||
Balance int64 // 余额
|
||||
Err error |
||||
} |
||||
|
||||
// 存储过程修改金币
|
||||
func UpdateCurrencyPro(data *common.UpdateCurrency) (*ProRes, error) { |
||||
b := NewCurrency(data) |
||||
if b == nil { |
||||
return nil, errors.New("invalid update") |
||||
} |
||||
b.notifyChan = make(chan *ProRes, 1) |
||||
b.UpdateCurrencyPro() |
||||
// retPro := new(ProRes)
|
||||
// for pro := range b.notifyChan {
|
||||
// if pro.Err != nil {
|
||||
// return pro, pro.Err
|
||||
// }
|
||||
// retPro = pro
|
||||
// break
|
||||
// }
|
||||
retPro := <-b.notifyChan |
||||
b.Notify() |
||||
return retPro, nil |
||||
} |
||||
|
||||
// 存储过程修改金币,立即返回,失败后不重试(不判断玩家余额是否充足,可能扣成负数)
|
||||
func UpdateCurrencyProReal(data *common.UpdateCurrency) *ProRes { |
||||
pro := &ProRes{} |
||||
b := NewCurrency(data) |
||||
if b == nil { |
||||
pro.Err = errors.New("invalid update") |
||||
return pro |
||||
} |
||||
pro, err := b.UpdatePro() |
||||
if err != nil { |
||||
pro.Err = err |
||||
return pro |
||||
} |
||||
if pro.Err != nil { |
||||
return pro |
||||
} |
||||
b.Notify() |
||||
return pro |
||||
} |
||||
|
||||
// 存储过程修改金币,立即返回,失败后不重试(会判断玩家余额是否充足)
|
||||
func MineCurrencyProReal(data *common.UpdateCurrency) *ProRes { |
||||
pro := &ProRes{} |
||||
b := NewCurrency(data) |
||||
if b == nil { |
||||
pro.Err = errors.New("invalid update") |
||||
return pro |
||||
} |
||||
b.ProType = ProTypeMineCash |
||||
pro, err := b.UpdatePro() |
||||
if err != nil { |
||||
pro.Err = err |
||||
return pro |
||||
} |
||||
if pro.Err != nil { |
||||
return pro |
||||
} |
||||
if pro.Result == 1 { |
||||
pro.Err = ErrNotEnoughBalance |
||||
return pro |
||||
} |
||||
b.Notify() |
||||
return pro |
||||
} |
||||
|
||||
// 通过存储过程改变金币(不判断玩家余额是否充足,可能扣成负数)
|
||||
func (b *BaseCurrency) UpdateCurrencyPro() { |
||||
util.IndexTryCallback(func() error { |
||||
pro, err := b.UpdatePro() |
||||
if err != nil { |
||||
return err |
||||
} |
||||
b.notifyChan <- pro |
||||
return nil |
||||
}, func() { |
||||
b.notifyChan <- &ProRes{Err: fmt.Errorf("index try fail")} |
||||
}) |
||||
} |
||||
|
||||
func (b *BaseCurrency) UpdatePro() (*ProRes, error) { |
||||
uid := b.UID |
||||
field := b.Type.GetCurrencyName() |
||||
pro := &ProRes{Type: b.Type} |
||||
callName := "settleCurrency" |
||||
if b.ProType == ProTypeMineCash { |
||||
callName = "mineCurrency" |
||||
} |
||||
err := db.Mysql().C().Raw(fmt.Sprintf("call %s(%d,'%v',%d,%d,@a,@b)", callName, uid, field, b.Value, b.NeedBet)).Scan(pro).Error |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return pro, err |
||||
} |
||||
b.Balance = pro.Balance |
||||
util.Go(func() { |
||||
WriteBalance(b.CurrencyBalance) |
||||
}) |
||||
return pro, nil |
||||
} |
||||
|
||||
func (b *BaseCurrency) UpdateCurrency() (err error) { |
||||
tx := b.tx |
||||
if tx == nil { |
||||
tx = db.Mysql().C() |
||||
} |
||||
defer func() { |
||||
if r := recover(); r != nil { |
||||
buf := make([]byte, 1024) |
||||
runtime.Stack(buf, false) |
||||
log.Error(string(buf)) |
||||
return |
||||
} |
||||
}() |
||||
uid := b.UID |
||||
field := b.Type.GetCurrencyName() |
||||
log.Debug("player %v update currency:%+v", uid, *b) |
||||
pc := &common.PlayerCurrency{UID: uid} |
||||
tableName := pc.TableName() |
||||
err = db.Mysql().C().Table(tableName).Where(&common.PlayerCurrency{UID: uid}).Select(field).Scan(&b.Balance).Error |
||||
if err != nil { |
||||
return |
||||
} |
||||
if b.Value > 0 { |
||||
err = tx.Model(&common.PlayerCurrency{UID: uid}).Updates(map[string]interface{}{field: gorm.Expr(fmt.Sprintf("%s + ?", field), b.Value)}).Error |
||||
if err != nil { |
||||
return |
||||
} |
||||
} else { |
||||
if b.Balance < -b.Value { |
||||
err = errors.New("not enough balance") |
||||
return |
||||
} |
||||
res := tx.Table(tableName).Where(&common.PlayerCurrency{UID: uid}).Where(fmt.Sprintf("uid = %d and %s>=%d", uid, field, -b.Value)). |
||||
Updates(map[string]interface{}{field: gorm.Expr(fmt.Sprintf("%s + ?", field), -b.Value)}) |
||||
if res.RowsAffected == 0 || res.Error != nil { |
||||
log.Error("err:%e", res.Error) |
||||
err = errors.New("not enough balance") |
||||
return |
||||
} |
||||
} |
||||
if b.NeedBet > 0 { |
||||
err = tx.Model(&common.PlayerProfile{}).Where("uid = ?", uid).Updates(map[string]interface{}{"need_bet": gorm.Expr("need_bet + ?", b.NeedBet)}).Error |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
} |
||||
|
||||
b.Balance += b.Value |
||||
err = WriteBalance(b.CurrencyBalance, tx) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
if b.subCurrency != nil { |
||||
err = b.subCurrency.updateCurrency() |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
return |
||||
} |
||||
return |
||||
} |
||||
|
||||
type subCurrency interface { |
||||
updateCurrency() error |
||||
} |
||||
|
||||
func WriteBalance(b *common.CurrencyBalance, d ...*gorm.DB) error { |
||||
tx := db.Mysql().C() |
||||
if d != nil { |
||||
tx = d[0] |
||||
} |
||||
if len(b.Exs1) > 64 { |
||||
b.Exs1 = b.Exs1[:64] |
||||
} |
||||
if len(b.Exs2) > 64 { |
||||
b.Exs2 = b.Exs2[:64] |
||||
} |
||||
if len(b.Exs3) > 64 { |
||||
b.Exs3 = b.Exs3[:64] |
||||
} |
||||
err := tx.Table(b.TableName()).Create(b).Error |
||||
if err != nil { |
||||
log.Error("dbUpdateCurrency AddCurrencyBalance error:%v", err) |
||||
return err |
||||
} |
||||
db.ES().InsertToESGO(common.ESIndexBalance, b) |
||||
return nil |
||||
} |
||||
|
||||
// 汇率转换(转成美元)
|
||||
func Rate(t common.CurrencyType, amount int64) int64 { |
||||
switch t { |
||||
case common.CurrencyBrazil: |
||||
// 汇率每天刷新一次
|
||||
rate := GetConfigCurrencyRateUSD(t) |
||||
if rate == 0 { |
||||
rate = 2000 |
||||
} |
||||
return amount * rate / 10000 |
||||
default: |
||||
return amount |
||||
} |
||||
} |
||||
|
||||
func RateBRL(t common.CurrencyType, amount int64) int64 { |
||||
switch t { |
||||
case common.CurrencyBrazil: |
||||
return amount |
||||
case common.CurrencyUSDT: |
||||
// 汇率每天刷新一次
|
||||
rate := GetConfigCurrencyRateUSD(common.CurrencyBrazil) |
||||
if rate == 0 { |
||||
rate = 2000 |
||||
} |
||||
return amount * 10000 / rate |
||||
default: |
||||
return amount |
||||
} |
||||
} |
||||
|
||||
const ( |
||||
RateKey = "0P0U7HP7G0GIDJJ6" // 汇率查询网站apikey
|
||||
) |
||||
|
||||
type FXRate struct { |
||||
FromCurrencyCode string `json:"1. From_Currency Code"` |
||||
FromCurrencyName string `json:"2. From_Currency Name"` |
||||
ToCurrencyCode string `json:"3. To_Currency Code"` |
||||
ToCurrencyName string `json:"4. To_Currency Name"` |
||||
ExchangeRate float64 `json:"5. Exchange Rate,string"` |
||||
} |
||||
|
||||
// GetRateFromAPI 查询货币汇率,返回万分位
|
||||
func GetRateFromAPI(t common.CurrencyType) int64 { |
||||
if t == common.CurrencyUSDT { |
||||
return 10000 |
||||
} |
||||
url := fmt.Sprintf("https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=%v&to_currency=USD&apikey=%v", t.GetCurrencyName(), RateKey) |
||||
|
||||
resp, err := http.Get(url) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return 0 |
||||
} |
||||
defer resp.Body.Close() |
||||
|
||||
body, err := ioutil.ReadAll(resp.Body) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return 0 |
||||
} |
||||
log.Debug("GetRateFromAPI:%v", string(body)) |
||||
|
||||
var data map[string]FXRate |
||||
err = json.Unmarshal(body, &data) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return 0 |
||||
} |
||||
|
||||
fxRate, ok := data["Realtime Currency Exchange Rate"] |
||||
if !ok { |
||||
return 0 |
||||
} |
||||
return int64(fxRate.ExchangeRate * 10000) |
||||
} |
||||
@ -0,0 +1,46 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"fmt" |
||||
"server/common" |
||||
"server/db" |
||||
"server/util" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
"gorm.io/gorm" |
||||
) |
||||
|
||||
func UpdateJackpot(t, tid int, amount int64) { |
||||
if err := db.Mysql().C().Exec(fmt.Sprintf("call jackpot(%v,%v,%v)", t, tid, amount)).Error; err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
} |
||||
|
||||
func GetJackpot(t, tid int) int64 { |
||||
data := &common.Jackpot{Type: t, TypeID: tid} |
||||
db.Mysql().Get(data) |
||||
return data.Amount |
||||
} |
||||
|
||||
func GetJack(t, tid int) *common.Jackpot { |
||||
data := &common.Jackpot{Type: t, TypeID: tid} |
||||
db.Mysql().Get(data) |
||||
return data |
||||
} |
||||
|
||||
func UpdateGameJackpot(t, tid int, amount, playerAmount int64) { |
||||
jack := GetJack(t, tid) |
||||
u := map[string]interface{}{"player_amount": gorm.Expr("player_amount + ?", playerAmount)} |
||||
if jack.Amount+amount >= jack.Max { |
||||
u["amnout"] = jack.Max |
||||
} else { |
||||
u["amount"] = gorm.Expr("amount + ?", amount) |
||||
} |
||||
db.Mysql().Update(&common.Jackpot{Type: t, TypeID: tid}, u) |
||||
} |
||||
|
||||
func UpdateGameSort(provider, gameID int) { |
||||
util.Go(func() { |
||||
db.Mysql().Update(&common.ConfigGameList{GameProvider: provider, GameID: gameID}, map[string]interface{}{"sort": gorm.Expr("sort + 1")}) |
||||
}) |
||||
} |
||||
@ -0,0 +1,40 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"fmt" |
||||
"server/common" |
||||
"server/db" |
||||
"time" |
||||
) |
||||
|
||||
func GetUserItem(uid, itemID int) []*common.PlayerItems { |
||||
list := []*common.PlayerItems{} |
||||
db.Mysql().QueryAll(fmt.Sprintf("uid = %d and item_id = %d", uid, itemID), "", &common.PlayerItems{}, &list) |
||||
return list |
||||
} |
||||
|
||||
func GetUserValidItems(uid, itemID int) []*common.PlayerItems { |
||||
list := []*common.PlayerItems{} |
||||
db.Mysql().QueryAll(fmt.Sprintf("uid = %d and item_id = %d and status = %d", uid, itemID, common.ItemStatusNormal), "", &common.PlayerItems{}, &list) |
||||
return list |
||||
} |
||||
|
||||
func GetUserItemByExi1(uid, itemID, exi1 int) []*common.PlayerItems { |
||||
list := []*common.PlayerItems{} |
||||
db.Mysql().QueryAll(fmt.Sprintf("uid = %d and item_id = %d and exi1 = %d and status = %d", uid, itemID, exi1, common.ItemStatusNormal), "", &common.PlayerItems{}, &list) |
||||
return list |
||||
} |
||||
|
||||
// 获取力度最大的折扣券
|
||||
func GetUserBestDiscountTicket(uid int) *common.PlayerItems { |
||||
list := []*common.PlayerItems{} |
||||
db.Mysql().QueryAll(fmt.Sprintf("uid = %d and item_id = %d and status = %d", uid, common.ItemDiscountTicket, common.ItemStatusNormal), "exi1 desc", &common.PlayerItems{}, &list) |
||||
if len(list) > 0 { |
||||
return list[0] |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func AddUserDiscountTicket(uid, exi1 int) { |
||||
db.Mysql().Create(&common.PlayerItems{UID: uid, ItemID: common.ItemDiscountTicket, Time: time.Now().Unix(), Status: common.ItemStatusNormal, Exi1: exi1}) |
||||
} |
||||
@ -0,0 +1,65 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"fmt" |
||||
"server/common" |
||||
"server/db" |
||||
"time" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
"gorm.io/gorm" |
||||
) |
||||
|
||||
func checkMail(uid int, red *common.PlayerRed) { |
||||
data := &common.PlayerData{UID: uid} |
||||
db.Mysql().Get(data) |
||||
t := data.LastSysEmailDraw |
||||
all := []common.Mail{} |
||||
// mailCount := db.Mysql().QueryNewMailCount(uid)
|
||||
mailCount := 0 |
||||
db.Mysql().QueryAll(fmt.Sprintf("receiver = %v and time > %v", 0, t), "", &common.Mail{}, &all) |
||||
if len(all) > 0 { |
||||
now := time.Now().Unix() |
||||
u, err := db.Mysql().UpdateRes(&common.PlayerData{UID: uid, LastSysEmailDraw: data.LastSysEmailDraw}, &common.PlayerData{LastSysEmailDraw: now}) |
||||
if err != nil || u == 0 { |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
for _, v := range all { |
||||
one := v |
||||
one.ID = 0 |
||||
one.Receiver = uid |
||||
db.Mysql().Create(&one) |
||||
mailCount++ |
||||
} |
||||
if red.ID == 0 { |
||||
red.Mail = mailCount |
||||
db.Mysql().Create(red) |
||||
} else { |
||||
db.Mysql().Update(red, map[string]interface{}{"mail": gorm.Expr("mail + ?", mailCount)}) |
||||
} |
||||
} |
||||
red.Mail += mailCount |
||||
} |
||||
|
||||
const ( |
||||
MailWithdrawType2 = "Your withdrawal order is already in payment. We've paid cash to bank, the final time is determined by the bank, please be patient!\nIf cash has not yet arrived, please click online customer service on the upper right corner or WhatsApp us at %v." |
||||
MailWithdrawType3 = "1.Please check your bank/UPI information and try to withdraw again: Bank IFSC Code is formatted as 'AAAA0XXXXXX'; there shouldn't be space in UPI account;\n2.If withdrawal still fails, please click online customer service on the upper right corner or WhatsApp us at %v." |
||||
) |
||||
|
||||
func SendWithdrawMail(uid int, contentType string) { |
||||
one := &common.Mail{ |
||||
Sender: "System", |
||||
Receiver: uid, |
||||
Title: "Withdraw Notice", |
||||
Content: fmt.Sprintf(contentType, GetConfigPlatform().Whatsapp), |
||||
Time: time.Now().Unix(), |
||||
} |
||||
db.Mysql().Create(one) |
||||
UpsertRedPointAndNotify(uid, 1, ModuleMail) |
||||
} |
||||
|
||||
func SendMail(mail *common.Mail) { |
||||
db.Mysql().Create(mail) |
||||
UpsertRedPointAndNotify(mail.Receiver, 1, ModuleMail) |
||||
} |
||||
@ -0,0 +1,70 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"strconv" |
||||
|
||||
"github.com/liangdas/mqant/registry" |
||||
"github.com/liangdas/mqant/selector" |
||||
) |
||||
|
||||
func GetGameOriginID(id int) int { |
||||
return id / 100 * 100 |
||||
} |
||||
|
||||
// 选择器
|
||||
var ( |
||||
WorkIDSelector = func(nodeID string) selector.SelectOption { |
||||
return selector.WithFilter(func(services []*registry.Service) []*registry.Service { |
||||
// log.Debug("nodeID:%v", nodeID)
|
||||
ret := []*registry.Service{} |
||||
for _, service := range services { |
||||
nodes := []*registry.Node{} |
||||
for _, node := range service.Nodes { |
||||
if node.Metadata["workID"] == nodeID { |
||||
// log.Debug("find node:%v", node)
|
||||
nodes = append(nodes, node) |
||||
} |
||||
} |
||||
service.Nodes = nodes |
||||
ret = append(ret, service) |
||||
} |
||||
return ret |
||||
}) |
||||
} |
||||
// 服务器版本选择器
|
||||
VersionSelector = func(nodeID interface{}) selector.SelectOption { |
||||
return selector.WithFilter(func(services []*registry.Service) []*registry.Service { |
||||
origin := 0 |
||||
switch t := nodeID.(type) { |
||||
case int: |
||||
origin = t |
||||
case string: |
||||
origin, _ = strconv.Atoi(t) |
||||
default: |
||||
return services |
||||
} |
||||
if origin >= 3000 { |
||||
origin = GetGameOriginID(origin) |
||||
} |
||||
version := GetServerVersion(origin) |
||||
// log.Debug("nodeID:%v,version:%v", nodeID, version)
|
||||
if version == 0 { |
||||
return services |
||||
} |
||||
ret := []*registry.Service{} |
||||
for _, service := range services { |
||||
nodes := []*registry.Node{} |
||||
for _, node := range service.Nodes { |
||||
ver, _ := strconv.Atoi(node.Metadata["version"]) |
||||
if ver == version { |
||||
// log.Debug("find node:%v", node)
|
||||
nodes = append(nodes, node) |
||||
} |
||||
} |
||||
service.Nodes = nodes |
||||
ret = append(ret, service) |
||||
} |
||||
return ret |
||||
}) |
||||
} |
||||
) |
||||
@ -0,0 +1,813 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"context" |
||||
"encoding/json" |
||||
"errors" |
||||
"fmt" |
||||
"io/ioutil" |
||||
"net/http" |
||||
"server/common" |
||||
"server/config" |
||||
"server/db" |
||||
"server/natsClient" |
||||
"server/pb" |
||||
"server/util" |
||||
"time" |
||||
|
||||
"github.com/gogo/protobuf/proto" |
||||
"github.com/liangdas/mqant/log" |
||||
mqrpc "github.com/liangdas/mqant/rpc" |
||||
"gorm.io/gorm" |
||||
) |
||||
|
||||
func GetRechargeInfo(uid int) *common.RechargeInfo { |
||||
info := &common.RechargeInfo{UID: uid} |
||||
err := db.Mysql().Get(info) |
||||
if err != nil { |
||||
return info |
||||
} |
||||
now := time.Now().Unix() |
||||
if !util.IsSameDayTimeStamp(now, info.LastRecharge) { |
||||
info.DayRecharge = 0 |
||||
} |
||||
return info |
||||
} |
||||
|
||||
// Recharge 内部充值调用
|
||||
func Recharge(data *pb.InnerRechargeReq) (*pb.InnerRechargeResp, error) { |
||||
to, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
||||
defer cancel() |
||||
module := "pay" |
||||
if data.PaySource == common.PaySourceBlockPay { |
||||
module = "blockpay" |
||||
} |
||||
ret, err := GetCaller().GetApp().Call(to, module, "recharge", mqrpc.Param(data)) |
||||
if err != "" { |
||||
return nil, errors.New(err) |
||||
} |
||||
retData := new(pb.InnerRechargeResp) |
||||
if err := proto.Unmarshal(ret.([]byte), retData); err != nil { |
||||
log.Error("err:%v", err) |
||||
return nil, err |
||||
} |
||||
return retData, nil |
||||
} |
||||
|
||||
// Withdraw 内部退出调用
|
||||
func Withdraw(data *pb.InnerWithdrawReq) (*pb.InnerWithdrawResp, error) { |
||||
log.Debug("withdraw req:%+v", *data) |
||||
to, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
||||
defer cancel() |
||||
module := "pay" |
||||
if data.PaySource == common.PaySourceBlockPay { |
||||
module = "blockpay" |
||||
} |
||||
ret, err := GetCaller().GetApp().Call(to, module, "withdraw", mqrpc.Param(data)) |
||||
retData := new(pb.InnerWithdrawResp) |
||||
if data, ok := ret.([]byte); ok { |
||||
if err := proto.Unmarshal(data, retData); err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
} |
||||
if err != "" { |
||||
return retData, errors.New(err) |
||||
} |
||||
return retData, nil |
||||
} |
||||
|
||||
// RechargeCallback 充值回调
|
||||
func RechargeCallback(r *common.RechargeOrder, success bool, payAccount, extra string) (err error) { |
||||
log.Info("RechargeCallback:%+v,%v,%v,%v,", r, success, payAccount, extra) |
||||
if r == nil { |
||||
return errors.New("order invalid") |
||||
} |
||||
|
||||
if !success { |
||||
ro := &common.RechargeOrder{OrderID: r.OrderID, Status: common.StatusROrderCreate} |
||||
return db.Mysql().Update(ro, &common.RechargeOrder{Status: common.StatusROrderFail}) |
||||
} |
||||
|
||||
uid := r.UID |
||||
re := new(common.RechargeInfo) |
||||
re.UID = uid |
||||
err = db.Mysql().Get(re) |
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { |
||||
log.Error("get recharage info err:%v,uid:%v", err, r.UID) |
||||
return err |
||||
} |
||||
// product := GetConfigPayProductByID(r.ProductID)
|
||||
// if product == nil {
|
||||
// log.Error("unkonwn product:%d", r.ProductID)
|
||||
// return errors.New("unkonwn product")
|
||||
// }
|
||||
amount := r.Amount |
||||
|
||||
notCharge := re.TotalRecharge == 0 |
||||
re.TotalRecharge += amount |
||||
now := time.Now().Unix() |
||||
// var dayR, weekR bool
|
||||
var dayR bool |
||||
if util.IsSameDayTimeStamp(re.LastRecharge, now) || re.LastRecharge == 0 { |
||||
dayR = true |
||||
re.DayRecharge += amount |
||||
} |
||||
// if util.IsSameWeek(re.LastRecharge, now) || re.LastRecharge == 0 {
|
||||
// weekR = true
|
||||
// re.WeekRecharge += amount
|
||||
// }
|
||||
|
||||
re.LastRecharge = now |
||||
re.TotalRechargeCount++ |
||||
// re.ProductPayCount = common.AddProductPayCount(re.ProductPayCount, r.ProductID)
|
||||
// if product.IsFirstPayProduct() {
|
||||
// json.Unmarshal([]byte(re.ProductFirstPay), &re.ProductFirstPaySub)
|
||||
// if util.SliceContain(re.ProductFirstPaySub, product.ProductID) { // 该商品已购买,替换为可多次购买的同价值商品
|
||||
// product = GetConfigPayProductShopByAmount(product.Amount)
|
||||
// if product == nil {
|
||||
// return errors.New("product invalid")
|
||||
// }
|
||||
// } else {
|
||||
// re.ProductFirstPaySub = append(re.ProductFirstPaySub, int(product.ProductID))
|
||||
// str, _ := json.Marshal(re.ProductFirstPaySub)
|
||||
// re.ProductFirstPay = string(str)
|
||||
// }
|
||||
// }
|
||||
|
||||
// var per int64 = 0
|
||||
// level := GetConfigFirstPayLevelByAmount(r.Amount)
|
||||
// playerPayData := GetPlayerPayData(uid)
|
||||
tx := db.Mysql().Begin() |
||||
defer func() { |
||||
if err == nil { |
||||
if err := tx.Commit().Error; err != nil { |
||||
tx.Rollback() |
||||
return |
||||
} |
||||
} else { |
||||
log.Error("err:%v", err) |
||||
tx.Rollback() |
||||
return |
||||
} |
||||
}() |
||||
|
||||
// 第一步,更新订单状态
|
||||
updates := common.RechargeOrder{Status: common.StatusROrderPay, APIPayID: r.APIPayID, PayAccount: payAccount, Extra: extra, CallbackTime: now} |
||||
dbtx := tx.Table("recharge_order").Where(fmt.Sprintf("orderid = '%v' and status <> %v", r.OrderID, common.StatusROrderPay)).Updates(updates) |
||||
if dbtx.Error != nil { |
||||
return fmt.Errorf("update order err:%v", dbtx.Error) |
||||
} |
||||
// 已处理的单不返回错误了
|
||||
if dbtx.RowsAffected == 0 { |
||||
return nil |
||||
} |
||||
|
||||
// 更新paydata
|
||||
// if playerPayData.ID == 0 {
|
||||
// err = tx.Model(playerPayData).Create(playerPayData).Error
|
||||
// if err != nil {
|
||||
// log.Error("err:%v", err)
|
||||
// return
|
||||
// }
|
||||
// } else {
|
||||
// playerPayData.SubFirstPay = append(playerPayData.SubFirstPay, level)
|
||||
// updatePayData, _ := json.Marshal(playerPayData.SubFirstPay)
|
||||
// res := tx.Model(playerPayData).Where("id = ? and first_pay = ?", playerPayData.ID, playerPayData.FirstPay).Updates(map[string]interface{}{"first_pay": string(updatePayData)})
|
||||
// if res.RowsAffected == 0 {
|
||||
// log.Error("err:%v", err)
|
||||
// return errors.New("update payData fail")
|
||||
// }
|
||||
// if err != nil {
|
||||
// log.Error("update payData err:%v", err)
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
|
||||
// 第二步,更新recharge_info
|
||||
payData := &common.ESPlayerPayData{UID: uid, Channel: r.ChannelID, Type: 1, CurrencyType: r.CurrencyType} |
||||
if re.ID == 0 { |
||||
err = tx.Model(re).Create(re).Error |
||||
if err != nil { |
||||
// 说明数据库出问题或者两单并发回调,一分钟后重试
|
||||
time.AfterFunc(1*time.Minute, func() { |
||||
RechargeCallback(r, success, payAccount, extra) |
||||
}) |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
payData.FirstAmount = amount |
||||
} else { |
||||
updates := map[string]interface{}{ |
||||
"total_recharge_count": gorm.Expr("total_recharge_count + 1"), |
||||
"total_recharge": gorm.Expr("total_recharge + ?", amount), |
||||
"last_recharge": now, |
||||
// "product_paycount": re.ProductPayCount,
|
||||
// "product_firstpay": re.ProductFirstPay,
|
||||
} |
||||
if dayR { |
||||
updates["day_recharge"] = gorm.Expr("day_recharge + ?", amount) |
||||
} else { |
||||
updates["day_recharge"] = amount |
||||
} |
||||
// if weekR {
|
||||
// updates["week_recharge"] = gorm.Expr("week_recharge + ?", amount)
|
||||
// } else {
|
||||
// updates["week_recharge"] = amount
|
||||
// }
|
||||
err = tx.Model(re).Where("uid=?", re.UID).Updates(updates).Error |
||||
} |
||||
if err != nil { |
||||
log.Error("recharge err:%v", err) |
||||
return err |
||||
} |
||||
// 第三步,给玩家发货
|
||||
// 正常商城充值
|
||||
var bonus int64 |
||||
if r.ProductID == 0 { |
||||
amount := PayExtra(r) // 判断特殊购买,如优惠券
|
||||
if amount == 0 { |
||||
amount = r.Amount |
||||
} |
||||
// cb := &common.CurrencyBalance{
|
||||
// UID: r.UID,
|
||||
// Type: r.CurrencyType,
|
||||
// Value: amount,
|
||||
// Event: common.CurrencyEvent(r.Event),
|
||||
// Exs1: r.OrderID,
|
||||
// Exi1: int(amount), // 充值金额传递
|
||||
// Exi2: r.ProductID,
|
||||
// NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceRecharge, amount),
|
||||
// }
|
||||
// err = UpdateCurrencyProReal(&common.UpdateCurrency{
|
||||
// CurrencyBalance: cb,
|
||||
// }).Err
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// } else {
|
||||
per := GetConfigFirstPayPerByAmount(notCharge, amount) |
||||
if per > 0 { |
||||
bonus = amount * per / 100 |
||||
} |
||||
cb := &common.CurrencyBalance{ |
||||
UID: r.UID, |
||||
Type: r.CurrencyType, |
||||
Value: amount + bonus, |
||||
Event: common.CurrencyEvent(r.Event), |
||||
Exs1: r.OrderID, |
||||
Exi1: int(amount), // 充值金额传递
|
||||
Exi2: r.ProductID, |
||||
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceRecharge, amount) + GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, bonus), |
||||
} |
||||
err = UpdateCurrencyProReal(&common.UpdateCurrency{ |
||||
CurrencyBalance: cb, |
||||
}).Err |
||||
if err != nil { |
||||
return |
||||
} |
||||
} |
||||
// 以上逻辑为处理订单,更新玩家充值信息,给玩家加钱。
|
||||
// 下面逻辑处理活动,数据统计等,不影响以上效率,接下来逻辑并发执行
|
||||
util.Go(func() { |
||||
// 更新活动数据上传
|
||||
if bonus > 0 { |
||||
UploadActivityData(uid, common.ActivityIDRecharge, common.ActivityDataJoin, bonus) |
||||
} |
||||
user, _ := GetUserInfo(uid) |
||||
PayActivity(r, notCharge, user) |
||||
if r.Event != int(common.CurrencyEventGMRecharge) { |
||||
payData.Amount = amount |
||||
WritePlayerPayData(payData) |
||||
} |
||||
var uploads []func() |
||||
uploads = append(uploads, func() { UploadAdjust(common.AdjustEventAllPay, user, nil) }) |
||||
// 24小时内注册的用户所有付费事件上报
|
||||
if now-user.Birth <= 24*60*60 { |
||||
uploads = append(uploads, func() { |
||||
UploadAdjust(common.AdjustEventNewPay, user, map[string]string{"revenue": util.RoundFloat(float64(amount/1e6)/100, 2), "currency": "BRL"}) |
||||
}) |
||||
|
||||
// 上报fb
|
||||
UploadFB(uid, FBEventPurchase, amount/common.DecimalDigits) |
||||
UploadKwai(uid, KwaiEventPay, amount) |
||||
} |
||||
for _, f := range uploads { |
||||
f() |
||||
} |
||||
}) |
||||
return nil |
||||
} |
||||
|
||||
func WithdrawCallback(order *common.WithdrawOrder) error { |
||||
uid := order.UID |
||||
amount := order.Amount |
||||
var err error |
||||
// 不成功退款
|
||||
if order.Status == common.StatusROrderFail { |
||||
err = ReturnBackWithdraw(order, common.StatusROrderFinish, common.StatusROrderFail) |
||||
} else { |
||||
tx := db.Mysql().Begin() |
||||
or := new(common.WithdrawOrder) |
||||
or.ID = order.ID |
||||
or.Status = uint8(common.StatusROrderFinish) |
||||
or.CallbackTime = time.Now().Unix() |
||||
or.APIPayID = order.APIPayID |
||||
or.FailReason = order.FailReason |
||||
if len(or.FailReason) > 200 { |
||||
or.FailReason = or.FailReason[:200] |
||||
} |
||||
res := tx.Model(or).Where("id = ? and status <> ?", or.ID, common.StatusROrderFinish).Updates(or) |
||||
if res.Error != nil { |
||||
log.Error("Withdraw callback err:%v", res.Error) |
||||
tx.Rollback() |
||||
return err |
||||
} |
||||
// 已处理的情况不返回错误了
|
||||
if res.RowsAffected == 0 { |
||||
log.Error("Withdraw callback order:%v done", order.OrderID) |
||||
tx.Rollback() |
||||
return nil |
||||
} |
||||
rei := &common.RechargeInfo{UID: uid} |
||||
db.Mysql().Get(rei) |
||||
payData := &common.ESPlayerPayData{UID: uid, Channel: order.ChannelID, Amount: amount, Type: 2} |
||||
if rei.TotalWithdrawCount == 0 { |
||||
payData.FirstAmount = amount |
||||
} |
||||
WritePlayerPayData(payData) |
||||
u := map[string]interface{}{ |
||||
"total_withdraw_count": gorm.Expr("total_withdraw_count + ?", 1), |
||||
"total_withdraw": gorm.Expr("total_withdraw + ?", order.Amount), |
||||
"total_withdrawing": gorm.Expr("total_withdrawing - ?", amount), |
||||
"withdrawing_cash": gorm.Expr("withdrawing_cash - ?", order.WithdrawCash), |
||||
} |
||||
err = tx.Model(rei).Where("uid = ?", uid).Updates(u).Error |
||||
if err != nil { |
||||
log.Error("BaseWithdraw err :%v", err) |
||||
tx.Rollback() |
||||
return err |
||||
} |
||||
// err = UpdatePlayerRechargeInfoCurrency(uid, order.CurrencyType, map[string]interface{}{
|
||||
// "total_withdrawing": gorm.Expr("total_withdrawing - ?", order.WithdrawCash),
|
||||
// "total_withdraw": gorm.Expr("total_withdraw + ?", order.Amount),
|
||||
// }, tx)
|
||||
// if err != nil {
|
||||
// log.Error("BaseWithdraw err :%v", err)
|
||||
// tx.Rollback()
|
||||
// return err
|
||||
// }
|
||||
if err := tx.Commit().Error; err != nil { |
||||
log.Error("ZYWithdraw callback err:%v", err) |
||||
tx.Rollback() |
||||
return err |
||||
} |
||||
PublishWarn(WarnTypeWithdraw, 2, []int64{int64(order.ChannelID), int64(order.UID)}) |
||||
con := GetBroadcastConfigWithID(common.BrocastIDWithdraw) |
||||
if con != nil { |
||||
up := con.ConditionUp |
||||
down := con.ConditionDown |
||||
if (amount <= int64(up) || up <= 0) && amount >= int64(down) { |
||||
BroadcastReq(con, fmt.Sprintf(con.Content, uid, amount)) |
||||
} |
||||
} |
||||
// util.Go(func() {
|
||||
// SendRealWithdrawMail(order)
|
||||
// })
|
||||
} |
||||
if err != nil { |
||||
return err |
||||
} |
||||
Publish(natsClient.TopicInnerPlayerWithdraw, &pb.InnerWithdrawCallback{UID: uint32(uid)}) |
||||
return nil |
||||
} |
||||
|
||||
// ReturnBackWithdraw 退出被拒绝或者失败,返还金币
|
||||
func ReturnBackWithdraw(or *common.WithdrawOrder, originStatus, status uint8, payChannel ...int) error { |
||||
order := &common.WithdrawOrder{} |
||||
order.ID = or.ID |
||||
tx := db.Mysql().Begin() |
||||
u := map[string]interface{}{ |
||||
"status": status, |
||||
"fail_reason": or.FailReason, |
||||
"callback_time": time.Now().Unix(), |
||||
} |
||||
if len(payChannel) > 0 { |
||||
u["pay_channel"] = payChannel[0] |
||||
} |
||||
if len(or.APIPayID) > 0 { |
||||
u["apipayid"] = or.APIPayID |
||||
} |
||||
update := tx.Model(order).Where("status <= ?", originStatus).Updates(u) |
||||
if update.Error != nil { |
||||
log.Error("err:%v", update.Error) |
||||
tx.Rollback() |
||||
return update.Error |
||||
} |
||||
// 已处理的情况不返回错误了
|
||||
if update.RowsAffected == 0 { |
||||
err := fmt.Errorf("update fail:%+v", or) |
||||
log.Error("err:%v", err) |
||||
tx.Rollback() |
||||
return nil |
||||
} |
||||
uid := or.UID |
||||
re := new(common.RechargeInfo) |
||||
re.UID = uid |
||||
updateRe := map[string]interface{}{ |
||||
"withdrawing_cash": gorm.Expr("withdrawing_cash - ?", or.WithdrawCash), |
||||
"total_withdrawing": gorm.Expr("total_withdrawing - ?", or.Amount), |
||||
"day_withdraw": gorm.Expr("day_withdraw - ?", or.Amount), |
||||
} |
||||
if status == common.StatusROrderFail { |
||||
updateRe["withdraw_count"] = gorm.Expr("withdraw_count + ?", -1) |
||||
} |
||||
err := tx.Model(re).Where("uid = ? and withdrawing_cash >= ? and total_withdrawing >= ?", or.UID, or.WithdrawCash, or.Amount). |
||||
Updates(updateRe).Error |
||||
if err != nil { |
||||
log.Error("err :%v", err) |
||||
tx.Rollback() |
||||
return err |
||||
} |
||||
if err := UpdateCurrency(&common.UpdateCurrency{ |
||||
CurrencyBalance: &common.CurrencyBalance{ |
||||
UID: or.UID, |
||||
Type: or.CurrencyType, |
||||
Value: or.WithdrawCash, |
||||
Event: common.CurrencyEventWithDrawBack, |
||||
Exs1: or.OrderID, |
||||
}, |
||||
}, tx); err != nil { |
||||
log.Error("Withdraw callback err:%v", err) |
||||
tx.Rollback() |
||||
return err |
||||
} |
||||
// 退还代付券
|
||||
// if or.Extra == "useFreeWithdraw" {
|
||||
// if err := tx.Model(&common.PlayerItems{UID: uid}).Updates(map[string]interface{}{"free_withdraw": gorm.Expr("free_withdraw + 1")}).Error; err != nil {
|
||||
// log.Error("err:%v", err)
|
||||
// tx.Rollback()
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
if err := tx.Commit().Error; err != nil { |
||||
log.Error("err:%v", err) |
||||
tx.Rollback() |
||||
return err |
||||
} |
||||
// 失败的时候才发送邮件
|
||||
// if status == common.StatusROrderFail {
|
||||
// util.Go(func() {
|
||||
// SendWithdrawMail(uid, MailWithdrawType3)
|
||||
// SendRealWithdrawMail(or)
|
||||
// })
|
||||
// }
|
||||
return nil |
||||
} |
||||
|
||||
func WritePlayerPayData(data *common.ESPlayerPayData) { |
||||
data.Time = time.Now().Unix() |
||||
ret, _ := GetUserXInfo(data.UID, "birth") |
||||
data.IsNew = IsNewPlayer(ret.Birth) |
||||
data.IsNew = util.IsSameDayTimeStamp(ret.Birth, data.Time) |
||||
db.ES().InsertToESGO(common.ESIndexBackPlayerPayData, data) |
||||
} |
||||
|
||||
// PayExtra 支付extra字段判断
|
||||
func PayExtra(r *common.RechargeOrder) (amount int64) { |
||||
if len(r.Extra) == 0 { |
||||
return |
||||
} |
||||
extraData := &common.ActivityRechargeData{} |
||||
json.Unmarshal([]byte(r.Extra), extraData) |
||||
switch extraData.ID { |
||||
case common.ItemDiscountTicket: |
||||
list := GetUserItemByExi1(r.UID, common.ItemDiscountTicket, extraData.I1) |
||||
if len(list) == 0 { |
||||
return |
||||
} |
||||
item := list[0] |
||||
rows, err := db.Mysql().UpdateRes(&common.PlayerItems{ID: item.ID, Status: common.ItemStatusNormal}, |
||||
map[string]interface{}{"status": common.ItemStatusInvalid}) |
||||
if err != nil || rows == 0 { |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
amount = extraData.I2 |
||||
} |
||||
return |
||||
} |
||||
|
||||
// PayActivity 支付活动
|
||||
func PayActivity(r *common.RechargeOrder, notCharge bool, user *common.PlayerDBInfo) (err error) { |
||||
// VIP
|
||||
UpdateVip(r.UID, r.Amount, 0, 0) |
||||
// 检查任务
|
||||
CheckTask(r) |
||||
// 检查所有活动
|
||||
CheckAllActivity(r) |
||||
|
||||
// 更新loginrecord
|
||||
if notCharge { |
||||
InsertLoginRecord(r.UID, r.ChannelID, user.IP, user.Birth, user.Platform) |
||||
CheckShare(r) |
||||
} |
||||
|
||||
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) { |
||||
rechargeBackData := GetUserFirstRechargeBackData(r.UID) |
||||
if rechargeBackData.RechargeTime == 0 { |
||||
db.Mysql().Create(&common.ActivityFirstRechargeBackData{UID: r.UID, RechargeTime: time.Now().Unix(), Amount: r.Amount}) |
||||
} else if now-rechargeBackData.RechargeTime < common.ActivityFirstRechargeBackTime { |
||||
db.Mysql().Update(&common.ActivityFirstRechargeBackData{UID: r.UID}, map[string]interface{}{"amount": gorm.Expr("amount + ?", r.Amount)}) |
||||
} |
||||
} |
||||
} |
||||
|
||||
func CheckAllActivity(r *common.RechargeOrder) { |
||||
// 首充返还活动
|
||||
ActivityFirstRechargeBack(r) |
||||
|
||||
var product *common.ConfigPayProduct |
||||
if r.ProductID > 0 { |
||||
product = GetConfigPayProductByID(r.ProductID) |
||||
} |
||||
// slots奖池活动
|
||||
ActivitySlots(r, product) |
||||
|
||||
if product == nil { |
||||
return |
||||
} |
||||
|
||||
switch product.ActivityID { |
||||
case common.ActivityIDBreakGift: |
||||
ActivityBreakGift(r, product) |
||||
case common.ActivityIDWeekCard: |
||||
ActivityWeekCard(r, product) |
||||
case common.ActivityIDLuckyShop: |
||||
ActivityLuckyShop(r, product) |
||||
case common.ActivityIDSevenDayBox: |
||||
ActivitySevenDayBox(r, product) |
||||
case common.ActivityIDSuper: |
||||
ActivitySuper(r, product) |
||||
} |
||||
} |
||||
|
||||
func ActivityBreakGift(r *common.RechargeOrder, product *common.ConfigPayProduct) { |
||||
payData := GetPlayerPayData(r.UID) |
||||
gift := GetConfigActivityBreakGiftByProductID(r.ProductID) |
||||
if util.SliceContain(payData.SubBreakGift, gift.Level) { |
||||
return |
||||
} |
||||
payData.SubBreakGift = append(payData.SubBreakGift, gift.Level) |
||||
str, _ := json.Marshal(payData.SubBreakGift) |
||||
rows, err := db.Mysql().UpdateRes(&common.PlayerPayData{UID: r.UID, BreakGift: payData.BreakGift}, map[string]interface{}{"break_gift": string(str)}) |
||||
if rows == 0 || err != nil { |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
// ok
|
||||
UpdateCurrencyPro(&common.UpdateCurrency{ |
||||
CurrencyBalance: &common.CurrencyBalance{ |
||||
UID: r.UID, |
||||
Value: product.Value, |
||||
Event: common.CurrencyEventActivityBreakGift, |
||||
Type: common.CurrencyBrazil, |
||||
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, product.Value), |
||||
ChannelID: r.ChannelID, |
||||
Exi1: product.ProductID, |
||||
}, |
||||
}) |
||||
UploadActivityData(r.UID, common.ActivityIDBreakGift, common.ActivityDataJoin, product.Value) |
||||
} |
||||
|
||||
func ActivityWeekCard(r *common.RechargeOrder, product *common.ConfigPayProduct) { |
||||
level := product.Exi |
||||
card := GetUserWeekCard(r.UID, level) |
||||
con := GetConfigActivityWeekCardByLevel(level) |
||||
if con == nil { |
||||
return |
||||
} |
||||
if card.ID == 0 { |
||||
err := db.Mysql().Create(&common.ActivityWeekCardData{ |
||||
UID: r.UID, |
||||
Level: level, |
||||
DayReward: con.DayReward, |
||||
Day: con.Day, |
||||
// LastDraw: time.Now().Unix(),
|
||||
}) |
||||
if err != nil { |
||||
return |
||||
} |
||||
} else { |
||||
if card.Day > 0 { |
||||
return |
||||
} |
||||
rows, err := db.Mysql().UpdateResW(&common.ActivityWeekCardData{}, map[string]interface{}{ |
||||
"day": con.Day, "day_reward": con.DayReward, "get_discount": 0, "last_draw": 0}, |
||||
fmt.Sprintf("uid = %d and level = %d and day = 0", r.UID, level)) |
||||
if err != nil || rows == 0 { |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
} |
||||
// ok
|
||||
UpdateCurrencyPro(&common.UpdateCurrency{ |
||||
CurrencyBalance: &common.CurrencyBalance{ |
||||
UID: r.UID, |
||||
Value: product.Value, |
||||
Event: common.CurrencyEventActivityWeekCard, |
||||
Type: common.CurrencyBrazil, |
||||
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, product.Value), |
||||
ChannelID: r.ChannelID, |
||||
Exi1: product.ProductID, |
||||
}, |
||||
}) |
||||
UploadActivityData(r.UID, common.ActivityIDWeekCard, common.ActivityDataJoin, product.Value) |
||||
} |
||||
|
||||
func ActivityLuckyShop(r *common.RechargeOrder, product *common.ConfigPayProduct) { |
||||
rows, err := db.Mysql().UpdateResW(&common.ActivityLuckyShopData{}, map[string]interface{}{"buy": 1}, |
||||
fmt.Sprintf("uid = %d and product_id = %d and buy = 0", r.UID, product.ProductID)) |
||||
value := product.Value |
||||
if rows == 0 || err != nil { |
||||
// 直接给玩家按商品原价加钱
|
||||
value = r.Amount |
||||
} |
||||
UpdateCurrencyProReal(&common.UpdateCurrency{ |
||||
CurrencyBalance: &common.CurrencyBalance{ |
||||
UID: r.UID, |
||||
Type: r.CurrencyType, |
||||
Value: value, |
||||
Event: common.CurrencyEvent(r.Event), |
||||
Exs1: r.OrderID, |
||||
Exi1: int(r.Amount), // 充值金额传递
|
||||
Exi2: r.ProductID, |
||||
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, value), |
||||
}, |
||||
}) |
||||
UploadActivityData(r.UID, common.ActivityIDLuckyShop, common.ActivityDataJoin, product.Value) |
||||
} |
||||
|
||||
func ActivitySlots(r *common.RechargeOrder, product *common.ConfigPayProduct) { |
||||
if !IsActivityValid(common.ActivityIDSlots) { |
||||
return |
||||
} |
||||
if product != nil && product.ActivityID == common.ActivityIDSlots { |
||||
if product.Exi > 0 { |
||||
UpdateUserActivitySlotsData(r.UID, int(product.Exi)) |
||||
} |
||||
UpdateCurrencyProReal(&common.UpdateCurrency{ |
||||
CurrencyBalance: &common.CurrencyBalance{ |
||||
UID: r.UID, |
||||
Type: r.CurrencyType, |
||||
Value: product.Value, |
||||
Event: common.CurrencyEvent(r.Event), |
||||
Exs1: r.OrderID, |
||||
Exi1: int(r.Amount), // 充值金额传递
|
||||
Exi2: r.ProductID, |
||||
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, product.Value), |
||||
}, |
||||
}) |
||||
return |
||||
} |
||||
count := r.Amount / 1000000000 |
||||
if count >= 1 { |
||||
UpdateUserActivitySlotsData(r.UID, int(count)) |
||||
} |
||||
} |
||||
|
||||
func ActivitySevenDayBox(r *common.RechargeOrder, product *common.ConfigPayProduct) { |
||||
data := &common.ActivitySevenDayBoxData{UID: r.UID} |
||||
db.Mysql().Get(data) |
||||
now := time.Now().Unix() |
||||
value := product.Value |
||||
if util.IsSameDayTimeStamp(now, data.Time) { // 一天只能买一次
|
||||
value = r.Amount |
||||
} else { |
||||
if data.ID == 0 { |
||||
data.Time = now |
||||
data.Count = 1 |
||||
err := db.Mysql().Create(data) |
||||
if err != nil { |
||||
value = r.Amount |
||||
} |
||||
} else { |
||||
rows, err := db.Mysql().UpdateResW(&common.ActivitySevenDayBoxData{}, map[string]interface{}{"count": gorm.Expr("count + 1"), "time": now}, |
||||
fmt.Sprintf("uid = %d and count = %d and time = %d", r.UID, data.Count, data.Time)) |
||||
if rows == 0 || err != nil { |
||||
// 直接给玩家按商品原价加钱
|
||||
value = r.Amount |
||||
} |
||||
} |
||||
} |
||||
if value > 0 { |
||||
UpdateCurrencyProReal(&common.UpdateCurrency{ |
||||
CurrencyBalance: &common.CurrencyBalance{ |
||||
UID: r.UID, |
||||
Type: r.CurrencyType, |
||||
Value: value, |
||||
Event: common.CurrencyEvent(r.Event), |
||||
Exs1: r.OrderID, |
||||
Exi1: int(r.Amount), // 充值金额传递
|
||||
Exi2: r.ProductID, |
||||
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, value), |
||||
}, |
||||
}) |
||||
} |
||||
} |
||||
|
||||
func ActivitySuper(r *common.RechargeOrder, product *common.ConfigPayProduct) { |
||||
data := GetUserActivitySuperData(r.UID) |
||||
value := product.Value |
||||
if !data.CanBuy { |
||||
value = r.Amount |
||||
} else { |
||||
rows, err := db.Mysql().UpdateResW(&common.ActivitySuperData{}, map[string]interface{}{"open": 0, "time": time.Now().Unix()}, |
||||
fmt.Sprintf("uid = %d and time = %d", r.UID, data.Time)) |
||||
if rows == 0 || err != nil { |
||||
log.Error("err:%v", err) |
||||
value = r.Amount |
||||
} |
||||
} |
||||
if value > 0 { |
||||
UpdateCurrencyProReal(&common.UpdateCurrency{ |
||||
CurrencyBalance: &common.CurrencyBalance{ |
||||
UID: r.UID, |
||||
Type: r.CurrencyType, |
||||
Value: value, |
||||
Event: common.CurrencyEvent(r.Event), |
||||
Exs1: r.OrderID, |
||||
Exi1: int(r.Amount), // 充值金额传递
|
||||
Exi2: r.ProductID, |
||||
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, value), |
||||
}, |
||||
}) |
||||
} |
||||
} |
||||
|
||||
type IFSCRet struct { |
||||
Ifsc string `json:"IFSC"` |
||||
} |
||||
|
||||
func CheckIFSC(ifsc string) bool { |
||||
ret := &IFSCRet{} |
||||
client := http.Client{ |
||||
Timeout: 2 * time.Second, |
||||
} |
||||
url := config.GetConfig().Web.IFSCURL + "/" + ifsc |
||||
log.Debug("url:%v", url) |
||||
resp, err := client.Get(url) |
||||
if err != nil { |
||||
log.Error("get err:%v", err) |
||||
return true |
||||
} |
||||
// if resp.StatusCode != http.StatusOK {
|
||||
// log.Error("req fail err code:%v", resp.StatusCode)
|
||||
// return true
|
||||
// }
|
||||
defer resp.Body.Close() |
||||
data, err := ioutil.ReadAll(resp.Body) |
||||
if err != nil { |
||||
log.Error("read err %v", err) |
||||
return true |
||||
} |
||||
json.Unmarshal(data, ret) |
||||
return ret.Ifsc != "" |
||||
} |
||||
|
||||
func GetTotalRechargePer(thisWithdraw int64) int64 { |
||||
zero := util.GetZeroTime(time.Now()).Unix() |
||||
recharge := db.Mysql().Sum(&common.RechargeOrder{}, fmt.Sprintf("create_time >= %d and event = %d and status = %d", zero, common.CurrencyEventReCharge, common.StatusROrderPay), "amount") |
||||
withdraw := db.Mysql().Sum(&common.WithdrawOrder{}, fmt.Sprintf("create_time >= %d and event = %d and status = %d", zero, common.CurrencyEventWithDraw, common.StatusROrderFinish), "amount") |
||||
withdraw += thisWithdraw |
||||
if recharge == 0 { |
||||
return withdraw * 100 / common.DecimalDigits |
||||
} |
||||
return withdraw * 100 / recharge |
||||
} |
||||
@ -0,0 +1,38 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"server/common" |
||||
"server/pb" |
||||
"strconv" |
||||
"strings" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
) |
||||
|
||||
func GetModuleName(id int) string { |
||||
if id == 1000 { |
||||
return "hall" |
||||
} |
||||
if id == 1100 { |
||||
return "common" |
||||
} |
||||
if id == 1101 { |
||||
return "matching" |
||||
} |
||||
return common.GetGameModuleName(id) |
||||
} |
||||
|
||||
func GetModuleID(name string) int { |
||||
if name == "hall" { |
||||
return int(pb.ServerType_ServerTypeGate) |
||||
} |
||||
if name == "common" { |
||||
return int(pb.ServerType_ServerTypeCommon) |
||||
} |
||||
name = strings.ReplaceAll(name, common.GameModulePrefix, "") |
||||
id, err := strconv.Atoi(name) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
return id |
||||
} |
||||
@ -0,0 +1,47 @@ |
||||
package call |
||||
|
||||
import "server/util" |
||||
|
||||
var ( |
||||
execQueue = NewQueue() |
||||
) |
||||
|
||||
// 顺序执行并发操作
|
||||
func InitExecQueue() { |
||||
execQueue.Run() |
||||
} |
||||
|
||||
func AddQueue(f func()) { |
||||
execQueue.AddQueue(f) |
||||
} |
||||
|
||||
type ExecQueue struct { |
||||
c chan func() |
||||
} |
||||
|
||||
func (e *ExecQueue) Run() { |
||||
util.Go(func() { |
||||
for { |
||||
f := <-e.c |
||||
func() { |
||||
defer util.Recover() |
||||
f() |
||||
}() |
||||
} |
||||
}) |
||||
} |
||||
|
||||
func (e *ExecQueue) AddQueue(f func()) { |
||||
e.c <- f |
||||
} |
||||
|
||||
func NewQueue(size ...int) *ExecQueue { |
||||
e := &ExecQueue{} |
||||
if size != nil { |
||||
e.c = make(chan func(), size[0]) |
||||
} else { |
||||
e.c = make(chan func(), 10000) |
||||
} |
||||
e.Run() |
||||
return e |
||||
} |
||||
@ -0,0 +1,203 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"crypto/tls" |
||||
"encoding/json" |
||||
"errors" |
||||
"fmt" |
||||
"math/rand" |
||||
"net/smtp" |
||||
"server/common" |
||||
"server/config" |
||||
"server/db" |
||||
"strings" |
||||
"time" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
) |
||||
|
||||
const ( |
||||
RealMailSuccessTitle = "Withdrawal succeeded! [%v]" |
||||
RealMailSuccessContext = "Deal %v:\n" + |
||||
"\n" + |
||||
"Congratulations! Your latest withdrawal has been successfully transferred to your bank account. Please check your account." + |
||||
"If there is any question about this order, please feel free to contact our customer service below.\n" + |
||||
"\n" + |
||||
"Email:%v\n" + |
||||
"\n" + |
||||
"Whatsapp:%v\n" + |
||||
"\n" + |
||||
"Thanks for your playing!\n" + |
||||
"\n" + |
||||
"\n" + |
||||
"Best wishes\n" + |
||||
"\n" + |
||||
"%v" |
||||
RealMailFailTitle = "Withdrawal failure! [%v]" |
||||
RealMailFailContext = "Deal %v:\n" + |
||||
"\n" + |
||||
"Important information about your withdrawal order:\n" + |
||||
"\n" + |
||||
"AccountName:%v\n" + |
||||
"\n" + |
||||
"Mobile:%v\n" + |
||||
"\n" + |
||||
"%v\n" + |
||||
"\n" + |
||||
"Your latest withdrawal order has failed for the following reasons:\n" + |
||||
"\n" + |
||||
"\t1.Wrong UPI/BANK information you submitted. Please CAREFULLY check your UPI/BANK information and try to withdraw again:\n" + |
||||
"\n" + |
||||
"\t\t(1) The UPI/BANK account shall not have any space;\n" + |
||||
"\t\t(2) The bank IFSC Code shall be 11 digital letters formatted as 'AAAA0XXXXXX;\n" + |
||||
"\n" + |
||||
"\t2.Bank refused. The bank refused this order because of your bank account problems.\n" + |
||||
"\n" + |
||||
"If withdrawal still fails after all your information was checked, please get in touch with customer service:\n" + |
||||
"\n" + |
||||
"\t1.Email:%v\n" + |
||||
"\t2.Whatsapp:%v\n" + |
||||
"\n" + |
||||
"Do not worry! The refunds of the withdrawal order that failed will be returned to your game account.\n" + |
||||
"\n" + |
||||
"\n" + |
||||
"Kind regards\n" + |
||||
"\n" + |
||||
"%v" |
||||
) |
||||
|
||||
type realMail struct { |
||||
user string |
||||
passwd string |
||||
} |
||||
|
||||
// 初始化用户名和密码
|
||||
func NewMail(u string, p string) *realMail { |
||||
temp := &realMail{user: u, passwd: p} |
||||
return temp |
||||
} |
||||
|
||||
// 标题 文本 目标邮箱
|
||||
func (m *realMail) Send(title string, text string, toId string) error { |
||||
auth := smtp.PlainAuth("", m.user, m.passwd, "smtp.gmail.com") |
||||
|
||||
tlsconfig := &tls.Config{ |
||||
InsecureSkipVerify: true, |
||||
ServerName: "smtp.gmail.com", |
||||
} |
||||
|
||||
conn, err := tls.Dial("tcp", "smtp.gmail.com:465", tlsconfig) |
||||
if err != nil { |
||||
log.Error("real:%+v,err:%v", *m, err) |
||||
return err |
||||
} |
||||
|
||||
client, err := smtp.NewClient(conn, "smtp.gmail.com") |
||||
if err != nil { |
||||
log.Error("real:%+v,err:%v", *m, err) |
||||
return err |
||||
} |
||||
|
||||
if err = client.Auth(auth); err != nil { |
||||
log.Error("real:%+v,err:%v", *m, err) |
||||
return err |
||||
} |
||||
|
||||
if err = client.Mail(m.user); err != nil { |
||||
log.Error("real:%+v,err:%v", *m, err) |
||||
return err |
||||
} |
||||
|
||||
if err = client.Rcpt(toId); err != nil { |
||||
log.Error("real:%+v,toId:%v,err:%v", *m, toId, err) |
||||
return err |
||||
} |
||||
|
||||
w, err := client.Data() |
||||
if err != nil { |
||||
log.Error("real:%+v,err:%v", *m, err) |
||||
return err |
||||
} |
||||
|
||||
msg := fmt.Sprintf("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s", m.user, toId, title, text) |
||||
|
||||
_, err = w.Write([]byte(msg)) |
||||
if err != nil { |
||||
log.Error("real:%+v,err:%v", *m, err) |
||||
return err |
||||
} |
||||
|
||||
err = w.Close() |
||||
if err != nil { |
||||
log.Error("real:%+v,err:%v", *m, err) |
||||
return err |
||||
} |
||||
|
||||
client.Quit() |
||||
return nil |
||||
} |
||||
|
||||
// SendRealWithdrawMail 给玩家真实的邮箱发送邮件
|
||||
func SendRealWithdrawMail(or *common.WithdrawOrder) error { |
||||
withdrawCommon := &common.WithdrawCommon{} |
||||
if err := json.Unmarshal([]byte(or.PayAccount), withdrawCommon); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
if withdrawCommon.Email == "" { |
||||
log.Error("or:%+v,withdrawCommon:%+v,email is null", or, withdrawCommon) |
||||
return fmt.Errorf("or:%+v,email is null", or) |
||||
} |
||||
if strings.Contains(GetConfigPlatform().Email, withdrawCommon.Email) { |
||||
return nil |
||||
} |
||||
accounts := config.GetBase().Mails.Accounts |
||||
if len(accounts) == 0 { |
||||
return nil |
||||
} |
||||
|
||||
channel := GetChannelByID(or.ChannelID) |
||||
if channel == nil { |
||||
return errors.New("unknown channel") |
||||
} |
||||
title := "" |
||||
context := "" |
||||
status := 0 |
||||
if or.Status == common.StatusROrderFail { |
||||
status = 0 |
||||
payInfo := "" |
||||
// if withdrawCommon.DrawType == common.WithdrawTypeUPI {
|
||||
// payInfo = fmt.Sprintf("UPI Account:%v", withdrawCommon.BankCode)
|
||||
// } else if withdrawCommon.DrawType == common.WithdrawTypeBank {
|
||||
// payInfo = fmt.Sprintf("BankCard Number:%v\n\nIFSC Code:%v", withdrawCommon.BankCardNo, withdrawCommon.BankCode)
|
||||
// }
|
||||
title = fmt.Sprintf(RealMailFailTitle, channel.Name) |
||||
context = fmt.Sprintf(RealMailFailContext, withdrawCommon.Name, withdrawCommon.Name, |
||||
withdrawCommon.Mobile, payInfo, GetConfigPlatform().Email, GetConfigPlatform().Whatsapp, channel.Name) |
||||
} else if or.Status == common.StatusROrderFinish { |
||||
status = 1 |
||||
title = fmt.Sprintf(RealMailSuccessTitle, channel.Name) |
||||
context = fmt.Sprintf(RealMailSuccessContext, withdrawCommon.Name, GetConfigPlatform().Email, |
||||
GetConfigPlatform().Whatsapp, channel.Name) |
||||
} |
||||
if db.Redis().Exist(common.GetRedisKeyRealMail(or.UID, status)) { |
||||
return nil |
||||
} |
||||
|
||||
pass := config.GetBase().Mails.Pass |
||||
rans := rand.Perm(len(accounts)) |
||||
// 只尝试一次
|
||||
for i := 0; i < 1; i++ { |
||||
index := rans[i] |
||||
if index > len(pass)-1 { |
||||
break |
||||
} |
||||
m := NewMail(accounts[index], pass[index]) |
||||
if err := m.Send(title, context, withdrawCommon.Email); err == nil { |
||||
// 每24小时同类型邮件只发送一次
|
||||
db.Redis().SetData(common.GetRedisKeyRealMail(or.UID, status), 1, 24*time.Hour) |
||||
return nil |
||||
} |
||||
} |
||||
return errors.New("send fail") |
||||
} |
||||
@ -0,0 +1,53 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"fmt" |
||||
"reflect" |
||||
"server/common" |
||||
"server/db" |
||||
"server/pb" |
||||
"strings" |
||||
|
||||
"gorm.io/gorm" |
||||
) |
||||
|
||||
const ( |
||||
ModuleMail = "Mail" |
||||
) |
||||
|
||||
// UpsertRedPointAndNotify 更新红点并通知客户端
|
||||
func UpsertRedPointAndNotify(uid, num int, module string) { |
||||
red := &common.PlayerRed{UID: uid} |
||||
db.Mysql().Get(red) |
||||
val := reflect.ValueOf(red).Elem().FieldByName(module) |
||||
diff := int(val.Int()) + num |
||||
if red.ID == 0 { |
||||
if diff < 0 { |
||||
diff = 0 |
||||
} |
||||
val.SetInt(int64(diff)) |
||||
db.Mysql().Create(red) |
||||
} else { |
||||
update := map[string]interface{}{} |
||||
if num == 0 || diff <= 0 { |
||||
update[module] = 0 |
||||
val.SetInt(0) |
||||
} else { |
||||
update[module] = gorm.Expr(fmt.Sprintf("%v + ?", strings.ToLower(module)), num) |
||||
val.SetInt(int64(diff)) |
||||
} |
||||
db.Mysql().Update(&common.PlayerRed{UID: uid}, update) |
||||
} |
||||
send := &pb.RedPoint{} |
||||
reflect.ValueOf(send).Elem().FieldByName(module).SetUint(uint64(diff)) |
||||
SendNR(uid, int(pb.ServerCommonResp_CommonRedPointResp), send, "common") |
||||
} |
||||
|
||||
func PushRed(uid int) { |
||||
redPoints := &common.PlayerRed{UID: uid} |
||||
db.Mysql().Get(redPoints) |
||||
checkMail(uid, redPoints) |
||||
one := new(pb.RedPoint) |
||||
one.Mail = uint32(redPoints.Mail) |
||||
SendNR(uid, int(pb.ServerCommonResp_CommonRedPointResp), one, "common") |
||||
} |
||||
@ -0,0 +1,442 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"server/common" |
||||
"server/natsClient" |
||||
"server/pb" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
"github.com/nats-io/nats.go" |
||||
) |
||||
|
||||
var ( |
||||
reloadFuncs = map[int][]func(*pb.ReloadGameConfig) error{} |
||||
) |
||||
|
||||
func LoadConfigs(funcs map[int][]func(*pb.ReloadGameConfig) error) error { |
||||
if funcs == nil { |
||||
funcs = map[int][]func(*pb.ReloadGameConfig) error{} |
||||
} |
||||
CommonReload(funcs) |
||||
for _, v := range funcs { |
||||
for _, k := range v { |
||||
if err := k(nil); err != nil { |
||||
log.Error("err:%v", err) |
||||
// return err
|
||||
} |
||||
} |
||||
} |
||||
reloadFuncs = funcs |
||||
return nil |
||||
} |
||||
|
||||
// LoadSomeConfigs 加载特定配置
|
||||
func LoadSomeConfigs(funcs map[int][]func(*pb.ReloadGameConfig) error) error { |
||||
for _, v := range funcs { |
||||
for _, k := range v { |
||||
if err := k(nil); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
} |
||||
} |
||||
reloadFuncs = funcs |
||||
return nil |
||||
} |
||||
|
||||
func InitReload(conn *nats.Conn) { |
||||
natsClient.NewReloadNats(conn, ReloadConfig) |
||||
} |
||||
|
||||
func ReloadConfig(c *pb.ReloadGameConfig) { |
||||
log.Debug("reload %v", c.Type) |
||||
if fs, ok := reloadFuncs[int(c.Type)]; ok { |
||||
for _, v := range fs { |
||||
if err := v(c); err != nil { |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
func CommonReload(c map[int][]func(*pb.ReloadGameConfig) error) { |
||||
if _, ok := c[common.ReloadWhiteList]; !ok { |
||||
c[common.ReloadWhiteList] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := InitWhite(); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadChannel]; !ok { |
||||
c[common.ReloadChannel] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadChannels(); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadPlatform]; !ok { |
||||
c[common.ReloadPlatform] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigPlatform(); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadNotice]; !ok { |
||||
c[common.ReloadNotice] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigNotice(); err != nil { |
||||
log.Error("从mysql加载公告失败, error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadBroadcast]; !ok { |
||||
c[common.ReloadBroadcast] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigBroadcast(); err != nil { |
||||
log.Error("从mysql加载广播失败, error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivity]; !ok { |
||||
c[common.ReloadConfigActivity] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivity(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigPayProduct]; !ok { |
||||
c[common.ReloadConfigPayProduct] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigPayProduct(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigPayWeight]; !ok { |
||||
c[common.ReloadConfigPayWeight] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigPayChannels(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigWithdrawWeight]; !ok { |
||||
c[common.ReloadConfigWithdrawWeight] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigWithdrawChannels(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigVip]; !ok { |
||||
c[common.ReloadConfigVip] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigVIP(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigTron]; !ok { |
||||
c[common.ReloadConfigTron] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigTron(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigWithdrawProduct]; !ok { |
||||
c[common.ReloadConfigWithdrawProduct] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigWithdrawProduct(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigGameProvider]; !ok { |
||||
c[common.ReloadConfigGameProvider] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadGames(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigGameList]; !ok { |
||||
c[common.ReloadConfigGameList] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadGames(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigGameTypes]; !ok { |
||||
c[common.ReloadConfigGameTypes] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigGameTypes(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigGameMarks]; !ok { |
||||
c[common.ReloadConfigGameMarks] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigGameMarks(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigFirstPageGames]; !ok { |
||||
c[common.ReloadConfigFirstPageGames] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigFirstPageGames(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigRWPer]; !ok { |
||||
c[common.ReloadConfigRWPer] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigRWPer(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigCurrencyRateUSD]; !ok { |
||||
c[common.ReloadConfigCurrencyRateUSD] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigCurrencyRateUSD(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigServerVersion]; !ok { |
||||
c[common.ReloadConfigServerVersion] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadServerVersions(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigGameRoom]; !ok { |
||||
c[common.ReloadConfigGameRoom] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigGameRooms(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigRobot]; !ok { |
||||
c[common.ReloadConfigRobot] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigRobots(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigAppSpin]; !ok { |
||||
c[common.ReloadConfigAppSpin] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigAppSpin(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigShare]; !ok { |
||||
c[common.ReloadConfigShare] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigShare(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigShareSys]; !ok { |
||||
c[common.ReloadConfigShareSys] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigShareSys(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivityPddSpin]; !ok { |
||||
c[common.ReloadConfigActivityPddSpin] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivityPddSpin(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivityPdd]; !ok { |
||||
c[common.ReloadConfigActivityPdd] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivityPdd(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigTask]; !ok { |
||||
c[common.ReloadConfigTask] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigTask(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigCurrencyResource]; !ok { |
||||
c[common.ReloadConfigCurrencyResource] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigCurrencyResource(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigFirstPay]; !ok { |
||||
c[common.ReloadConfigFirstPay] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigFirstPay(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivityFreeSpin]; !ok { |
||||
c[common.ReloadConfigActivityFreeSpin] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivityFreeSpin(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivityFirstRechargeBack]; !ok { |
||||
c[common.ReloadConfigActivityFirstRechargeBack] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivityFirstRechargeBack(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigBanner]; !ok { |
||||
c[common.ReloadConfigBanner] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigBanner(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigLuckyCode]; !ok { |
||||
c[common.ReloadConfigLuckyCode] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivityLuckCode(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivitySign]; !ok { |
||||
c[common.ReloadConfigActivitySign] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivitySign(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivityBreakGift]; !ok { |
||||
c[common.ReloadConfigActivityBreakGift] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivityBreakGift(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigShareRobot]; !ok { |
||||
c[common.ReloadConfigShareRobot] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigShareRobot(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivityWeekCard]; !ok { |
||||
c[common.ReloadConfigActivityWeekCard] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivityWeekCard(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivitySlots]; !ok { |
||||
c[common.ReloadConfigActivitySlots] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivitySlots(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivityLuckyShop]; !ok { |
||||
c[common.ReloadConfigActivityLuckyShop] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivityLuckyShop(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigServerFlag]; !ok { |
||||
c[common.ReloadConfigServerFlag] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigServerFlag(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
if _, ok := c[common.ReloadConfigActivitySevenDayBox]; !ok { |
||||
c[common.ReloadConfigActivitySevenDayBox] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { |
||||
if err := LoadConfigActivitySevenDayBox(); err != nil { |
||||
log.Error("error : [%s]", err.Error()) |
||||
return err |
||||
} |
||||
return nil |
||||
}} |
||||
} |
||||
} |
||||
@ -0,0 +1,155 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"server/common" |
||||
"server/db" |
||||
"server/natsClient" |
||||
"server/pb" |
||||
"server/util" |
||||
"strconv" |
||||
|
||||
"github.com/gogo/protobuf/proto" |
||||
"github.com/liangdas/mqant/gate" |
||||
basegate "github.com/liangdas/mqant/gate/base" |
||||
"github.com/liangdas/mqant/log" |
||||
"github.com/liangdas/mqant/module" |
||||
mqrpc "github.com/liangdas/mqant/rpc" |
||||
"github.com/liangdas/mqant/selector" |
||||
) |
||||
|
||||
var ( |
||||
caller module.Module |
||||
) |
||||
|
||||
// NewCaller 新建一个调用对象
|
||||
func NewCaller(m module.Module) { |
||||
caller = m |
||||
} |
||||
|
||||
func GetCaller() module.Module { |
||||
return caller |
||||
} |
||||
|
||||
func GetTopicName() string { |
||||
name := caller.GetType() |
||||
return name |
||||
} |
||||
|
||||
// SendSS 给玩家发送消息
|
||||
func SendSS(session gate.Session, pid int, data proto.Message, t ...string) error { |
||||
payload := []byte{} |
||||
var err error |
||||
if data != nil { |
||||
payload, err = proto.Marshal(data) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
} |
||||
moduleName := "" |
||||
if t != nil { |
||||
moduleName = t[0] |
||||
} else { |
||||
moduleName = GetTopicName() |
||||
} |
||||
// moduleType := pb.ServerType_name[pb.ModuleType_value[moduleName]]
|
||||
// moduleType := GetModuleID(moduleName)
|
||||
topic := fmt.Sprintf("%v:%v", moduleName, strconv.Itoa(pid)) |
||||
// log.Debug("topic:%v", topic)
|
||||
session.SendNR(topic, payload) |
||||
return nil |
||||
} |
||||
|
||||
// SendSSBytes 给玩家发送消息
|
||||
func SendSSBytes(session gate.Session, pid int, payload []byte) error { |
||||
// moduleType := GetModuleID(caller.GetType())
|
||||
// moduleType := pb.ServerType_name[pb.ModuleType_value[caller.GetType()]]
|
||||
topic := fmt.Sprintf("%v:%v", GetTopicName(), pid) |
||||
session.SendNR(topic, payload) |
||||
return nil |
||||
} |
||||
|
||||
// SendNR 给玩家发送消息 注意:必须先调用NewCaller初始化
|
||||
func SendNR(uid int, pid int, data proto.Message, t ...string) { |
||||
util.Go(func() { |
||||
payload, err := proto.Marshal(data) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
moduleName := "" |
||||
if t != nil { |
||||
moduleName = t[0] |
||||
} else { |
||||
moduleName = GetTopicName() |
||||
} |
||||
// moduleType := GetModuleID(moduleName)
|
||||
// moduleType := pb.ServerType_name[pb.ModuleType_value[moduleName]]
|
||||
topic := fmt.Sprintf("%v:%v", moduleName, pid) |
||||
|
||||
g := GetUserSession(uid) |
||||
if g == nil { |
||||
// log.Error("get session fail")
|
||||
return |
||||
} |
||||
if err := g.Send(topic, payload); err != "" { |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
}) |
||||
} |
||||
|
||||
// Publish 发布消息
|
||||
func Publish(topic string, data proto.Message) error { |
||||
send, _ := proto.Marshal(data) |
||||
err := caller.GetApp().Transport().Publish(topic, send) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// Publish 发布消息
|
||||
func PublishRequest(topic, reply string, data proto.Message) error { |
||||
send, _ := proto.Marshal(data) |
||||
return caller.GetApp().Transport().PublishRequest(topic, reply, send) |
||||
} |
||||
|
||||
// RPC 服务器内部调用
|
||||
func RPC(module, method string, param proto.Message, opts ...selector.SelectOption) (interface{}, string) { |
||||
return caller.GetApp().Call(context.Background(), module, method, mqrpc.Param(param), opts...) |
||||
} |
||||
|
||||
func GetUserSession(uid int) gate.Session { |
||||
s := db.Redis().GetUserSession(uid) |
||||
if s == nil { |
||||
// log.Error("get session fail")
|
||||
return nil |
||||
} |
||||
g, _ := basegate.NewSession(caller.GetApp(), nil) |
||||
g.SetSessionID(s.SessionID) |
||||
g.SetServerID(s.GateID) |
||||
g.SetUserID(strconv.Itoa(uid)) |
||||
return g |
||||
} |
||||
|
||||
// Broadcast 发送广播
|
||||
func BroadcastReq(one *common.ConfigBroadcast, content ...string) { |
||||
c := one.Content |
||||
for _, v := range content { |
||||
c = v |
||||
} |
||||
data := &pb.InnerBroadcast{ |
||||
ID: int32(one.ID), |
||||
Content: c, |
||||
Priority: int32(one.Priority), |
||||
Frequency: int32(one.LoopFrequency), |
||||
Interval: int32(one.Interval), |
||||
} |
||||
// log.Debug("broadcastReq:%+v", data)
|
||||
send, _ := proto.Marshal(data) |
||||
caller.GetApp().Transport().Publish(natsClient.TopicBroadcastReq, send) |
||||
} |
||||
@ -0,0 +1,156 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"fmt" |
||||
"reflect" |
||||
"server/common" |
||||
"server/db" |
||||
"server/pb" |
||||
"server/util" |
||||
"time" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
"gorm.io/gorm" |
||||
) |
||||
|
||||
func GetShareInfo(uid int) *common.ShareInfo { |
||||
shareInfo := &common.ShareInfo{UID: uid} |
||||
db.Mysql().Get(shareInfo) |
||||
if shareInfo.ID <= 0 { |
||||
info, _ := GetUserXInfo(uid, "channel_id") |
||||
shareInfo.ChannelID = info.ChannelID |
||||
shareInfo.Share = util.GetShareCode(uid) |
||||
shareInfo.Time = time.Now().Unix() |
||||
db.Mysql().Create(shareInfo) |
||||
} |
||||
return shareInfo |
||||
} |
||||
|
||||
// 分享查询
|
||||
func ShareBind(share string, isOld bool, uid, cid int) { |
||||
// 绑定
|
||||
if share == "" || isOld { |
||||
return |
||||
} |
||||
// 一级
|
||||
upInfo := &common.ShareInfo{Share: share} |
||||
db.Mysql().Get(upInfo) |
||||
if upInfo.ID <= 0 { |
||||
return |
||||
} |
||||
shareInfo := &common.ShareInfo{UID: uid, UP1: upInfo.UID, UP2: upInfo.UP1, UP3: upInfo.UP2, Time: time.Now().Unix(), ChannelID: cid, Share: util.GetShareCode(uid)} |
||||
db.Mysql().Create(shareInfo) |
||||
|
||||
// 更新上级邀请玩家数
|
||||
db.Mysql().Update(&common.ShareInfo{UID: upInfo.UID}, map[string]interface{}{"invites": gorm.Expr("invites + 1")}) |
||||
} |
||||
|
||||
// 判断分享,发放有效用户奖励
|
||||
func CheckShare(r *common.RechargeOrder) { |
||||
reward := GetConfigShareSys().ShareReward |
||||
if reward <= 0 { |
||||
return |
||||
} |
||||
if r.Amount < GetConfigShareSys().ShareRecharge { |
||||
return |
||||
} |
||||
share := GetShareInfo(r.UID) |
||||
if share.UP1 == 0 { |
||||
return |
||||
} |
||||
// 发放奖励
|
||||
db.Mysql().Update(&common.ShareInfo{UID: share.UP1}, map[string]interface{}{ |
||||
"invalid_invites": gorm.Expr("invalid_invites + 1"), |
||||
"invite_reward": gorm.Expr("invite_reward + ?", reward), |
||||
"available_reward": gorm.Expr("available_reward + ?", reward), |
||||
}) |
||||
} |
||||
|
||||
// 投注奖励结算
|
||||
func ShareSettle(d *pb.InnerAfterSettle) { |
||||
shareInfo := &common.ShareInfo{UID: int(d.UID)} |
||||
db.Mysql().Get(shareInfo) |
||||
if shareInfo.UP1 == 0 { |
||||
return |
||||
} |
||||
db.Mysql().Update(&common.ShareInfo{UID: int(d.UID)}, map[string]interface{}{"bet": gorm.Expr("bet + ?", d.TotalBet)}) |
||||
|
||||
ref := reflect.ValueOf(shareInfo).Elem() |
||||
// 循环查询上级
|
||||
for i := 1; i <= 3; i++ { |
||||
uid := int(ref.FieldByName(fmt.Sprintf("UP%d", i)).Int()) |
||||
if uid == 0 { |
||||
break |
||||
} |
||||
con := GetConfigShareByLevel(i) |
||||
if con == nil { |
||||
log.Error("unknown config share level:%v", i) |
||||
continue |
||||
} |
||||
// 发奖
|
||||
reward := d.TotalBet * con.Per / 1000 |
||||
if reward <= 0 { |
||||
continue |
||||
} |
||||
db.Mysql().Update(&common.ShareInfo{UID: uid}, map[string]interface{}{ |
||||
"bet_reward": gorm.Expr("bet_reward + ?", reward), |
||||
"available_reward": gorm.Expr("available_reward + ?", reward), |
||||
}) |
||||
} |
||||
} |
||||
|
||||
func PackLevelSql(uid, level int) (sql string) { |
||||
if level == 0 { |
||||
sql = fmt.Sprintf("up1 = %d or up2 = %d or up3 = %d", uid, uid, uid) |
||||
} else { |
||||
sql = fmt.Sprintf("up%d = %d", level, uid) |
||||
} |
||||
return |
||||
} |
||||
|
||||
// GetUserShares 查询玩家下级数量
|
||||
func GetUserShares(uid, level int) int64 { |
||||
return db.Mysql().Count(&common.ShareInfo{}, PackLevelSql(uid, level)) |
||||
} |
||||
|
||||
// GetUserShareRecharges 查询玩家下级充值人数
|
||||
func GetUserShareRecharges(uid, level int) (count int64) { |
||||
sql := fmt.Sprintf(`SELECT count(*) as count from
|
||||
(SELECT uid from share_info WHERE %s)a |
||||
INNER JOIN |
||||
(SELECT uid from recharge_info WHERE total_recharge > 0)b |
||||
on a.uid = b.uid`, PackLevelSql(uid, level)) |
||||
err := db.Mysql().C().Raw(sql).Scan(&count).Error |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
return |
||||
} |
||||
|
||||
// GetUserShareValidRecharges 查询玩家下级有效充值人数
|
||||
func GetUserShareValidRecharges(uid, level int) (count int64) { |
||||
sql := fmt.Sprintf(`SELECT count(*) as count from
|
||||
(SELECT uid from share_info WHERE %s)a |
||||
INNER JOIN |
||||
(SELECT uid from recharge_info WHERE total_recharge >= %d)b |
||||
on a.uid = b.uid`, PackLevelSql(uid, level), GetConfigShareSys().ShareRecharge) |
||||
err := db.Mysql().C().Raw(sql).Scan(&count).Error |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
return |
||||
} |
||||
|
||||
// GetUserShareRechargeAmount 查询玩家下级充值总额
|
||||
func GetUserShareRechargeAmount(uid, level int) (count int64) { |
||||
sql := fmt.Sprintf(`SELECT sum(b.total_recharge) as count from
|
||||
(SELECT uid from share_info WHERE %s)a |
||||
INNER JOIN |
||||
(SELECT uid,total_recharge from recharge_info WHERE total_recharge > 0)b |
||||
on a.uid = b.uid`, PackLevelSql(uid, level)) |
||||
err := db.Mysql().C().Raw(sql).Scan(&count).Error |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
return |
||||
} |
||||
@ -0,0 +1,573 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"bytes" |
||||
"encoding/json" |
||||
"fmt" |
||||
"io" |
||||
"io/ioutil" |
||||
"mime/multipart" |
||||
"net/http" |
||||
"net/url" |
||||
"server/common" |
||||
"server/config" |
||||
"server/db" |
||||
"server/util" |
||||
"strconv" |
||||
"strings" |
||||
"time" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
) |
||||
|
||||
// 初始化在线人数上报
|
||||
func InitOnline(f func() []*common.ESNewOnline) { |
||||
now := time.Now() |
||||
zero := util.GetZeroTime(now) |
||||
h, m, _ := now.Clock() |
||||
m -= m % 5 |
||||
lastRecord := zero.Add(time.Duration(h) * time.Hour).Add(time.Duration(m) * time.Minute) |
||||
next := lastRecord.Add(5 * time.Minute).Sub(now) |
||||
time.AfterFunc(next, func() { |
||||
WriteOnline(lastRecord.Add(5*time.Minute).Unix(), f) |
||||
InitOnline(f) |
||||
}) |
||||
} |
||||
|
||||
// WriteOnline 写入在线统计
|
||||
func WriteOnline(time int64, f func() []*common.ESNewOnline) { |
||||
data := f() |
||||
if len(data) == 0 { |
||||
return |
||||
} |
||||
for i := range data { |
||||
if data[i].Total == 0 { |
||||
continue |
||||
} |
||||
data[i].Time = time |
||||
db.ES().InsertToESGO(common.ESIndexBackPlayerOnline, data[i]) |
||||
} |
||||
} |
||||
|
||||
type FBEvents struct { |
||||
EventName string `json:"event_name"` |
||||
EventTime int64 `json:"event_time"` |
||||
UserData struct { |
||||
Em string `json:"em,omitempty"` |
||||
Ph string `json:"ph,omitempty"` |
||||
FN string `json:"fn,omitempty"` |
||||
LN string `json:"ln,omitempty"` |
||||
Country string `json:"country,omitempty"` |
||||
IP string `json:"client_ip_address,omitempty"` |
||||
ClientUserAgent string `json:"client_user_agent"` |
||||
FBC string `json:"fbc,omitempty"` |
||||
FBP string `json:"fbp,omitempty"` |
||||
ExternalID string `json:"external_id,omitempty"` |
||||
CT string `json:"ct,omitempty"` // 城市,哈希处理
|
||||
ST string `json:"st,omitempty"` // 州,哈希处理
|
||||
ZP string `json:"zp,omitempty"` // 邮编,哈希处理
|
||||
} `json:"user_data"` |
||||
CustomData struct { |
||||
Currency string `json:"currency"` |
||||
Value int64 `json:"value"` |
||||
} `json:"custom_data"` |
||||
ActionSource string `json:"action_source"` |
||||
// AppData struct {
|
||||
// AdvertiserTrackingEnabled int `json:"advertiser_tracking_enabled"`
|
||||
// ApplicationTrackingEnabled int `json:"application_tracking_enabled"`
|
||||
// Extinfo []string `json:"extinfo"`
|
||||
// } `json:"app_data"`
|
||||
} |
||||
|
||||
type FBEvent int |
||||
|
||||
const ( |
||||
FBEventRegist FBEvent = iota |
||||
FBEventPurchase |
||||
) |
||||
|
||||
func (f FBEvent) GetName() string { |
||||
switch f { |
||||
case FBEventRegist: |
||||
return "CompleteRegistration" |
||||
case FBEventPurchase: |
||||
return "Purchase" |
||||
default: |
||||
return "" |
||||
} |
||||
} |
||||
|
||||
// UploadFB 上报fb数据
|
||||
func UploadFB(uid int, event FBEvent, amount int64) { |
||||
u := &common.PlayerDBInfo{Id: uid} |
||||
db.Mysql().Get(u) |
||||
|
||||
channel := GetChannelByID(u.ChannelID) |
||||
if channel == nil || channel.FBPixelID == "" || channel.FBAccessToken == "" || config.GetBase().AD.FBAPIURL == "" { |
||||
return |
||||
} |
||||
if channel.ADUpload != common.ADFB { |
||||
return |
||||
} |
||||
|
||||
pi := &common.PayInfo{UID: uid} |
||||
db.Mysql().Get(pi) |
||||
randPi := &common.PayInfo{} |
||||
db.Mysql().C().Raw("SELECT * FROM pay_info ORDER BY RAND() LIMIT 1").Scan(randPi) |
||||
pa := &common.PlayerADData{UID: uid} |
||||
db.Mysql().GetLast(pa) |
||||
if pa.FBC == "" { |
||||
pa = &common.PlayerADData{ChannelID: u.ChannelID} |
||||
db.Mysql().C().Raw("SELECT * FROM player_ad_data ORDER BY RAND() LIMIT 1").Scan(pa) |
||||
} |
||||
// 拿取玩家信息
|
||||
em := pi.Email |
||||
if em == "" { |
||||
em = randPi.Email |
||||
} |
||||
ph := u.Mobile |
||||
if ph == "" { |
||||
ph = randPi.Mobile |
||||
} |
||||
fn, ln := util.FormatUserName(pi.Name) |
||||
if fn == "" { |
||||
fn, ln = util.FormatUserName(randPi.Name) |
||||
} |
||||
ua := "$CLIENT_USER_AGENT" |
||||
if pa.UserAgent != "" { |
||||
ua = pa.UserAgent |
||||
} |
||||
// 分析ip
|
||||
var ct, st, zp string |
||||
ipinfo, err := SearchIP(u.IP) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
} else { |
||||
ct = util.CalculateSHA256(strings.ToLower(ipinfo.City.Names["en"])) |
||||
if len(ipinfo.Subdivisions) > 0 { |
||||
st = util.CalculateSHA256(strings.ToLower(ipinfo.Subdivisions[0].Names["en"])) |
||||
} |
||||
zp = util.CalculateSHA256(strings.ToLower(ipinfo.Postal.Code)) |
||||
} |
||||
util.IndexTry(func() error { |
||||
// 准备事件数据
|
||||
var requestBody bytes.Buffer |
||||
multipartWriter := multipart.NewWriter(&requestBody) |
||||
|
||||
// 添加文本字段
|
||||
events := []FBEvents{{ |
||||
EventName: event.GetName(), |
||||
EventTime: time.Now().Unix(), |
||||
}} |
||||
events[0].UserData.Em = util.CalculateSHA256(strings.ToLower(em)) |
||||
events[0].UserData.Ph = util.CalculateSHA256("91" + ph) |
||||
events[0].UserData.FN = util.CalculateSHA256(strings.ToLower(fn)) |
||||
events[0].UserData.LN = util.CalculateSHA256(strings.ToLower(ln)) |
||||
events[0].UserData.IP = u.IP |
||||
events[0].UserData.ClientUserAgent = ua |
||||
events[0].UserData.FBC = pa.FBC |
||||
events[0].UserData.FBP = pa.FBP |
||||
events[0].UserData.Country = util.CalculateSHA256("in") |
||||
events[0].UserData.ExternalID = util.CalculateSHA256(fmt.Sprintf("%d", uid)) |
||||
events[0].UserData.ST = st |
||||
events[0].UserData.CT = ct |
||||
events[0].UserData.ZP = zp |
||||
events[0].ActionSource = "website" |
||||
if event == FBEventPurchase { |
||||
events[0].CustomData.Currency = "brl" |
||||
events[0].CustomData.Value = amount |
||||
} |
||||
|
||||
evJson, _ := json.Marshal(events) |
||||
err = multipartWriter.WriteField("data", string(evJson)) |
||||
if err != nil { |
||||
log.Error("Error writing text field:%v", err) |
||||
return err |
||||
} |
||||
|
||||
err = multipartWriter.WriteField("access_token", channel.FBAccessToken) |
||||
if err != nil { |
||||
log.Error("Error writing text field:%v", err) |
||||
return err |
||||
} |
||||
multipartWriter.Close() |
||||
|
||||
req, err := http.NewRequest("POST", config.GetBase().AD.FBAPIURL+channel.FBPixelID+"/events?access_token="+channel.FBAccessToken, &requestBody) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
|
||||
// 设置请求头,包括 Content-Type
|
||||
req.Header.Set("Content-Type", multipartWriter.FormDataContentType()) |
||||
// 发送请求
|
||||
client := &http.Client{ |
||||
Timeout: 10 * time.Second, |
||||
} |
||||
log.Debug("UploadFB:%+v", req) |
||||
resp, err := client.Do(req) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
|
||||
defer resp.Body.Close() |
||||
ret, err := io.ReadAll(resp.Body) |
||||
if err != nil { |
||||
log.Error("http read body err:%v", err) |
||||
return err |
||||
} |
||||
log.Debug("fbres:%v", string(ret)) |
||||
return nil |
||||
}) |
||||
} |
||||
|
||||
// UploadAdjust 上报adjust数据
|
||||
func UploadAdjust(event common.AdjustEventType, u *common.PlayerDBInfo, param map[string]string) { |
||||
channel := GetChannelByID(u.ChannelID) |
||||
if channel == nil || (u.ADID == "" && u.GPSADID == "") || channel.AdjustAppToken == "" { |
||||
return |
||||
} |
||||
if channel.ADUpload != common.ADJust { |
||||
return |
||||
} |
||||
util.IndexTry(func() error { |
||||
var err error |
||||
// if u == nil {
|
||||
// u, err = GetUserXInfo("channel_id", "adid", "gps_adid")
|
||||
// if err != nil {
|
||||
// log.Error("err:%v", err)
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
reqURL, _ := url.Parse(config.GetConfig().Web.Adjust.URL) |
||||
params := url.Values{} |
||||
params.Add("app_token", channel.AdjustAppToken) |
||||
params.Add("event_token", channel.GetAdjustEventID(int(event))) |
||||
params.Add("s2s", "1") |
||||
params.Add("created_at", strconv.FormatInt(time.Now().Unix(), 10)) |
||||
params.Add("adid", u.ADID) |
||||
params.Add("gps_adid", u.GPSADID) |
||||
params.Add("web_uuid", u.GPSADID) |
||||
for k, v := range param { |
||||
params.Add(k, v) |
||||
} |
||||
reqURL.RawQuery = params.Encode() |
||||
|
||||
req, err := http.NewRequest("GET", reqURL.String(), nil) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
req.Header.Set("Authorization", "Bearer "+channel.AdjustAuth) |
||||
|
||||
client := &http.Client{ |
||||
Timeout: 5 * time.Second, |
||||
} |
||||
log.Debug("UploadAdjust:%+v", req) |
||||
res, err := client.Do(req) |
||||
if err != nil { |
||||
log.Error("http post call err:%v", err) |
||||
return err |
||||
} |
||||
ret, err := io.ReadAll(res.Body) |
||||
defer res.Body.Close() |
||||
if err != nil { |
||||
log.Error("http read body err:%v", err) |
||||
return err |
||||
} |
||||
log.Debug("adjustRes:%v", string(ret)) |
||||
return nil |
||||
}) |
||||
} |
||||
|
||||
// IsOrganic 查询设备是否是自然量 count 重试次数
|
||||
func IsOrganic(gpsID, appToken string, cid int, count int) (is bool) { |
||||
count-- |
||||
// reqURL, _ := url.Parse(config.GetConfig().Web.Adjust.APIURL)
|
||||
reqURL, _ := url.Parse("https://api.adjust.com/device_service/api/v1/inspect_device") |
||||
params := url.Values{} |
||||
params.Add("advertising_id", gpsID) |
||||
params.Add("app_token", appToken) |
||||
reqURL.RawQuery = params.Encode() |
||||
var lg string |
||||
|
||||
defer func() { |
||||
if count > 0 && is { |
||||
return |
||||
} |
||||
db.ES().InsertToESByIDGO(common.ESIndexBackABLog, fmt.Sprintf("%d_%s", cid, gpsID), &common.ESABLog{ |
||||
Channel: cid, |
||||
Time: time.Now().Unix(), |
||||
DeviceID: gpsID, |
||||
IsA: is, |
||||
Log: lg, |
||||
}) |
||||
}() |
||||
|
||||
req, err := http.NewRequest("GET", reqURL.String(), nil) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
lg = err.Error() |
||||
return |
||||
} |
||||
// req.Header.Set("Authorization", "Bearer "+config.GetConfig().Web.Adjust.APIToken)
|
||||
req.Header.Set("Authorization", "Bearer _2ZGYezfdZ7yD2he-zWx") |
||||
|
||||
client := &http.Client{ |
||||
Timeout: 5 * time.Second, |
||||
} |
||||
log.Debug("check organic:%+v", req) |
||||
res, err := client.Do(req) |
||||
if err != nil { |
||||
log.Error("http post call err:%v", err) |
||||
lg = err.Error() |
||||
return |
||||
} |
||||
if res.Status == http.StatusText(http.StatusNotFound) { |
||||
is = true |
||||
lg = "http not found" |
||||
return |
||||
} |
||||
ret, err := ioutil.ReadAll(res.Body) |
||||
defer res.Body.Close() |
||||
if err != nil { |
||||
log.Error("http read body err:%v", err) |
||||
lg = err.Error() |
||||
return |
||||
} |
||||
log.Debug("AdjustDeviceResp:%v", string(ret)) |
||||
ad := new(AdjustDeviceResp) |
||||
if err := json.Unmarshal(ret, ad); err != nil { |
||||
log.Error("err:%v", err) |
||||
lg = string(ret) |
||||
} |
||||
is = ad.TrackerName == "Organic" |
||||
if is { |
||||
lg = "Organic" |
||||
} |
||||
if is && count > 0 { |
||||
time.Sleep(time.Second) |
||||
return IsOrganic(gpsID, appToken, cid, count) |
||||
} |
||||
return |
||||
} |
||||
|
||||
// IsOrganic2 查询设备是否是自然量(更为严格,凡是找不到设备号的,一律禁止) count 重试次数
|
||||
func IsOrganic2(gpsID, appToken string, cid int, count int) (is bool) { |
||||
count-- |
||||
// reqURL, _ := url.Parse(config.GetConfig().Web.Adjust.APIURL)
|
||||
reqURL, _ := url.Parse("https://api.adjust.com/device_service/api/v1/inspect_device") |
||||
params := url.Values{} |
||||
params.Add("advertising_id", gpsID) |
||||
params.Add("app_token", appToken) |
||||
reqURL.RawQuery = params.Encode() |
||||
var lg string |
||||
|
||||
defer func() { |
||||
if count > 0 && is { |
||||
return |
||||
} |
||||
db.ES().InsertToESByIDGO(common.ESIndexBackABLog, fmt.Sprintf("%d_%s", cid, gpsID), &common.ESABLog{ |
||||
Channel: cid, |
||||
Time: time.Now().Unix(), |
||||
DeviceID: gpsID, |
||||
IsA: is, |
||||
Log: lg, |
||||
}) |
||||
}() |
||||
|
||||
req, err := http.NewRequest("GET", reqURL.String(), nil) |
||||
if err != nil { |
||||
is = true |
||||
log.Error("err:%v", err) |
||||
lg = err.Error() |
||||
return |
||||
} |
||||
// req.Header.Set("Authorization", "Bearer "+config.GetConfig().Web.Adjust.APIToken)
|
||||
req.Header.Set("Authorization", "Bearer _2ZGYezfdZ7yD2he-zWx") |
||||
|
||||
client := &http.Client{ |
||||
Timeout: 5 * time.Second, |
||||
} |
||||
log.Debug("check organic:%+v", req) |
||||
res, err := client.Do(req) |
||||
if err != nil { |
||||
is = true |
||||
log.Error("http post call err:%v", err) |
||||
lg = err.Error() |
||||
return |
||||
} |
||||
if res.Status == http.StatusText(http.StatusNotFound) { |
||||
is = true |
||||
lg = "http not found" |
||||
return |
||||
} |
||||
ret, err := ioutil.ReadAll(res.Body) |
||||
defer res.Body.Close() |
||||
if err != nil { |
||||
is = true |
||||
log.Error("http read body err:%v", err) |
||||
lg = err.Error() |
||||
return |
||||
} |
||||
log.Debug("AdjustDeviceResp2:%v", string(ret)) |
||||
ad := new(AdjustDeviceResp) |
||||
if err := json.Unmarshal(ret, ad); err != nil { |
||||
log.Error("err:%v", err) |
||||
is = true |
||||
lg = string(ret) |
||||
} |
||||
if !is { |
||||
is = ad.TrackerName == "Organic" |
||||
if is { |
||||
lg = "Organic" |
||||
} |
||||
} |
||||
if is && count > 0 { |
||||
time.Sleep(time.Second) |
||||
return IsOrganic2(gpsID, appToken, cid, count) |
||||
} |
||||
return |
||||
} |
||||
|
||||
type AdjustDeviceResp struct { |
||||
Adid string `json:"Adid"` |
||||
AdvertisingID string `json:"AdvertisingId"` |
||||
Tracker string `json:"Tracker"` |
||||
TrackerName string `json:"TrackerName"` |
||||
// ClickTime time.Time `json:"ClickTime"`
|
||||
// InstallTime time.Time `json:"InstallTime"`
|
||||
// LastAppVersion string `json:"LastAppVersion"`
|
||||
// LastAppVersionShort string `json:"LastAppVersionShort"`
|
||||
// LastSessionTime time.Time `json:"LastSessionTime"`
|
||||
// LastEventTimes struct {
|
||||
// Zcqz1Y time.Time `json:"zcqz1y"`
|
||||
// } `json:"LastEventTimes"`
|
||||
// PushToken string `json:"PushToken"`
|
||||
// State string `json:"State"`
|
||||
// InstallState string `json:"InstallState"`
|
||||
// SignatureAcceptanceStatus string `json:"SignatureAcceptanceStatus"`
|
||||
// SignatureVerificationResult string `json:"SignatureVerificationResult"`
|
||||
} |
||||
|
||||
// WriteRealOnline 写入各场次实时在线
|
||||
func WriteRealOnline(field string, f func() map[int]*common.RedisRealOnline) { |
||||
now := time.Now() |
||||
zero := util.GetZeroTime(now) |
||||
h, m, _ := now.Clock() |
||||
m -= m % 5 |
||||
lastRecord := zero.Add(time.Duration(h) * time.Hour).Add(time.Duration(m) * time.Minute) |
||||
next := lastRecord.Add(5 * time.Minute).Sub(now) |
||||
// _, _, s := now.Clock()
|
||||
// next := now.Add(time.Duration(60-s) * time.Second).Sub(now)
|
||||
log.Debug("next real:%v", next) |
||||
time.AfterFunc(next, func() { |
||||
real := f() |
||||
for i, v := range real { |
||||
keyField := fmt.Sprintf("%v", field) |
||||
if i > 0 { |
||||
keyField += fmt.Sprintf(":%v", i) |
||||
} |
||||
key := common.GetRedisKeyOnlineKey(keyField) |
||||
if !db.Redis().Exist(key) { |
||||
if err := db.Redis().HSet(key, v); err != nil { |
||||
log.Error("err:%v", err) |
||||
continue |
||||
} |
||||
if err := db.Redis().Expire(key, next-2*time.Second); err != nil { |
||||
log.Error("err:%v", err) |
||||
continue |
||||
} |
||||
} else { |
||||
if err := db.Redis().HIncrBy(key, "Total", int64(v.Total)); err != nil { |
||||
log.Error("err:%v", err) |
||||
continue |
||||
} |
||||
if err := db.Redis().HIncrBy(key, "New", int64(v.New)); err != nil { |
||||
log.Error("err:%v", err) |
||||
continue |
||||
} |
||||
} |
||||
} |
||||
WriteRealOnline(field, f) |
||||
}) |
||||
} |
||||
|
||||
type KwaiReq struct { |
||||
Clickid string `json:"clickid"` |
||||
EventName string `json:"event_name"` |
||||
PixelID string `json:"pixelId"` |
||||
AccessToken string `json:"access_token"` |
||||
TestFlag bool `json:"testFlag"` |
||||
TrackFlag bool `json:"trackFlag"` |
||||
IsAttributed int `json:"is_attributed"` // 归因标记,此处需写死为1
|
||||
Mmpcode string `json:"mmpcode"` // 标记数据来源,此处需写死为 PL
|
||||
PixelSdkVersion string `json:"pixelSdkVersion"` // 版本信息,此处需写死为,9.9.9
|
||||
Properties string `json:"properties"` |
||||
} |
||||
type KwaiResp struct { |
||||
Result int `json:"result"` // 返回状态码
|
||||
ErrorMsg string `json:"error_msg"` // 返回信息详情
|
||||
} |
||||
|
||||
type KwaiProperties struct { |
||||
Currency string `json:"currency"` |
||||
Price float64 `json:"price"` |
||||
} |
||||
|
||||
const ( |
||||
KwaiEventRegist = iota |
||||
KwaiEventPay |
||||
) |
||||
|
||||
func GetKwaiEventName(event int) string { |
||||
switch event { |
||||
case KwaiEventRegist: |
||||
return "EVENT_COMPLETE_REGISTRATION" |
||||
case KwaiEventPay: |
||||
return "EVENT_PURCHASE" |
||||
} |
||||
return "" |
||||
} |
||||
|
||||
func UploadKwai(uid, event int, amount int64) { |
||||
u := &common.PlayerDBInfo{Id: uid} |
||||
db.Mysql().Get(u) |
||||
channel := GetChannelByID(u.ChannelID) |
||||
if channel == nil || (u.ADID == "" && u.GPSADID == "") || channel.AdjustAppToken == "" { |
||||
return |
||||
} |
||||
if channel.ADUpload != common.ADKwai { |
||||
return |
||||
} |
||||
pa := &common.PlayerADData{UID: uid} |
||||
db.Mysql().GetLast(pa) |
||||
if pa.FBC == "" { |
||||
pa = &common.PlayerADData{ChannelID: u.ChannelID} |
||||
db.Mysql().C().Raw("SELECT * FROM player_ad_data ORDER BY RAND() LIMIT 1").Scan(pa) |
||||
} |
||||
send := &KwaiReq{ |
||||
Clickid: pa.FBC, |
||||
EventName: GetKwaiEventName(event), |
||||
PixelID: channel.FBPixelID, |
||||
AccessToken: channel.FBAccessToken, |
||||
TestFlag: false, |
||||
TrackFlag: !config.GetBase().Release, |
||||
IsAttributed: 1, |
||||
Mmpcode: "PL", |
||||
PixelSdkVersion: "9.9.9", |
||||
} |
||||
if event == KwaiEventPay { |
||||
pro := &KwaiProperties{ |
||||
Currency: "brl", |
||||
Price: float64(amount/1e6) / 100, |
||||
} |
||||
byt, _ := json.Marshal(pro) |
||||
send.Properties = string(byt) |
||||
} |
||||
util.IndexTry(func() error { |
||||
ret := &KwaiResp{} |
||||
return util.HttpPost(config.GetBase().AD.KwaiAPIURL, send, ret, nil) |
||||
}) |
||||
} |
||||
@ -0,0 +1,183 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"fmt" |
||||
"server/common" |
||||
"server/config" |
||||
"server/db" |
||||
"sync" |
||||
"time" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
"github.com/olivere/elastic/v7" |
||||
) |
||||
|
||||
// WhitePass 白名单鉴权
|
||||
func WhitePass(ip, uuid, path string, version, channel int) bool { |
||||
if !IsWhiteOpen(channel, version, path) { |
||||
return true |
||||
} |
||||
log.Debug("check white ip:%v,uuid:%v,path:%v,version:%v,channel:%v", ip, uuid, path, version, channel) |
||||
one := GetWhite(ip, uuid) |
||||
log.Debug("white:%+v", one) |
||||
if one != nil { |
||||
// if one.Version < version {
|
||||
// return false
|
||||
// }
|
||||
return one.PowerPass(path) |
||||
} |
||||
return false |
||||
} |
||||
|
||||
var ( |
||||
ChannelWhiteMap sync.Map |
||||
Whites []*common.WhiteList |
||||
) |
||||
|
||||
const ( |
||||
SysListType = iota // 用作系统开关时的值
|
||||
WhiteListType |
||||
BlackListType |
||||
) |
||||
|
||||
func ReloadWhite(channel, opt int) { |
||||
val, ok := ChannelWhiteMap.Load(channel) |
||||
if !ok { |
||||
return |
||||
} |
||||
w := val.(*common.WhiteList) |
||||
w.LimitType = opt |
||||
} |
||||
|
||||
func IsWhiteOpen(channel, version int, path string) bool { |
||||
val, ok := ChannelWhiteMap.Load(channel) |
||||
if !ok { |
||||
return false |
||||
} |
||||
w := val.(*common.WhiteList) |
||||
if w.LimitType == 2 { |
||||
return false |
||||
} |
||||
// 如果当前版本号大于白名单开启的发布版本,直接全功能限制
|
||||
if version > w.Version { |
||||
return true |
||||
} |
||||
// 如果当前版本小与等于白名单发布版本,只限制部分功能
|
||||
if common.IsLimitMap(path) { |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
|
||||
func GetWhite(ip, uuid string) *common.WhiteList { |
||||
for i, v := range Whites { |
||||
if v.Content == ip || v.Content == uuid { |
||||
return Whites[i] |
||||
} |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func IsWhite(ip, uuid string) bool { |
||||
for _, v := range Whites { |
||||
if ip != "" && v.Content == ip { |
||||
return true |
||||
} |
||||
if uuid != "" && v.Content == uuid { |
||||
return true |
||||
} |
||||
} |
||||
return false |
||||
} |
||||
|
||||
func InitWhite() error { |
||||
one := []*common.WhiteList{} |
||||
if _, err := db.ES().QueryList(common.ESIndexBackWhiteList, 0, 5000, elastic.NewTermQuery("ListType", SysListType), &one); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
for _, v := range one { |
||||
log.Debug("all white:%+v", *v) |
||||
} |
||||
for i := range one { |
||||
ChannelWhiteMap.Store(one[i].Channel, one[i]) |
||||
} |
||||
Whites = []*common.WhiteList{} |
||||
q := elastic.NewBoolQuery() |
||||
// q.MustNot(elastic.NewMatchQuery("ListType", SysListType))
|
||||
q.Must(elastic.NewMatchQuery("ListType", WhiteListType)) |
||||
if _, err := db.ES().QueryList(common.ESIndexBackWhiteList, 0, 5000, q, &Whites); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
for _, v := range Whites { |
||||
log.Debug("all Whites:%+v", *v) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// IsExamine 是否是审核人员
|
||||
func IsExamine(ip string) bool { |
||||
log.Debug("check examine ip:%v", ip) |
||||
return db.ES().Exist(common.ESIndexBackExamineList, ip) |
||||
} |
||||
|
||||
// CheckChannel 检查渠道是否要屏蔽
|
||||
func CheckChannel(cid int, ip string) bool { |
||||
sip, err := SearchIP(ip) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return true |
||||
} |
||||
switch cid { |
||||
case 10002: |
||||
for _, v := range config.GetConfig().Web.PassRegion { |
||||
if sip.Subdivisions[0].Names["en"] == v { |
||||
return true |
||||
} |
||||
} |
||||
} |
||||
return false |
||||
} |
||||
|
||||
// CheckExamine 检查是否进审核服
|
||||
func CheckExamine(version int, ip, gpsID string, channel *common.Channel) (isExamine bool) { |
||||
if IsWhite(ip, "") || common.IsShareChannel(channel.ChannelID) { |
||||
return |
||||
} |
||||
if version == channel.Version { |
||||
log.Debug("examine ip:%v", ip) |
||||
isExamine = true |
||||
db.ES().InsertToESByIDGO(common.ESIndexBackExamineList, ip, &common.ExamineList{Time: time.Now().Unix()}) |
||||
return |
||||
} |
||||
// else if IsExamine(ip) {
|
||||
// isExamine = true
|
||||
// } else
|
||||
if config.GetBase().Release { |
||||
ipInfo, err := SearchIP(ip) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
return |
||||
} |
||||
if ipInfo.Country.IsoCode == "CN" { |
||||
isExamine = true |
||||
return |
||||
} |
||||
} |
||||
if channel.IgnoreOrganic == 2 && len(gpsID) > 0 { |
||||
if IsOrganic(gpsID, channel.AdjustAppToken, channel.ChannelID, 3) { |
||||
var count int64 |
||||
if channel.ChannelID >= 46 { |
||||
count = db.Mysql().Count(&common.PlayerDBInfo{}, fmt.Sprintf("channel_id = %v and deviceid = '%v'", channel.ChannelID, gpsID)) |
||||
} else { |
||||
count = db.Mysql().Count(&common.PlayerDBInfo{}, fmt.Sprintf("channel_id = %v and (deviceid = '%v' or gps_adid = '%v')", channel.ChannelID, gpsID, gpsID)) |
||||
} |
||||
if count == 0 { |
||||
isExamine = true |
||||
return |
||||
} |
||||
} |
||||
} |
||||
return |
||||
} |
||||
@ -0,0 +1,16 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"server/util" |
||||
"time" |
||||
|
||||
timewheel "github.com/liangdas/mqant/module/modules/timer" |
||||
) |
||||
|
||||
func InitTimeWheel(closeSig chan bool) { |
||||
timewheel.GetTimeWheel().Stop() |
||||
timewheel.SetTimeWheel(timewheel.New(100*time.Millisecond, 36)) |
||||
util.Go(func() { |
||||
timewheel.GetTimeWheel().Start(closeSig) |
||||
}) |
||||
} |
||||
@ -0,0 +1,664 @@ |
||||
package call |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"errors" |
||||
"fmt" |
||||
"math/rand" |
||||
"reflect" |
||||
"server/common" |
||||
"server/config" |
||||
"server/db" |
||||
"server/natsClient" |
||||
"server/pb" |
||||
"server/util" |
||||
"strconv" |
||||
"time" |
||||
|
||||
"github.com/liangdas/mqant/log" |
||||
"gorm.io/gorm" |
||||
) |
||||
|
||||
// 查询用户的信息
|
||||
func GetUserInfo(uid int) (ret *common.PlayerDBInfo, err error) { |
||||
ret = db.Redis().GetUserData(uid) |
||||
if ret != nil { |
||||
return |
||||
} |
||||
ret = &common.PlayerDBInfo{Id: uid} |
||||
err = db.Mysql().Get(ret) |
||||
return |
||||
} |
||||
|
||||
// 查询用户的信息
|
||||
func GetUserXInfo(uid int, fields ...string) (ret *common.PlayerDBInfo, err error) { |
||||
ret = new(common.PlayerDBInfo) |
||||
err = db.Redis().GetUserXInfo(uid, ret, fields...) |
||||
if err == nil { |
||||
return |
||||
} |
||||
// sqlFields := []string{}
|
||||
// for _, v := range fields {
|
||||
// sqlFields = append(sqlFields, v)
|
||||
// }
|
||||
ret = &common.PlayerDBInfo{Id: uid} |
||||
err = db.Mysql().SelectField(ret, fields...) |
||||
return |
||||
} |
||||
|
||||
// 查询用户的信息
|
||||
func GetUserXInfoByDB(uid int, fields ...string) (ret *common.PlayerDBInfo, err error) { |
||||
ret = &common.PlayerDBInfo{Id: uid} |
||||
err = db.Mysql().SelectField(ret, fields...) |
||||
return |
||||
} |
||||
|
||||
// UpdateUserXinfo更新玩家信息
|
||||
func UpdateUserXInfo(p *common.PlayerDBInfo, update map[string]interface{}) error { |
||||
if err := db.Mysql().Update(p, update); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
if err := db.Redis().UpdateUserFields(p.Id, update); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// AddUserXInfo 更新玩家某个字段
|
||||
func AddUserXInfo(uid int, field string, value int64, tx ...*gorm.DB) error { |
||||
p := &common.PlayerDBInfo{Id: uid} |
||||
dbUpdate := map[string]interface{}{field: gorm.Expr(fmt.Sprintf("%v + ?", field), value)} |
||||
if tx == nil { |
||||
if err := db.Mysql().Update(p, dbUpdate); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
} else { |
||||
if err := tx[0].Model(p).Where(p).Updates(dbUpdate).Error; err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
} |
||||
if err := db.Redis().HIncrBy(common.GetRedisKeyUser(uid), field, value); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func initPlayer(uid, channel int) { |
||||
db.Mysql().Create(&common.PlayerData{UID: uid}) |
||||
initCoin := GetConfigPlatform().NewPlayerGift |
||||
if initCoin < 0 { |
||||
initCoin = 0 |
||||
} |
||||
db.Mysql().Create(&common.PlayerCurrency{UID: uid, ChannelID: channel, BRL: initCoin}) |
||||
// db.Mysql().C().Table(common.PlayerRechargeTableName).Create(&common.PlayerCurrency{UID: uid, ChannelID: channel})
|
||||
db.Mysql().Create(&common.PlayerProfile{UID: uid, ChannelID: channel, NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, initCoin)}) |
||||
} |
||||
|
||||
func NewUser(info *common.PlayerDBInfo, ip, share, fbc, fbp, agent string) error { |
||||
// if info.AreaCode == "" {
|
||||
// i, err := call.SearchIP(ip)
|
||||
// log.Debug("searchip:%v,res:%v", ip, i)
|
||||
// if err != nil {
|
||||
// log.Error("err:%v", err)
|
||||
// }
|
||||
// id := call.GetCountryIDByCName(i.Country)
|
||||
// log.Debug("i.Country:%v", i.Country)
|
||||
// if id == "" {
|
||||
// id = "US"
|
||||
// }
|
||||
// info.AreaCode = id
|
||||
// }
|
||||
isOld := false |
||||
if config.GetBase().Release && !IsWhite(ip, "") { |
||||
// 首先判断ip
|
||||
// if db.Mysql().Count(&common.PlayerDBInfo{}, fmt.Sprintf("ip = '%s' and channel_id = %d", ip, info.ChannelID)) >= int64(config.GetConfig().Web.MaxPlayerAccountIP) {
|
||||
// log.Debug("ip:%v 创建过多账号", ip)
|
||||
// return errors.New("ip")
|
||||
// }
|
||||
if info.DeviceId != "" { |
||||
if IsBlackListPlayer(&common.BlackList{DeviceID: info.DeviceId, Phone: info.Mobile}) { |
||||
log.Debug("deviceid:%v 在黑名单里", info.DeviceId) |
||||
return errors.New("ip") |
||||
} |
||||
count := db.Mysql().Count(&common.PlayerDBInfo{}, fmt.Sprintf("deviceid = '%v' and channel_id = %d", info.DeviceId, info.ChannelID)) |
||||
isOld = count > 1 |
||||
if count >= int64(config.GetConfig().Web.MaxPlayerAccountIP) { |
||||
log.Debug("deviceid:%v 创建过多账号", info.DeviceId) |
||||
return errors.New("ip") |
||||
} |
||||
} |
||||
} |
||||
|
||||
r := []rune(info.Nick) |
||||
if len(r) > 13 { |
||||
info.Nick = string(r[:13]) |
||||
} |
||||
if info.Avatar == "" { |
||||
info.Avatar = RandomUserAvatar() |
||||
} |
||||
info.Status = common.AccountStatusNormal |
||||
info.Birth = time.Now().Unix() |
||||
info.Country = GetCountry(ip) |
||||
// initCoin := GetConfigPlatform().NewPlayerGift
|
||||
// if info.AccountType == common.PlatformPhone {
|
||||
// initCoin += GetConfigPlatform().BindPhoneGift
|
||||
// }
|
||||
// info.BindCash = initCoin
|
||||
if err := db.Mysql().Create(info); err != nil { |
||||
return err |
||||
} |
||||
// 游客昵称
|
||||
if len(r) < 2 { |
||||
info.Nick = fmt.Sprintf("User%v", info.Id) |
||||
if err := db.Mysql().Update(&common.PlayerDBInfo{Id: info.Id}, map[string]interface{}{"nick": info.Nick}); err != nil { |
||||
log.Error("err:%v", err) |
||||
return err |
||||
} |
||||
} |
||||
uid := info.Id |
||||
cid := info.ChannelID |
||||
// balance := &common.CurrencyBalance{UID: uid, Type: common.CurrencyTypeBindCash,
|
||||
// Event: common.CurrencyEventNewPlayer, Value: initCoin, ChannelID: info.ChannelID,
|
||||
// Balance: initCoin, Time: time.Now().Unix(), Exs1: "NewPlayer"}
|
||||
util.Go(func() { |
||||
initPlayer(uid, cid) |
||||
UploadAdjust(common.AdjustEventNewPlayer, info, nil) |
||||
ShareBind(share, isOld, uid, cid) |
||||
|
||||
// 新手赠送
|
||||
first := config.GetConfig().Web.FreeSpinFirst |
||||
if first > 0 { |
||||
UpdateCurrencyPro(&common.UpdateCurrency{ |
||||
CurrencyBalance: &common.CurrencyBalance{ |
||||
UID: uid, |
||||
Value: first, |
||||
ChannelID: info.ChannelID, |
||||
Type: common.CurrencyBrazil, |
||||
Event: common.CurrencyEventActivityFreeSpin, |
||||
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, first), |
||||
}, |
||||
}) |
||||
} |
||||
FBBind(ip, uid, cid, fbc, fbp, agent) |
||||
UploadFB(uid, FBEventRegist, 0) |
||||
UploadKwai(uid, KwaiEventRegist, 0) |
||||
}) |
||||
|
||||
return nil |
||||
} |
||||
|
||||
// fb绑定
|
||||
func FBBind(ip string, uid, cid int, fbc, fbp, agent string) { |
||||
// 优先ip绑定
|
||||
pa := &common.PlayerADData{IP: ip, ChannelID: cid} |
||||
db.Mysql().GetLast(pa) |
||||
if pa.ID != 0 { |
||||
if pa.UID == 0 { |
||||
db.Mysql().Update(pa, map[string]interface{}{"uid": uid}) |
||||
} else { |
||||
newPa := &common.PlayerADData{UID: uid, IP: ip, ChannelID: cid, FBC: pa.FBC, FBP: pa.FBP, UserAgent: agent} |
||||
db.Mysql().Create(newPa) |
||||
} |
||||
return |
||||
} |
||||
|
||||
// 绑定fb数据
|
||||
if len(fbc) != 0 || len(fbp) != 0 { |
||||
pa := &common.PlayerADData{ChannelID: cid, FBC: fbc, FBP: fbp} |
||||
db.Mysql().GetLast(pa) |
||||
if pa.ID == 0 { |
||||
newPa := &common.PlayerADData{UID: uid, IP: ip, ChannelID: cid, FBC: pa.FBC, FBP: pa.FBP, UserAgent: agent} |
||||
db.Mysql().Create(newPa) |
||||
return |
||||
} |
||||
if pa.UID == 0 { |
||||
db.Mysql().Update(pa, map[string]interface{}{"uid": uid}) |
||||
return |
||||
} |
||||
newPa := &common.PlayerADData{UID: uid, IP: ip, ChannelID: cid, FBC: pa.FBC, FBP: pa.FBP, UserAgent: agent} |
||||
db.Mysql().Create(newPa) |
||||
return |
||||
} |
||||
} |
||||
|
||||
func RandomUserAvatar() string { |
||||
max := GetConfigPlatform().AvatarCount |
||||
if max <= 0 { |
||||
max = 15 |
||||
} |
||||
ran := rand.Intn(max) + 1 |
||||
return strconv.Itoa(ran) |
||||
} |
||||
|
||||
func RandomRobotAvatar() string { |
||||
ranMethod := rand.Intn(100) |
||||
// 30%使用卡通头像
|
||||
if ranMethod < 30 { |
||||
return RandomUserAvatar() |
||||
} |
||||
max := GetConfigPlatform().AvatarCount |
||||
if max <= 0 { |
||||
max = 200 |
||||
} |
||||
ran := rand.Intn(max) |
||||
return strconv.Itoa(ran) |
||||
} |
||||
|
||||
func IsUserNickValid(nick string) bool { |
||||
n := []rune(nick) |
||||
if len(n) < 1 || len(n) > 15 { |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
|
||||
func InsertLoginRecord(uid, channel int, ip string, birth int64, deviceType int) { |
||||
date := time.Now().Format("20060102") |
||||
one := &common.LoginRecord{UID: uid, ChannelID: channel, Date: date} |
||||
db.Mysql().Get(one) |
||||
re := GetRechargeInfo(uid) |
||||
isRecharge := 2 |
||||
if re.TotalRecharge > 0 { |
||||
isRecharge = 1 |
||||
} |
||||
if one.ID > 0 { |
||||
u := &common.LoginRecord{} |
||||
u.ID = one.ID |
||||
db.Mysql().Update(u, map[string]interface{}{"time": time.Now().Unix(), "platform": deviceType, "ip": ip, "is_recharge": isRecharge}) |
||||
return |
||||
} |
||||
one.IP = ip |
||||
one.UID = uid |
||||
one.Date = date |
||||
one.ChannelID = channel |
||||
one.Time = time.Now().Unix() |
||||
one.Platform = deviceType |
||||
one.FirstTime = util.GetZeroTime(time.Unix(birth, 0)).Unix() |
||||
one.IsRecharge = isRecharge |
||||
|
||||
if util.IsSameDayTimeStamp(birth, one.Time) { |
||||
one.Status = common.NewUser |
||||
} else { |
||||
one.Status = common.OldUser |
||||
} |
||||
|
||||
db.Mysql().Create(one) |
||||
} |
||||
|
||||
func GetVIP(uid int) *common.VipData { |
||||
data := &common.VipData{UID: uid} |
||||
err := db.Mysql().Get(data) |
||||
if err == gorm.ErrRecordNotFound { |
||||
re := &common.RechargeInfo{UID: uid} |
||||
db.Mysql().Get(re) |
||||
data.Exp = re.TotalRecharge |
||||
if data.Exp > 0 { |
||||
cons := GetConfigVIP() |
||||
for i := len(cons) - 1; i >= 0; i-- { |
||||
if data.Exp >= cons[i].Exp && cons[i].Exp >= 0 { |
||||
data.Level = cons[i].Level + 1 |
||||
break |
||||
} |
||||
} |
||||
} |
||||
util.Go(func() { |
||||
db.Mysql().Create(data) |
||||
}) |
||||
} else { |
||||
level := GetVipLevel(data.Exp, data.Bet) |
||||
if level != data.Level { |
||||
data.Level = level |
||||
db.Mysql().UpdateRes(&common.VipData{UID: uid}, map[string]interface{}{"level": level}) |
||||
} |
||||
} |
||||
return data |
||||
} |
||||
|
||||
func GetVipCon(uid int) *common.ConfigVIP { |
||||
data := &common.VipData{UID: uid} |
||||
err := db.Mysql().Get(data) |
||||
if err == gorm.ErrRecordNotFound { |
||||
util.Go(func() { |
||||
db.Mysql().Create(data) |
||||
}) |
||||
} |
||||
return GetConfigVIPByLevel(data.Level) |
||||
} |
||||
|
||||
func GetVipLevel(exp, bet int64) int { |
||||
con := GetConfigVIP() |
||||
for i := len(con) - 2; i >= 0; i-- { |
||||
if con[i].Exp > 0 && exp >= con[i].Exp && con[i].Bet > 0 && bet >= con[i].Bet { // 升级
|
||||
return con[i].Level |
||||
} |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
// UpdateVip 增加vip经验
|
||||
func UpdateVip(uid int, exp, bet, settle int64) { |
||||
for i := 0; i < 3; i++ { |
||||
vip := GetVIP(uid) |
||||
update := map[string]interface{}{} |
||||
if exp > 0 { |
||||
update["exp"] = gorm.Expr("exp + ?", exp) |
||||
} |
||||
if bet > 0 { |
||||
update["bet"] = gorm.Expr("bet + ?", bet) |
||||
} |
||||
con := GetVipCon(uid) |
||||
win := bet - settle |
||||
// 刷新返利盈利
|
||||
now := time.Now().Unix() |
||||
reset := false |
||||
if config.GetBase().Release { |
||||
reset = !util.IsSameDayTimeStamp(now, vip.ProfitTime) |
||||
} else { |
||||
reset = util.GetNext5MinUnix()-vip.ProfitTime >= 5*60 |
||||
} |
||||
if reset { |
||||
if con != nil && vip.ProfitTime != 0 { |
||||
update["cashback"] = vip.Profit * con.Cashback / 1000 |
||||
} |
||||
update["profit"] = win |
||||
update["profit_time"] = now |
||||
} else { |
||||
update["profit"] = gorm.Expr("profit + ?", win) |
||||
} |
||||
level := GetVipLevel(vip.Exp+exp, vip.Bet+bet) |
||||
if level != vip.Level { // 升级
|
||||
update["level"] = level |
||||
} |
||||
res := db.Mysql().C().Model(&common.VipData{}).Where("uid = ? and exp = ? and bet = ?", uid, vip.Exp, vip.Bet).Updates(update) |
||||
if res.Error != nil { |
||||
log.Error("err:%v", res.Error) |
||||
} |
||||
if res.RowsAffected > 0 { |
||||
// 通知客户端等级变动
|
||||
if update["level"] != nil { |
||||
SendNR(uid, int(pb.ServerCommonResp_CommonVipResp), &pb.ConfigChangeResp{Type: pb.ConfigChangeType_ConfigVipLevel}, "common") |
||||
} |
||||
break |
||||
} |
||||
} |
||||
} |
||||
|
||||
// IsBlackListPlayer 判断用户是否是黑名单用户
|
||||
func IsBlackListPlayer(data *common.BlackList) bool { |
||||
if GetConfigPlatform().BlackList == 0 { |
||||
return false |
||||
} |
||||
phone := data.Phone |
||||
payAccount := data.PayAccount |
||||
email := data.Email |
||||
deviceID := data.DeviceID |
||||
if phone == "" && payAccount == "" && email == "" && deviceID == "" { |
||||
return false |
||||
} |
||||
sql := "" |
||||
if len(phone) > 0 { |
||||
sql += fmt.Sprintf("phone = '%s' ", phone) |
||||
} |
||||
if len(payAccount) > 0 { |
||||
if len(sql) > 0 { |
||||
sql += fmt.Sprintf("or pay_account = '%s' ", payAccount) |
||||
} else { |
||||
sql += fmt.Sprintf("pay_account = '%s' ", payAccount) |
||||
} |
||||
} |
||||
if len(deviceID) > 0 { |
||||
if len(sql) > 0 { |
||||
sql += fmt.Sprintf("or deviceid = '%s' ", deviceID) |
||||
} else { |
||||
sql += fmt.Sprintf("deviceid = '%s' ", deviceID) |
||||
} |
||||
} |
||||
if len(email) > 0 { |
||||
if len(sql) > 0 { |
||||
sql += fmt.Sprintf("or email = '%s' ", email) |
||||
} else { |
||||
sql += fmt.Sprintf("email = '%s' ", email) |
||||
} |
||||
} |
||||
if len(sql) == 0 { |
||||
return false |
||||
} |
||||
var count int64 |
||||
db.Mysql().C().Model(&common.BlackList{}).Where(sql).Limit(1).Count(&count) |
||||
return count > 0 |
||||
} |
||||
|
||||
// 封号
|
||||
func KickPlayer(uid int) { |
||||
UpdateUserXInfo(&common.PlayerDBInfo{Id: uid}, map[string]interface{}{"status": 2}) |
||||
player, _ := GetUserXInfo(uid, "token") |
||||
if player.Token != "" { |
||||
db.Redis().Delkey(common.GetRedisKeyToken(player.Token)) |
||||
} |
||||
db.Redis().Delkey(common.GetRedisKeyUser(uid)) |
||||
Publish(natsClient.TopicInnerOptPlayer, &pb.InnerOptPlayer{UID: uint32(uid), Opt: common.OptPlayerTypeKick}) |
||||
} |
||||
|
||||
// BlackListAndKick 判断用户是否是黑名单用户并且直接封号
|
||||
func BlackListAndKick(uid int, data *common.BlackList) bool { |
||||
if IsBlackListPlayer(data) { |
||||
KickPlayer(uid) |
||||
db.ES().InsertToESGO(common.ESIndexBackBlackList, &common.ESBlackList{UID: uid, Name: data.Name, |
||||
PayAccount: data.PayAccount, Email: data.Email, Phone: data.Phone, Time: time.Now().Unix()}) |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
|
||||
// GetItems 拉取用户道具
|
||||
func GetItems(uid int) *common.PlayerItems { |
||||
data := &common.PlayerItems{UID: uid} |
||||
err := db.Mysql().Get(data) |
||||
if err == gorm.ErrRecordNotFound { |
||||
util.Go(func() { |
||||
db.Mysql().Create(data) |
||||
}) |
||||
} |
||||
return data |
||||
} |
||||
|
||||
// IsUserBan 判断用户是否被禁
|
||||
func IsUserBan(uid int) bool { |
||||
p, _ := GetUserXInfo(uid, "status") |
||||
return p.Status == common.AccountStatusLimit |
||||
} |
||||
|
||||
// 赢钱账户的总额
|
||||
func GetUserCurrency(uid int, t common.CurrencyType) int64 { |
||||
var ret int64 |
||||
db.Mysql().C().Model(&common.PlayerCurrency{UID: uid}).Select(t.GetCurrencyName()).Scan(&ret) |
||||
return ret |
||||
} |
||||
|
||||
// 获取充值账户的总额
|
||||
func GetUserCurrencyRecharge(uid int, t common.CurrencyType) int64 { |
||||
var pcr int64 |
||||
db.Mysql().C().Table(common.PlayerRechargeTableName).Where("uid = ?", uid).Select(t.GetCurrencyName()).Scan(&pcr) |
||||
return pcr |
||||
} |
||||
|
||||
// 获取充值账户+赢钱账户的总额
|
||||
func GetUserCurrencyTotal(uid int, t common.CurrencyType) int64 { |
||||
var pc, pcr int64 |
||||
db.Mysql().C().Model(&common.PlayerCurrency{UID: uid}).Select(t.GetCurrencyName()).Scan(&pc) |
||||
db.Mysql().C().Table(common.PlayerRechargeTableName).Where("uid = ?", uid).Select(t.GetCurrencyName()).Scan(&pcr) |
||||
return pc + pcr |
||||
} |
||||
|
||||
func GetUserCurrencyFloat(uid int, t common.CurrencyType, num int) float64 { |
||||
var pc, pcr int64 |
||||
if err := db.Mysql().C().Model(&common.PlayerCurrency{UID: uid}).Select(t.GetCurrencyName()).Scan(&pc).Error; err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
if err := db.Mysql().C().Table(common.PlayerRechargeTableName).Where("uid = ?", uid).Select(t.GetCurrencyName()).Scan(&pcr).Error; err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
return util.Decimal(float64(pc+pcr)/common.DecimalDigits, num) |
||||
} |
||||
|
||||
func GetUserCurrencyByName(uid int, currencyName string) int64 { |
||||
pc := &common.PlayerCurrency{UID: uid} |
||||
db.Mysql().Get(pc) |
||||
ref := reflect.ValueOf(pc).Elem().FieldByName(currencyName) |
||||
if ref.IsValid() { |
||||
return ref.Int() |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
func IsNewPlayer(birth int64) bool { |
||||
return time.Now().Unix()-birth < 24*60*60 |
||||
} |
||||
|
||||
func GetPlayerRechargeInfoByCurrency(uid int, t common.CurrencyType) *common.RechargeInfoCurrency { |
||||
reu := &common.RechargeInfoCurrency{} |
||||
tableName := fmt.Sprintf("recharge_info_%s", t.GetCurrencyName()) |
||||
db.Mysql().C().Table(tableName).Where("uid = ?", uid).Scan(reu) |
||||
return reu |
||||
} |
||||
|
||||
func UpdatePlayerRechargeInfoCurrency(uid int, t common.CurrencyType, u map[string]interface{}, tx ...*gorm.DB) error { |
||||
tableName := fmt.Sprintf("recharge_info_%s", t.GetCurrencyName()) |
||||
if len(tx) > 0 { |
||||
return tx[0].Table(tableName).Where("uid = ?", uid).Updates(u).Error |
||||
} |
||||
return db.Mysql().C().Table(tableName).Where("uid = ?", uid).Updates(u).Error |
||||
} |
||||
|
||||
func GetPlayerProfileByCurrency(uid int, t common.CurrencyType) *common.PlayerProfile { |
||||
pp := &common.PlayerProfile{} |
||||
tableName := fmt.Sprintf("player_profile_%s", t.GetCurrencyName()) |
||||
db.Mysql().C().Table(tableName).Where("uid = ?", uid).Scan(pp) |
||||
return pp |
||||
} |
||||
|
||||
func UpdatePlayerProfile(data *common.ESGameData) error { |
||||
t := data.Type |
||||
bet := data.BetAmount |
||||
settle := data.SettleAmount |
||||
uid := data.UID |
||||
var err error |
||||
if data.Channel == 0 || data.Birth == 0 { |
||||
p, _ := GetUserXInfo(uid, "channel_id", "birth") |
||||
data.Channel = p.ChannelID |
||||
data.Birth = p.Birth |
||||
} |
||||
log.Debug("UpdatePlayerProfile:%+v", data) |
||||
|
||||
u := map[string]interface{}{"total_bet": gorm.Expr("total_bet + ?", bet), "total_settle": gorm.Expr("total_settle + ?", settle), |
||||
"total_counts": gorm.Expr("total_counts + 1")} |
||||
if db.Mysql().Exist(&common.PlayerProfile{UID: uid}) { |
||||
// 先更新总数据
|
||||
db.Mysql().Update(&common.PlayerProfile{UID: uid}, u) |
||||
} else { |
||||
db.Mysql().Create(&common.PlayerProfile{UID: uid, ChannelID: data.Channel, TotalBet: bet, TotalCounts: 1, TotalSettle: settle}) |
||||
} |
||||
// if err != nil {
|
||||
// log.Error("err:%v", err)
|
||||
// return err
|
||||
// }
|
||||
UpdateUserNeedBet(uid, data.BetAmount) |
||||
|
||||
// 更新货币数据
|
||||
tableName := fmt.Sprintf("player_profile_%s", t.GetCurrencyName()) |
||||
var count int64 |
||||
db.Mysql().C().Table(tableName).Where("uid = ?", uid).Count(&count) |
||||
if count > 0 { |
||||
u["total_bet"] = gorm.Expr("total_bet + ?", bet) |
||||
u["total_settle"] = gorm.Expr("total_settle + ?", settle) |
||||
err = db.Mysql().C().Table(tableName).Where("uid = ?", uid).Updates(u).Error |
||||
} else { |
||||
err = db.Mysql().C().Table(tableName).Create(&common.PlayerProfile{UID: uid, ChannelID: data.Channel, TotalBet: bet, TotalCounts: 1, TotalSettle: settle}).Error |
||||
} |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
|
||||
util.Go(func() { |
||||
// 更新vip
|
||||
UpdateVip(uid, 0, bet, settle) |
||||
}) |
||||
|
||||
// 写入es
|
||||
data.Time = time.Now().Unix() |
||||
data.IsNew = util.IsSameDayTimeStamp(data.Time, data.Birth) |
||||
db.ES().InsertToESGO(common.ESIndexGameData, data) |
||||
return nil |
||||
} |
||||
|
||||
func GetPlayerData(uid int) *common.PlayerData { |
||||
data := &common.PlayerData{UID: uid} |
||||
db.Mysql().Get(data) |
||||
return data |
||||
} |
||||
|
||||
func GetPlayerPayData(uid int) *common.PlayerPayData { |
||||
data := &common.PlayerPayData{UID: uid} |
||||
db.Mysql().Get(data) |
||||
if data.ID == 0 { |
||||
db.Mysql().Create(data) |
||||
} |
||||
if data.BreakGift != "" { |
||||
err := json.Unmarshal([]byte(data.BreakGift), &data.SubBreakGift) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
} |
||||
} |
||||
return data |
||||
} |
||||
|
||||
func GetUserNeedBet(uid int) int64 { |
||||
pro := &common.PlayerProfile{UID: uid} |
||||
db.Mysql().Get(pro) |
||||
return pro.NeedBet |
||||
} |
||||
|
||||
func GetUserTaskData(uid int) (ret []common.TaskData) { |
||||
if uid == 0 { |
||||
return |
||||
} |
||||
db.Mysql().QueryAll(fmt.Sprintf("uid = %d", uid), "", &common.TaskData{}, &ret) |
||||
return |
||||
} |
||||
|
||||
func GetUserTaskDataByTaskID(uid, taskID int) *common.TaskData { |
||||
data := &common.TaskData{UID: uid, TaskID: taskID} |
||||
db.Mysql().Get(data) |
||||
return data |
||||
} |
||||
|
||||
func UpdateUserNeedBet(uid int, amount int64) { |
||||
util.Go(func() { |
||||
for i := 0; i < 3; i++ { |
||||
pro := &common.PlayerProfile{UID: uid} |
||||
db.Mysql().Get(pro) |
||||
if pro.NeedBet == 0 { |
||||
return |
||||
} |
||||
var rows int64 |
||||
var err error |
||||
if pro.NeedBet < amount { |
||||
rows, err = db.Mysql().UpdateResW(&common.PlayerProfile{}, map[string]interface{}{"need_bet": 0}, fmt.Sprintf("uid = %d and need_bet = %d", uid, pro.NeedBet)) |
||||
} else { |
||||
rows, err = db.Mysql().UpdateResW(&common.PlayerProfile{}, map[string]interface{}{"need_bet": gorm.Expr("need_bet - ?", amount)}, |
||||
fmt.Sprintf("uid = %d and need_bet = %d", uid, pro.NeedBet)) |
||||
} |
||||
if rows == 0 || err != nil { |
||||
log.Error("err:%v", err) |
||||
time.Sleep(time.Second) |
||||
continue |
||||
} |
||||
return |
||||
} |
||||
}) |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,479 @@ |
||||
package common |
||||
|
||||
import ( |
||||
"time" |
||||
) |
||||
|
||||
const ( |
||||
ActivityID = iota + 10000 |
||||
ActivityIDRecharge // 首充活动
|
||||
ActivityIDAppSpin // 下载转盘活动
|
||||
ActivityIDPDD // pdd活动
|
||||
ActivityIDFreeSpin // 每日免费转盘
|
||||
ActivityIDFirstRechargeBack // 首日充值返还
|
||||
ActivityIDLuckyCode // 幸运码活动
|
||||
ActivityIDSign // 签到活动
|
||||
ActivityIDBreakGift // 破产礼包
|
||||
ActivityIDWeekCard // 周卡
|
||||
ActivityIDSlots // slots奖池活动
|
||||
ActivityIDLuckyShop // 幸运商店活动
|
||||
ActivityIDSevenDayBox // 7日签到宝箱
|
||||
ActivityIDSuper // 超级1+2
|
||||
) |
||||
|
||||
const ( |
||||
ActivityDataZero = iota |
||||
ActivityDataClick |
||||
ActivityDataJoin |
||||
ActivityDataAll |
||||
) |
||||
|
||||
// ConfigBanner banner配置
|
||||
type ConfigBanner struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"ID" web:"id"` |
||||
ActivityID int `gorm:"column:activity_id;uniqueIndex:activity_id" json:"ActivityID" web:"activity_id"` |
||||
Sort int `gorm:"column:sort;type:int(11);" json:"Sort" web:"sort"` |
||||
Start int64 `gorm:"column:start;type:bigint(20);" json:"Start" web:"start"` |
||||
End int64 `gorm:"column:end;type:bigint(20);" json:"End" web:"end"` |
||||
IsRelease int `gorm:"column:is_release;type:int(11);default:1;comment:是否开启 1关闭 2开启" json:"IsRelease" web:"is_release"` |
||||
Push int `gorm:"column:push;type:int(11);default:1;comment:是否推送 1不推送 2推送" json:"Push" web:"push"` |
||||
PushFrequency int `gorm:"column:push_frequency;type:int(11);default:1;comment:推送频率" json:"PushFrequency" web:"push_frequency"` |
||||
Type int `gorm:"column:type;type:int(11);default:1;comment:类型" json:"Type" web:"type"` |
||||
Pic string `gorm:"column:pic;type:varchar(255);comment:活动图片" json:"Pic" web:"pic"` |
||||
Data string `gorm:"column:data;type:varchar(255);comment:跳转数据" json:"Data" web:"data"` |
||||
} |
||||
|
||||
func (c *ConfigBanner) TableName() string { |
||||
return "config_banner" |
||||
} |
||||
|
||||
func (s *ConfigBanner) IsValid() bool { |
||||
now := time.Now().Unix() |
||||
if s.IsRelease != 2 || s.Start > now || (s.End < now && s.End > 0) { |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
|
||||
// ConfigActivity
|
||||
type ConfigActivity struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"ID" web:"id"` |
||||
ActivityID int `gorm:"column:activity_id;uniqueIndex:activity_id" json:"ActivityID" web:"activity_id"` |
||||
Sort int `gorm:"column:sort;type:int(11);" json:"Sort" web:"sort"` |
||||
Start int64 `gorm:"column:start;type:bigint(20);" json:"Start" web:"start"` |
||||
End int64 `gorm:"column:end;type:bigint(20);" json:"End" web:"end"` |
||||
IsRelease int `gorm:"column:is_release;type:int(11);default:1;comment:是否开启 1关闭 2开启" json:"IsRelease" web:"is_release"` |
||||
Push int `gorm:"column:push;type:int(11);default:1;comment:是否推送 1推送 2不推送" json:"Push" web:"push"` |
||||
PushFrequency int `gorm:"column:push_frequency;type:int(11);default:1;comment:推送频率" json:"PushFrequency" web:"push_frequency"` |
||||
Type int `gorm:"column:type;type:int(11);default:1;comment:类型" json:"Type" web:"type"` |
||||
Pic string `gorm:"column:pic;type:varchar(255);comment:活动图片" json:"Pic" web:"pic"` |
||||
Data string `gorm:"column:data;type:varchar(255);comment:跳转数据" json:"Data" web:"data"` |
||||
} |
||||
|
||||
func (a *ConfigActivity) TableName() string { |
||||
return "config_activity" |
||||
} |
||||
|
||||
// Expire 判断活动是否可用
|
||||
func (s *ConfigActivity) IsValid() bool { |
||||
now := time.Now().Unix() |
||||
if s.IsRelease != 2 || s.Start > now || (s.End < now && s.End > 0) { |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
|
||||
type PddData struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
Time int64 `gorm:"column:time;type:bigint(20);comment:创建时间"` |
||||
Amount int64 `gorm:"column:amount;type:bigint(20);comment:当前金额"` |
||||
Spin int `gorm:"column:spin;type:int(11);comment:剩余旋转次数"` |
||||
FreeSpinTime int64 `gorm:"column:free_spin_time;type:bigint(20);comment:免费旋转时间"` |
||||
NewRecordTime int64 `gorm:"column:new_record_time;type:bigint(20);comment:判断新邀请用户标记时间"` |
||||
} |
||||
|
||||
func (a *PddData) TableName() string { |
||||
return "pdd_data" |
||||
} |
||||
|
||||
// 拼多多活动转盘物品类型
|
||||
const ( |
||||
ActivityPddItemType = iota |
||||
ActivityPddItemTypeFinish // 直接补齐差额
|
||||
ActivityPddItemTypeCash // 固定金额
|
||||
ActivityPddItemTypeRandomCash // 随机金额
|
||||
ActivityPddItemTypeAll |
||||
) |
||||
|
||||
// ConfigActivityPddSpin 拼多多分享活动转盘配置
|
||||
type ConfigActivityPddSpin struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"ID"` |
||||
AmountDown int64 `gorm:"column:amount_down;type:bigint(20);default:0;uniqueIndex:amount_sort;comment:区间金额下限" web:"amount_down"` |
||||
AmountUp int64 `gorm:"column:amount_up;type:bigint(20);default:0;comment:区间金额上限" web:"amount_up"` |
||||
Type int `gorm:"column:type;type:int(11);default:3;comment:物品类型" web:"type"` |
||||
Amount int64 `gorm:"column:amount;type:bigint(20);default:0;comment:物品数量" web:"amount"` |
||||
Weight int `gorm:"column:weight;type:int(11);default:0;comment:权重" web:"weight"` |
||||
Sort int `gorm:"column:sort;type:int(11);default:0;uniqueIndex:amount_sort;comment:排序" web:"sort"` |
||||
CashDown int64 `gorm:"column:cash_down;type:bigint(20);default:0;comment:当type是随机金额的时候,表示随机金额的下限" web:"cash_down"` |
||||
CashUp int64 `gorm:"column:cash_up;type:bigint(20);default:0;comment:当type是随机金额的时候,表示随机金额的上限" web:"cash_up"` |
||||
} |
||||
|
||||
func (c *ConfigActivityPddSpin) TableName() string { |
||||
return "config_activity_pdd_spin" |
||||
} |
||||
|
||||
// ConfigActivityPdd 拼多多分享活动配置
|
||||
type ConfigActivityPdd struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"` |
||||
WithdrawAmount int64 `gorm:"column:withdraw_amount;type:bigint(20);default:0;comment:可退出门槛" web:"withdraw_amount"` |
||||
AmountDown int64 `gorm:"column:amount_down;type:bigint(20);default:0;comment:随机金额下限" web:"amount_down"` |
||||
AmountUp int64 `gorm:"column:amount_up;type:bigint(20);default:0;comment:随机金额上限" web:"amount_up"` |
||||
Expire int64 `gorm:"column:expire;type:bigint(20);default:0;comment:过期时间,单位分钟" web:"expire"` |
||||
} |
||||
|
||||
func (c *ConfigActivityPdd) TableName() string { |
||||
return "config_activity_pdd" |
||||
} |
||||
|
||||
// ConfigFirstPay 首充奖励配置
|
||||
type ConfigFirstPay struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"` |
||||
Level int `gorm:"column:level;type:int(11);default:0;comment:等级" web:"level"` |
||||
Amount int64 `gorm:"column:amount;type:bigint(20);default:0;comment:充值额度" web:"amount"` |
||||
FirstPer int64 `gorm:"column:first_per;type:bigint(20);default:0;comment:首次充值赠送比例,百分位" web:"first_per"` |
||||
Per int64 `gorm:"column:per;type:bigint(20);default:0;comment:后续充值赠送比例,百分位" web:"per"` |
||||
} |
||||
|
||||
func (c *ConfigFirstPay) TableName() string { |
||||
return "config_first_pay" |
||||
} |
||||
|
||||
// ConfigActivityFreeSpin 每日免费转盘配置
|
||||
type ConfigActivityFreeSpin struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"ID"` |
||||
Type int `gorm:"column:type;type:int(11);default:3;comment:物品类型,对应枚举" web:"type"` |
||||
Amount int64 `gorm:"column:amount;type:bigint(20);default:0;comment:物品数量" web:"amount"` |
||||
Weight int `gorm:"column:weight;type:int(11);default:0;comment:权重" web:"weight"` |
||||
Sort int `gorm:"column:sort;type:int(11);default:0;uniqueIndex:amount_sort;comment:排序" web:"sort"` |
||||
CashDown int64 `gorm:"column:cash_down;type:bigint(20);default:0;comment:当type是随机金额的时候,表示随机金额的下限" web:"cash_down"` |
||||
CashUp int64 `gorm:"column:cash_up;type:bigint(20);default:0;comment:当type是随机金额的时候,表示随机金额的上限" web:"cash_up"` |
||||
} |
||||
|
||||
func (c *ConfigActivityFreeSpin) TableName() string { |
||||
return "config_activity_free_spin" |
||||
} |
||||
|
||||
// 拼多多活动转盘物品类型
|
||||
const ( |
||||
ActivityFreeSpinItem = iota |
||||
ActivityFreeSpinItemNone // 转到无奖励
|
||||
ActivityFreeSpinItemCash // 固定金额
|
||||
ActivityFreeSpinItemRandomCash // 随机金额
|
||||
ActivityFreeSpinItemDoubleCash // 双倍奖励
|
||||
ActivityFreeSpinItemAll |
||||
) |
||||
|
||||
// ActivityFreeSpinData
|
||||
type ActivityFreeSpinData struct { |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
LastSpin int64 `gorm:"column:last_spin;default:0;type:bigint(20);comment:上次旋转时间"` |
||||
} |
||||
|
||||
func (c *ActivityFreeSpinData) TableName() string { |
||||
return "activity_free_spin_data" |
||||
} |
||||
|
||||
// 首次充值后判断间隔
|
||||
const ( |
||||
ActivityFirstRechargeBackTime = 86400 // 一天
|
||||
) |
||||
|
||||
// ConfigActivityFirstRechargeBack 首日充值返还
|
||||
type ConfigActivityFirstRechargeBack struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"ID"` |
||||
MinRecharge int64 `gorm:"column:min_recharge;type:bigint(20);default:10000000000;comment:最低充值额度" web:"min_recharge"` |
||||
MaxBack int64 `gorm:"column:max_back;type:bigint(20);default:-1;comment:最大返还额度" web:"max_back"` |
||||
} |
||||
|
||||
func (c *ConfigActivityFirstRechargeBack) TableName() string { |
||||
return "config_activity_first_recharge_back" |
||||
} |
||||
|
||||
type ActivityFirstRechargeBackData struct { |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
RechargeTime int64 `gorm:"column:recharge_time;type:bigint(20);default:0;comment:首次充值时间"` |
||||
Amount int64 `gorm:"column:amount;type:bigint(20);default:0;comment:总充值金额"` |
||||
Lost int64 `gorm:"column:lost;type:bigint(20);default:0;comment:活动时间内总损失"` |
||||
} |
||||
|
||||
func (c *ActivityFirstRechargeBackData) TableName() string { |
||||
return "activity_first_recharge_back_data" |
||||
} |
||||
|
||||
const ( |
||||
LuckyCodeTypeZero = iota |
||||
LuckyCodeTypeNormal |
||||
LuckyCodeTypeAll |
||||
) |
||||
|
||||
type ConfigActivityLuckyCode struct { |
||||
ID int `gorm:"primarykey"` |
||||
Type int `gorm:"column:type;type:int(11);default:1;comment:类型" web:"type"` |
||||
Reward int64 `gorm:"column:reward;not null;type:bigint(20);comment:奖励的物品" web:"reward"` |
||||
Per int64 `gorm:"column:per;type:int(11);default:60;comment:奖品的权重" web:"per"` |
||||
} |
||||
|
||||
func (c *ConfigActivityLuckyCode) TableName() string { |
||||
return "config_activity_lucky_code" |
||||
} |
||||
|
||||
type ActivityLuckyCodeData struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"` |
||||
Type int `gorm:"column:type;default:1;type:int(11);"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
LastDraw int64 `gorm:"column:last_draw;default:0;type:bigint(20)"` |
||||
} |
||||
|
||||
func (c *ActivityLuckyCodeData) TableName() string { |
||||
return "activity_lucky_code_data" |
||||
} |
||||
|
||||
// 存放每天的兑换码记录
|
||||
type ActivityLuckyCode struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"` |
||||
Type int `gorm:"column:type;default:1;type:int(11);"` |
||||
Code int `gorm:"column:code;default:0;type:int(11)"` |
||||
Date string `gorm:"column:date;default:'';type:varchar(64);uniqueIndex:date;comment:日期"` |
||||
} |
||||
|
||||
func (c *ActivityLuckyCode) TableName() string { |
||||
return "activity_lucky_code" |
||||
} |
||||
|
||||
type ConfigActivitySign struct { |
||||
ID int `gorm:"primarykey"` |
||||
Day int `gorm:"column:day;type:int(11);default:1;comment:签到天数" web:"day"` |
||||
Reward int64 `gorm:"column:reward;not null;type:bigint(20);comment:奖励" web:"reward"` |
||||
Recharge int64 `gorm:"column:recharge;type:bigint(20);default:0;comment:所需充值金额" web:"recharge"` |
||||
} |
||||
|
||||
func (c *ConfigActivitySign) TableName() string { |
||||
return "config_activity_sign" |
||||
} |
||||
|
||||
type ActivitySignData struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;type:int(11);uniqueIndex:uid"` |
||||
Sign int `gorm:"column:sign;type:int(11);comment:签到天数,二进制"` |
||||
Time int64 `gorm:"column:time;type:bigint(20);comment:首次参与时间"` |
||||
} |
||||
|
||||
func (c *ActivitySignData) TableName() string { |
||||
return "activity_sign_data" |
||||
} |
||||
|
||||
type ConfigActivityBreakGift struct { |
||||
ID int `gorm:"primarykey"` |
||||
Level int `gorm:"column:level;type:int(11);default:1;comment:等级" web:"level"` |
||||
RechargeDown int64 `gorm:"column:recharge_down;type:bigint(11);default:1000000000;comment:充值金额下限" web:"recharge_down"` |
||||
RechargeUp int64 `gorm:"column:recharge_up;type:bigint(20);default:2000000000;comment:充值金额上限" web:"recharge_up"` |
||||
CountDown int `gorm:"column:count_down;type:int(11);default:30;comment:倒计时" web:"count_down"` |
||||
ProductID int `gorm:"column:product_id;type:int(11);default:0;comment:商品id" web:"product_id"` |
||||
} |
||||
|
||||
func (c *ConfigActivityBreakGift) TableName() string { |
||||
return "config_activity_break_gift" |
||||
} |
||||
|
||||
type ConfigActivityWeekCard struct { |
||||
ID int `gorm:"primarykey"` |
||||
Level int `gorm:"column:level;type:int(11);default:1;comment:等级" web:"level"` |
||||
ProductID int `gorm:"column:product_id;type:int(11);default:0;comment:商品id" web:"product_id"` |
||||
DayReward int64 `gorm:"column:day_reward;type:bigint(11);default:700000000;comment:每日可领取奖励" web:"day_reward"` |
||||
OriginPrice int64 `gorm:"column:origin_price;type:bigint(11);default:5000000000;comment:显示的原价" web:"origin_price"` |
||||
Day int `gorm:"column:day;type:int(11);default:6;comment:可领取天数" web:"day"` |
||||
Discount int `gorm:"column:discount;type:int(11);default:70;comment:折扣率,百分位" web:"discount"` |
||||
Rebate int `gorm:"column:rebate;type:int(11);default:240;comment:返利率,百分位" web:"rebate"` |
||||
Range string `gorm:"column:range;default:'[2000000000,100000000000]';type:varchar(255);comment:充值可用范围"` |
||||
SubRange []int64 `gorm:"-" json:"-"` |
||||
} |
||||
|
||||
func (c *ConfigActivityWeekCard) TableName() string { |
||||
return "config_activity_week_card" |
||||
} |
||||
|
||||
const ( |
||||
ActivityWeekCardTicketExpireTime = 48 * 3600 // 两个小时
|
||||
) |
||||
|
||||
type ActivityWeekCardData struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;type:int(11);uniqueIndex:ul"` |
||||
Level int `gorm:"column:level;type:int(11);default:0;uniqueIndex:ul;comment:周卡等级"` |
||||
DayReward int64 `gorm:"column:day_reward;type:bigint(11);default:700000000;comment:每日可领取奖励"` |
||||
Day int `gorm:"column:day;type:int(11);default:6;comment:可领取天数"` |
||||
LastDraw int64 `gorm:"column:last_draw;type:bigint(20);default:0;comment:上次领取时间"` |
||||
GetDiscount int `gorm:"column:get_discount;type:tinyint(4);default:0;comment:前面是否已经获得了折扣券"` |
||||
} |
||||
|
||||
func (c *ActivityWeekCardData) TableName() string { |
||||
return "activity_week_card_data" |
||||
} |
||||
|
||||
// 支付时带有一些信息,如折扣券,赋值在recharge_order的extra字段
|
||||
type ActivityRechargeData struct { |
||||
ID int `json:"ID,omitempty"` // 活动id
|
||||
I1 int `json:"I1,omitempty"` // 携带的信息1,不同活动可能含义不同,折扣券活动代表折扣券等级
|
||||
I2 int64 `json:"I2,omitempty"` // 携带信息2,不同活动可能含义不同,折扣券活动代表实际发放金额
|
||||
} |
||||
|
||||
type ConfigActivitySlots struct { |
||||
ID int `gorm:"primarykey"` |
||||
RankDown int `gorm:"column:rank_down;type:int(11);default:1;comment:排名下限" web:"rank_down"` |
||||
RankUp int `gorm:"column:rank_up;type:int(11);default:1;comment:排名上限" web:"rank_up"` |
||||
Reward int64 `gorm:"column:reward;type:bigint(11);default:99900000000;comment:奖励" web:"reward"` |
||||
} |
||||
|
||||
func (c *ConfigActivitySlots) TableName() string { |
||||
return "config_activity_slots" |
||||
} |
||||
|
||||
// 1,2通过对当天日期取余决定
|
||||
type ActivitySlotsData struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;type:int(11);uniqueIndex:uid"` |
||||
Avatar string `gorm:"column:avatar;default:'';type:varchar(255);comment:头像"` |
||||
Nick string `gorm:"column:nick;default:'';type:varchar(255);comment:昵称"` |
||||
Spin int `gorm:"column:spin;type:int(11);default:0;comment:抽奖次数"` |
||||
BestNumber1 int `gorm:"column:best_number1;type:int(11);default:0;comment:抽到的最大的数字1"` |
||||
Time1 int64 `gorm:"column:time1;type:bigint(20);comment:参与时间1"` |
||||
BestNumber2 int `gorm:"column:best_number2;type:int(11);default:0;comment:抽到的最大的数字2"` |
||||
Time2 int64 `gorm:"column:time2;type:bigint(20);comment:参与时间2"` |
||||
Role int `gorm:"column:role;type:int(11);default:0;comment:角色,1代表机器人,2初始默认的机器人"` |
||||
} |
||||
|
||||
func (c *ActivitySlotsData) TableName() string { |
||||
return "activity_slots_data" |
||||
} |
||||
|
||||
// 结算记录
|
||||
type ActivitySlotsRecord struct { |
||||
ID int `gorm:"primarykey"` |
||||
Date string `gorm:"column:date;default:'';type:varchar(255);uniqueIndex:du;comment:日期"` |
||||
UID int `gorm:"column:uid;type:int(11);uniqueIndex:du"` |
||||
Settle int `gorm:"column:settle;type:int(11);default:0;comment:是否结算,1代表已结算"` |
||||
BestNumber int `gorm:"column:best_number;type:int(11);default:0;comment:当日的最大的数字"` |
||||
Reward int64 `gorm:"column:reward;type:bigint(20);default:0;comment:奖励" web:"reward"` |
||||
MyNumber int `gorm:"column:my_number;type:int(11);default:0;comment:玩家的数字"` |
||||
Rank int `gorm:"column:rank;type:int(11);default:0;comment:排名"` |
||||
} |
||||
|
||||
func (c *ActivitySlotsRecord) TableName() string { |
||||
return "activity_slots_Record" |
||||
} |
||||
|
||||
const ( |
||||
ActivityLuckyShopType = iota |
||||
ActivityLuckyShopTypeRechargeLess |
||||
ActivityLuckyShopTypeRechargeMore |
||||
ActivityLuckyShopTypeLogin |
||||
ActivityLuckyShopTypeAll |
||||
) |
||||
|
||||
type ConfigActivityLuckyShop struct { |
||||
ID int `gorm:"primarykey"` |
||||
Type int `gorm:"column:type;type:int(11);default:1;comment:类型,1是首充小于弹出,2是首充大于弹出,3是付费玩家登录弹出" web:"type"` |
||||
Recharge int64 `gorm:"column:recharge;type:bigint(20);default:2000000000;comment:首充玩家弹出的充值额度" web:"recharge"` |
||||
ProductID int `gorm:"column:product_id;type:int(11);default:0;comment:商品id" web:"product_id"` |
||||
} |
||||
|
||||
func (c *ConfigActivityLuckyShop) TableName() string { |
||||
return "config_activity_lucky_shop" |
||||
} |
||||
|
||||
const ( |
||||
ActivityLuckyShopExpire = 2 * 3600 // 2小时过期
|
||||
) |
||||
|
||||
type ActivityLuckyShopData struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:ut"` |
||||
Type int `gorm:"column:type;type:int(11);default:1;uniqueIndex:ut;comment:类型,1是首充小于弹出,2是首充大于弹出,3是付费玩家登录弹出"` |
||||
Push int64 `gorm:"column:push;type:bigint(20);default:0;comment:弹窗弹出时间"` |
||||
Buy int `gorm:"column:buy;type:tinyint(4);default:0;comment:前面是否已经完成购买"` |
||||
ProductID int `gorm:"column:product_id;type:int(11);default:0;comment:商品id"` |
||||
} |
||||
|
||||
func (c *ActivityLuckyShopData) TableName() string { |
||||
return "activity_lucky_shop_data" |
||||
} |
||||
|
||||
func (c *ActivityLuckyShopData) IsValid() bool { |
||||
if c.Buy == 1 { |
||||
return false |
||||
} |
||||
return time.Now().Unix()-c.Push < ActivityLuckyShopExpire |
||||
} |
||||
|
||||
const ( |
||||
ActivitySevenDayBoxType = iota |
||||
ActivitySevenDayBoxTypeCash |
||||
ActivitySevenDayBoxTypeDiscountTicket |
||||
ActivitySevenDayBoxTypeAll |
||||
) |
||||
|
||||
type ConfigActivitySevenDayBox struct { |
||||
ID int `gorm:"primarykey"` |
||||
Recharge int64 `gorm:"column:recharge;type:bigint(20);default:10000000000;comment:充值额度" web:"recharge"` |
||||
Type int `gorm:"column:type;type:int(11);default:1;comment:奖励类型 1金币 2折扣券" web:"type"` |
||||
CashRange string `gorm:"column:cash_range;type:varchar(255);default:[1000000000,2000000000];comment:随机金币范围,当type为1时有用" web:"cash_range"` |
||||
Discount int `gorm:"column:discount;type:int(11);default:70;comment:折扣,type为2时有用" web:"discount"` |
||||
Per int `gorm:"column:per;type:int(11);default:60;comment:概率" web:"per"` |
||||
SubCashRange []int64 `gorm:"-" json:"-"` |
||||
ProductID int `gorm:"column:product_id;type:int(11);default:0;comment:商品id" web:"product_id"` |
||||
} |
||||
|
||||
func (c *ConfigActivitySevenDayBox) TableName() string { |
||||
return "config_activity_seven_day_box" |
||||
} |
||||
|
||||
type ActivitySevenDayBoxData struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
Count int `gorm:"column:count;type:int(11);default:0;comment:剩余开宝箱次数" web:"count"` |
||||
Time int64 `gorm:"column:time;type:bigint(20);comment:购买时间"` |
||||
} |
||||
|
||||
func (c *ActivitySevenDayBoxData) TableName() string { |
||||
return "activity_seven_day_box_data" |
||||
} |
||||
|
||||
type ConfigActivitySuper struct { |
||||
ID int `gorm:"primarykey"` |
||||
Type int `gorm:"column:type;type:int(11);default:1;comment:类型 1新用户 2老用户" web:"type"` |
||||
Recharge int64 `gorm:"column:recharge;type:bigint(20);default:20000000000;comment:充值额度" web:"recharge"` |
||||
Index int `gorm:"column:index;type:int(11);default:1;comment:奖池编号" web:"index"` |
||||
RewardType int `gorm:"column:reward_type;type:bigint(20);default:1;comment:奖励的类型 1金币 2折扣券" web:"reward_type"` |
||||
Reward int64 `gorm:"column:reward;default:0;type:bigint(20);comment:奖励的物品数量(折扣券时为折扣数额)" web:"reward"` |
||||
Sort int `gorm:"column:sort;type:int(11);default:0;comment:排序" web:"sort"` |
||||
Per int `gorm:"column:per;type:int(11);default:60;comment:概率" web:"per"` |
||||
ProductID int `gorm:"column:product_id;type:int(11);default:0;comment:商品id" web:"product_id"` |
||||
} |
||||
|
||||
func (c *ConfigActivitySuper) TableName() string { |
||||
return "config_activity_super" |
||||
} |
||||
|
||||
type ActivitySuperData struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
Open int `gorm:"column:open;default:0;type:int(11);comment:箱子开启情况,二进制"` |
||||
Time int64 `gorm:"column:time;type:bigint(20);comment:购买时间"` |
||||
Type int `gorm:"-"` |
||||
CanBuy bool `gorm:"-"` |
||||
} |
||||
|
||||
func (c *ActivitySuperData) TableName() string { |
||||
return "activity_super_data" |
||||
} |
||||
@ -0,0 +1,539 @@ |
||||
package common |
||||
|
||||
// 重新加载配置的id
|
||||
const ( |
||||
ReloadWhiteList = iota + 1 |
||||
ReloadChannel |
||||
ReloadPlatform |
||||
ReloadNotice |
||||
ReloadBroadcast |
||||
ReloadConfigServerVersion // 服务器版本配置
|
||||
ReloadConfigRWPer // 充提比配置
|
||||
ReloadConfigActivity // 活动配置
|
||||
ReloadConfigPayWeight // 支付渠道权重配置
|
||||
ReloadConfigWithdrawWeight // 退出渠道配置
|
||||
ReloadConfigPayProduct // 商品配置
|
||||
ReloadConfigGameSwitch // 游戏开关配置变动
|
||||
ReloadConfigVip // VIP
|
||||
ReloadConfigH5 // h5配置
|
||||
ReloadConfigTron // tron配置
|
||||
ReloadConfigWithdrawProduct // 退出商品配置
|
||||
ReloadConfigGameList // 游戏列表配置
|
||||
ReloadConfigGameProvider // 游戏提供商配置
|
||||
ReloadConfigGameTypes // 游戏类别配置
|
||||
ReloadConfigGameMarks // 游戏角标配置
|
||||
ReloadConfigFirstPageGames // 首页游戏配置
|
||||
ReloadConfigBroadcast // 广播配置
|
||||
ReloadConfigCurrencyRateUSD // 汇率配置
|
||||
ReloadConfigGameRoom // 房间配置
|
||||
ReloadConfigWater // 水位配置
|
||||
ReloadConfigRobot // 机器人配置
|
||||
ReloadConfigAppSpin // 下载app转盘
|
||||
ReloadConfigShare // 分享相关配置
|
||||
ReloadConfigShareSys // 分享系统相关配置
|
||||
ReloadConfigActivityPddSpin // 拼多多转盘配置
|
||||
ReloadConfigActivityPdd // 拼多多配置
|
||||
ReloadConfigTask // 任务配置
|
||||
ReloadConfigCurrencyResource // 奖励来源配置
|
||||
ReloadConfigFirstPay // 首充配置
|
||||
ReloadConfigActivityFreeSpin // 免费转盘活动
|
||||
ReloadConfigActivityFirstRechargeBack // 首日充值返还
|
||||
ReloadConfigLuckyCode // 幸运码活动
|
||||
ReloadConfigBanner // banner配置
|
||||
ReloadConfigActivitySign // 签到配置
|
||||
ReloadConfigActivityBreakGift // 破产礼包
|
||||
ReloadConfigShareRobot // 分享机器人
|
||||
ReloadConfigActivityWeekCard // 周卡
|
||||
ReloadConfigActivitySlots // slots奖池活动
|
||||
ReloadConfigActivityLuckyShop // 幸运商店活动
|
||||
ReloadConfigServerFlag // 服务器配置
|
||||
ReloadConfigActivitySevenDayBox // 7日宝箱活动
|
||||
ReloadConfigActivitySuper // 超级1+2
|
||||
) |
||||
|
||||
// GetConfigStructByType 获取相应配置的结构
|
||||
func GetConfigStructByType(t int) (interface{}, interface{}) { |
||||
switch t { |
||||
case ReloadConfigRWPer: |
||||
return &ConfigRWPer{}, &[]ConfigRWPer{} |
||||
case ReloadConfigActivity: |
||||
return &ConfigActivity{}, &[]ConfigActivity{} |
||||
case ReloadConfigPayProduct: |
||||
return &ConfigPayProduct{}, &[]ConfigPayProduct{} |
||||
case ReloadConfigPayWeight: |
||||
return &ConfigPayChannels{}, &[]ConfigPayChannels{} |
||||
case ReloadConfigWithdrawWeight: |
||||
return &ConfigWithdrawChannels{}, &[]ConfigWithdrawChannels{} |
||||
case ReloadConfigH5: |
||||
return &ConfigH5{}, &[]ConfigH5{} |
||||
case ReloadConfigTron: |
||||
return &ConfigTron{}, &[]ConfigTron{} |
||||
case ReloadConfigWithdrawProduct: |
||||
return &ConfigWithdrawProduct{}, &[]ConfigWithdrawProduct{} |
||||
case ReloadConfigGameList: |
||||
return &ConfigGameList{}, &[]ConfigGameList{} |
||||
case ReloadConfigGameProvider: |
||||
return &ConfigGameProvider{}, &[]ConfigGameProvider{} |
||||
case ReloadConfigGameTypes: |
||||
return &ConfigGameType{}, &[]ConfigGameType{} |
||||
case ReloadConfigGameMarks: |
||||
return &ConfigGameMark{}, &[]ConfigGameMark{} |
||||
case ReloadConfigFirstPageGames: |
||||
return &ConfigFirstPageGames{}, &[]ConfigFirstPageGames{} |
||||
case ReloadConfigBroadcast: |
||||
return &ConfigBroadcast{}, &[]ConfigBroadcast{} |
||||
case ReloadConfigVip: |
||||
return &ConfigVIP{}, &[]ConfigVIP{} |
||||
case ReloadConfigCurrencyRateUSD: |
||||
return &ConfigCurrencyRateUSD{}, &[]ConfigCurrencyRateUSD{} |
||||
case ReloadConfigGameRoom: |
||||
return &ConfigGameRoom{}, &[]ConfigGameRoom{} |
||||
case ReloadConfigWater: |
||||
return &ConfigWater{}, &[]ConfigWater{} |
||||
case ReloadConfigRobot: |
||||
return &ConfigRobot{}, &[]ConfigRobot{} |
||||
case ReloadConfigAppSpin: |
||||
return &ConfigAppSpin{}, &[]ConfigAppSpin{} |
||||
case ReloadConfigShare: |
||||
return &ConfigShare{}, &[]ConfigShare{} |
||||
case ReloadConfigShareSys: |
||||
return &ConfigShareSys{}, &[]ConfigShareSys{} |
||||
case ReloadConfigActivityPddSpin: |
||||
return &ConfigActivityPddSpin{}, &[]ConfigActivityPddSpin{} |
||||
case ReloadConfigActivityPdd: |
||||
return &ConfigActivityPdd{}, &[]ConfigActivityPdd{} |
||||
case ReloadConfigTask: |
||||
return &ConfigTask{}, &[]ConfigTask{} |
||||
case ReloadConfigCurrencyResource: |
||||
return &ConfigCurrencyResource{}, &[]ConfigCurrencyResource{} |
||||
case ReloadConfigFirstPay: |
||||
return &ConfigFirstPay{}, &[]ConfigFirstPay{} |
||||
case ReloadConfigActivityFreeSpin: |
||||
return &ConfigActivityFreeSpin{}, &[]ConfigActivityFreeSpin{} |
||||
case ReloadConfigActivityFirstRechargeBack: |
||||
return &ConfigActivityFirstRechargeBack{}, &[]ConfigActivityFirstRechargeBack{} |
||||
case ReloadConfigLuckyCode: |
||||
return &ConfigActivityLuckyCode{}, &[]ConfigActivityLuckyCode{} |
||||
case ReloadConfigBanner: |
||||
return &ConfigBanner{}, &[]ConfigBanner{} |
||||
case ReloadConfigActivitySign: |
||||
return &ConfigActivitySign{}, &[]ConfigActivitySign{} |
||||
case ReloadConfigActivityBreakGift: |
||||
return &ConfigActivityBreakGift{}, &[]ConfigActivityBreakGift{} |
||||
case ReloadConfigShareRobot: |
||||
return &ConfigShareRobot{}, &[]ConfigShareRobot{} |
||||
case ReloadConfigActivityWeekCard: |
||||
return &ConfigActivityWeekCard{}, &[]ConfigActivityWeekCard{} |
||||
case ReloadConfigActivitySlots: |
||||
return &ConfigActivitySlots{}, &[]ConfigActivitySlots{} |
||||
case ReloadConfigActivityLuckyShop: |
||||
return &ConfigActivityLuckyShop{}, &[]ConfigActivityLuckyShop{} |
||||
case ReloadConfigServerFlag: |
||||
return &ConfigServerFlag{}, &[]ConfigServerFlag{} |
||||
case ReloadConfigActivitySevenDayBox: |
||||
return &ConfigActivitySevenDayBox{}, &[]ConfigActivitySevenDayBox{} |
||||
case ReloadConfigActivitySuper: |
||||
return &ConfigActivitySuper{}, &[]ConfigActivitySuper{} |
||||
default: |
||||
return nil, nil |
||||
} |
||||
} |
||||
|
||||
// 平台配置
|
||||
// BreakAmount 破产金币
|
||||
// NewPlayerGift 新玩家初始赠送
|
||||
// NewGuideFirst 新手引导初始赠送
|
||||
// NewGuideGift 完成新手引导赠送
|
||||
// BindPhoneGift 绑定手机赠送
|
||||
// WithdrawRecharge 退出需付费的金额
|
||||
// NewControlEnd 新手调控结束阀值
|
||||
type ConfigPlatform struct { |
||||
ID int `gorm:"primarykey"` |
||||
NewPlayerGift int64 `gorm:"column:new_player_gift;type:int(11);default:1000;comment:新玩家赠送金币" json:"NewPlayerGift" web:"new_player_gift"` |
||||
BindPhoneGift int64 `gorm:"column:bind_phone_gift;type:int(11);default:1000;comment:绑定手机赠送" json:"BindPhoneGift" web:"bind_phone_gift"` |
||||
AvatarCount int `gorm:"column:avatar_count;type:int(11);default:400;comment:最大头像数目" json:"AvatarCount" web:"avatar_count"` |
||||
CartoonCount int `gorm:"column:cartoon_count;type:int(11);default:15;comment:卡通头像数目" json:"CartoonCount" web:"cartoon_count"` |
||||
SmsChannel int `gorm:"column:sms_channel;type:int(11);default:1;comment:短信服务商 1Antgst 2Buka" json:"SmsChannel" web:"sms_channel"` |
||||
Telegram string `gorm:"column:telegram;type:varchar(256);default:'+66636640245';comment:客服telegram" json:"Telegram" web:"telegram"` |
||||
Whatsapp string `gorm:"column:whatsapp;type:varchar(256);default:'+66636640245';comment:客服whatsapp" json:"Whatsapp" web:"whatsapp"` |
||||
Email string `gorm:"column:email;type:varchar(256);default:'rummywallah@gmail.com';comment:客服email" json:"Email" web:"email"` |
||||
PayTips string `gorm:"column:pay_tips;type:varchar(256);default:'';comment:充值提示语" json:"PayTips" web:"pay_tips"` |
||||
WithdrawTips string `gorm:"column:withdraw_tips;type:varchar(256);default:'';comment:tx提示语" json:"WithdrawTips" web:"withdraw_tips"` |
||||
BlackList int `gorm:"column:black_list;type:int(11);default:0;comment:是否开启黑名单 0不开 1开启" json:"BlackList" web:"black_list"` |
||||
} |
||||
|
||||
func (c *ConfigPlatform) TableName() string { |
||||
return "config_platform" |
||||
} |
||||
|
||||
const ( |
||||
RWPerTypeZero = iota |
||||
RWPerTypeFirst |
||||
RWPerTypeMulti |
||||
RWPerTypeAll |
||||
) |
||||
|
||||
// ConfigRWPer 充提比配置
|
||||
type ConfigRWPer struct { |
||||
ID int `gorm:"primarykey"` |
||||
Down int64 `gorm:"column:down;type:bigint(20);default:0;comment:充值范围下限" json:"Down" web:"down"` |
||||
Up int64 `gorm:"column:up;type:bigint(20);default:0;comment:充值范围上限" json:"Up" web:"up"` |
||||
Per int64 `gorm:"column:per;type:int(11);default:10;comment:充提比" json:"Per" web:"per"` |
||||
Type int `gorm:"column:type;type:int(11);default:1;comment:类型 1首次 2非首次" json:"Type" web:"type"` |
||||
} |
||||
|
||||
func (c *ConfigRWPer) TableName() string { |
||||
return "config_rwper" |
||||
} |
||||
|
||||
const ( |
||||
PayKindBank = iota + 1 |
||||
PayKindTron |
||||
) |
||||
|
||||
// ConfigPayProduct
|
||||
type ConfigPayProduct struct { |
||||
ID int `gorm:"primarykey"` |
||||
Pic string `gorm:"column:pic;type:varchar(256);default:'';comment:图片" web:"pic"` |
||||
ProductID int `gorm:"column:product_id;type:int(11);default:0;comment:商品id" web:"product_id"` |
||||
ActivityID int `gorm:"column:activityid;type:int(11);default:0;comment:活动id" web:"activityid"` |
||||
Sort int `gorm:"column:sort;type:int(11);default:0;comment:排序" web:"sort"` |
||||
Recommend int `gorm:"column:recommend;type:int(11);default:0;comment:是否推荐 1推荐 2不推荐" web:"recommend"` |
||||
OriginAmount int64 `gorm:"column:origin_amount;type:bigint(20);default:0;comment:显示价格" web:"origin_amount"` |
||||
Amount int64 `gorm:"column:amount;type:bigint(20);default:0;comment:实际价格" web:"amount"` |
||||
Value int64 `gorm:"column:value;type:bigint(20);default:0;comment:发放金额" web:"value"` |
||||
Type CurrencyType `gorm:"column:type;type:int(11);default:1;comment:货币类型" web:"type"` |
||||
IfSell int `gorm:"column:if_sell;type:int(11);default:1;comment:是否上架 1上架 2不上架" web:"if_sell"` |
||||
Kind int `gorm:"column:kind;type:int(11);default:1;comment:支付类型 1银行 2区块链" web:"kind"` |
||||
Exi int `gorm:"column:exi;type:int(11);default:0;comment:商品额外信息" web:"exi"` |
||||
Channels []int `gorm:"-"` |
||||
} |
||||
|
||||
func (c *ConfigPayProduct) TableName() string { |
||||
return "config_pay_product" |
||||
} |
||||
|
||||
// ConfigPayChannels 代收渠道配置
|
||||
type ConfigPayChannels struct { |
||||
ID int `gorm:"primarykey"` |
||||
ChannelID int `gorm:"column:channel_id;not null;type:int(11);uniqueIndex:channel_id" web:"ChannelID"` |
||||
PayPer int `gorm:"column:pay_per;type:int(11);default:0;comment:代收权重" json:"PayPer" web:"pay_per"` |
||||
PayDown int64 `gorm:"column:pay_down;type:bigint(20);default:1;comment:代收下限" json:"PayDown" web:"pay_down"` |
||||
PayUp int64 `gorm:"column:pay_up;type:bigint(20);default:1;comment:代收上限" json:"PayUp" web:"pay_up"` |
||||
CurrencyType CurrencyType `gorm:"column:currency_type;type:bigint(20);default:1;uniqueIndex:channel_id;comment:货币类型" json:"CurrencyType" web:"currency_type"` |
||||
Kind int64 `gorm:"column:kind;type:bigint(20);default:1;comment:协议类型" json:"Kind" web:"kind"` |
||||
} |
||||
|
||||
func (c *ConfigPayChannels) TableName() string { |
||||
return "config_pay_channels" |
||||
} |
||||
|
||||
// ConfigWithdrawChannels 代付渠道配置
|
||||
type ConfigWithdrawChannels struct { |
||||
ID int `gorm:"primarykey"` |
||||
ChannelID int `gorm:"column:channel_id;not null;type:int(11);uniqueIndex:channel_id" web:"ChannelID"` |
||||
WithdrawPer int `gorm:"column:withdraw_per;type:int(11);default:0;comment:代付权重" json:"WithdrawPer" web:"WithdrawPer"` |
||||
PayDown int64 `gorm:"column:pay_down;type:bigint(20);default:1;comment:代收下限" json:"PayDown" web:"pay_down"` |
||||
PayUp int64 `gorm:"column:pay_up;type:bigint(20);default:1;comment:代收上限" json:"PayUp" web:"pay_up"` |
||||
CurrencyType CurrencyType `gorm:"column:currency_type;type:bigint(20);default:1;uniqueIndex:channel_id;comment:货币类型" json:"CurrencyType" web:"currency_type"` |
||||
Kind int64 `gorm:"column:kind;type:bigint(20);default:1;comment:协议类型" json:"Kind" web:"kind"` |
||||
} |
||||
|
||||
func (c *ConfigWithdrawChannels) TableName() string { |
||||
return "config_withdraw_channels" |
||||
} |
||||
|
||||
// ConfigVIP vip配置
|
||||
// Exp 该等级需要的经验值
|
||||
// WithdrawCount 每日可代付次数
|
||||
// Cashback 返利比例(千分位)
|
||||
// Bonus 等级奖励
|
||||
// Bet 升级所需下注额
|
||||
// Fee 代付手续费(千分位)
|
||||
type ConfigVIP struct { |
||||
ID int `gorm:"primarykey;AUTO_INCREMENT;column:id"` |
||||
Level int `gorm:"column:level;not null;type:int(11);default:0;comment:vip等级" json:"Level" web:"level"` |
||||
Exp int64 `gorm:"column:exp;not null;type:bigint(20);default:0;comment:该等级需要的经验值" json:"Exp" web:"exp"` |
||||
WithdrawCount int `gorm:"column:withdraw_count;not null;type:int(11);default:0;comment:每日可代付次数" json:"WithdrawCount" web:"withdraw_count"` |
||||
Cashback int64 `gorm:"column:cashback;type:bigint(20);default:0;comment:返利比例千分位" json:"Cashback" web:"cashback"` |
||||
Bonus int64 `gorm:"column:bonus;type:bigint(20);default:0;comment:等级奖励" json:"Bonus" web:"bonus"` |
||||
Bet int64 `gorm:"column:bet;type:bigint(20);default:0;comment:升级所需下注额" json:"Bet" web:"bet"` |
||||
Fee int64 `gorm:"column:fee;type:bigint(20);default:0;comment:手续费率千分比" json:"Fee" web:"fee"` |
||||
UFee int64 `gorm:"column:u_fee;type:bigint(20);default:0;comment:u手续费(固定值)" json:"UFee" web:"u_fee"` |
||||
} |
||||
|
||||
func (c *ConfigVIP) TableName() string { |
||||
return "config_vip" |
||||
} |
||||
|
||||
// vip商品类型
|
||||
const ( |
||||
VIPProductTypeDay = iota + 1 |
||||
VIPProductTypeWeek |
||||
VIPProductTypeMonth |
||||
) |
||||
|
||||
// H5配置
|
||||
type ConfigH5 struct { |
||||
ID int `gorm:"primarykey"` |
||||
CollectReward int64 `gorm:"column:collect_reward;type:bigint(20);default:0;comment:收藏奖励" web:"collect_reward"` |
||||
DownloadReward int64 `gorm:"column:download_reward;type:bigint(20);default:0;comment:下载奖励" web:"download_reward"` |
||||
} |
||||
|
||||
func (c *ConfigH5) TableName() string { |
||||
return "config_h5" |
||||
} |
||||
|
||||
// ConfigTron
|
||||
type ConfigTron struct { |
||||
ID int `gorm:"primarykey"` |
||||
CurrentBlock int64 `gorm:"column:current_block;type:bigint(20);default:0;comment:当前扫描的区块" web:"current_block"` |
||||
CurrentBlockTest int64 `gorm:"column:current_block_test;type:bigint(20);default:0;comment:当前扫描的区块(测试链)" web:"current_block_test"` |
||||
Rate int64 `gorm:"column:rate;type:bigint(20);default:8193;comment:1U转换成当前货币的汇率,百分位" web:"rate"` |
||||
} |
||||
|
||||
func (c *ConfigTron) TableName() string { |
||||
return "config_tron" |
||||
} |
||||
|
||||
// ConfigWithdrawProduct
|
||||
type ConfigWithdrawProduct struct { |
||||
ID int `gorm:"primarykey"` |
||||
Pic string `gorm:"column:pic;type:varchar(256);default:'';comment:图片" web:"pic"` |
||||
ProductID int `gorm:"column:product_id;type:int(11);default:0;comment:商品id" web:"product_id"` |
||||
Sort int `gorm:"column:sort;type:int(11);default:0;comment:排序" web:"sort"` |
||||
Amount int64 `gorm:"column:amount;type:bigint(20);default:0;comment:金额" web:"amount"` |
||||
Type CurrencyType `gorm:"column:type;type:int(11);default:1;comment:货币类型" web:"type"` |
||||
IfSell int `gorm:"column:if_sell;type:int(11);default:1;comment:是否上架 1上架 2不上架" web:"if_sell"` |
||||
Kind int `gorm:"column:kind;type:int(11);default:1;comment:支付类型 1银行 2区块链" web:"kind"` |
||||
Channels []int `gorm:"-"` |
||||
} |
||||
|
||||
func (c *ConfigWithdrawProduct) TableName() string { |
||||
return "config_withdraw_product" |
||||
} |
||||
|
||||
// ConfigGameList 游戏列表配置
|
||||
// GameID 游戏id
|
||||
// Icon 游戏图标
|
||||
// URL 跳转url
|
||||
// GameProvider 提供商id
|
||||
// Mark 角标
|
||||
// Sort 排序(玩家每玩一次,sort值会自增1)
|
||||
// Jackpot 奖池
|
||||
// Demo 是否支持demo 1支持 2不支持
|
||||
// SubID 一些游戏有子id 如桌子号
|
||||
type ConfigGameList struct { |
||||
ID int `gorm:"primarykey"` |
||||
GameID int `gorm:"column:game_id;not null;type:int(11);uniqueIndex:game;comment:游戏id" web:"game_id"` |
||||
GameCode string `gorm:"column:game_code;type:varchar(255);default:'';comment:一些游戏的唯一识别" web:"game_code"` |
||||
GameType int `gorm:"column:game_type;not null;type:int(11);comment:游戏类别id" web:"game_type"` |
||||
Name string `gorm:"column:name;not null;type:varchar(255);comment:游戏名" web:"name"` |
||||
Icon string `gorm:"column:icon;type:varchar(255);comment:游戏图标" web:"icon"` |
||||
URL string `gorm:"column:url;type:varchar(255);comment:跳转地址" web:"url"` |
||||
GameProvider int `gorm:"column:game_provider;not null;type:int(11);uniqueIndex:game;comment:游戏提供商" web:"game_provider"` |
||||
Mark int `gorm:"column:mark;default:0;type:int(11);comment:角标" web:"mark"` |
||||
Sort uint64 `gorm:"column:sort;type:bigint(20);comment:游戏排序,玩家每玩一次,sort值会自增1" web:"sort"` |
||||
Open int `gorm:"column:open;type:int(11);default:1;comment:是否开启 1开2不开" web:"open"` |
||||
Orientation int `gorm:"column:orientation;type:int(11);default:1;comment:横屏竖屏 1竖屏2横屏3两者都可" web:"orientation"` |
||||
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:"-"` |
||||
} |
||||
|
||||
func (c *ConfigGameList) TableName() string { |
||||
return "config_game_list" |
||||
} |
||||
|
||||
// ConfigGameProvider 游戏提供商配置
|
||||
type ConfigGameProvider struct { |
||||
ID int `gorm:"primarykey"` |
||||
ProviderID int `gorm:"column:provider_id;not null;type:int(11);uniqueIndex:id;comment:游戏提供商id"` |
||||
ProviderName string `gorm:"column:provider_name;type:varchar(255);comment:游戏提供商名称" web:"provider_name"` |
||||
Icon string `gorm:"column:icon;type:varchar(255);comment:供应商图标" web:"icon"` |
||||
Sort int `gorm:"column:sort;type:int(11);comment:供应商排序" web:"sort"` |
||||
Callback string `gorm:"column:callback;type:varchar(255);comment:回调地址" web:"callback"` |
||||
WhiteIPs string `gorm:"column:white_ips;type:varchar(1024);comment:ip白名单" web:"white_ips"` |
||||
SubIp []string `gorm:"-" web:"-"` |
||||
GamesNum int `gorm:"-" web:"-"` |
||||
Open int `gorm:"column:open;type:int(11);default:1;comment:是否开启 1开2不开" web:"open"` |
||||
Show int `gorm:"column:show;type:int(11);default:1;comment:是否显示在banner栏 1显示2不显示" web:"show"` |
||||
Method int `gorm:"column:method;type:int(11);default:1;comment:打开方式 1正常url 2html格式" web:"method"` |
||||
} |
||||
|
||||
func (c *ConfigGameProvider) TableName() string { |
||||
return "config_game_provider" |
||||
} |
||||
|
||||
func (c *ConfigGameProvider) IsIpWhite(ip string) bool { |
||||
if len(c.SubIp) == 0 { |
||||
return true |
||||
} |
||||
for _, v := range c.SubIp { |
||||
if v == ip { |
||||
return true |
||||
} |
||||
} |
||||
return false |
||||
} |
||||
|
||||
type ConfigGameType struct { |
||||
ID int `gorm:"primarykey"` |
||||
TypeID int `gorm:"column:type_id;not null;type:int(11);uniqueIndex:type_id;comment:游戏类别id" web:"type_id"` |
||||
TypeName string `gorm:"column:type_name;type:varchar(64);comment:游戏类别名" web:"type_name"` |
||||
Icon string `gorm:"column:icon;type:varchar(255);comment:游戏类别图标" web:"icon"` |
||||
Sort int `gorm:"column:sort;type:int(11);comment:排序" web:"sort"` |
||||
Open int `gorm:"column:open;type:int(11);default:0;comment:是否打开 1打开" web:"open"` |
||||
} |
||||
|
||||
func (c *ConfigGameType) TableName() string { |
||||
return "config_game_type" |
||||
} |
||||
|
||||
type ConfigGameMark struct { |
||||
ID int `gorm:"primarykey"` |
||||
MarkID int `gorm:"column:mark_id;not null;type:int(11);uniqueIndex:type_id;comment:游戏角标id" web:"mark_id"` |
||||
MarkName string `gorm:"column:mark_name;type:varchar(64);comment:游戏角标名" web:"mark_name"` |
||||
Icon string `gorm:"column:icon;type:varchar(255);comment:游戏角标图标" web:"icon"` |
||||
Sort int `gorm:"column:sort;type:int(11);comment:排序" web:"sort"` |
||||
} |
||||
|
||||
func (c *ConfigGameMark) TableName() string { |
||||
return "config_game_mark" |
||||
} |
||||
|
||||
type ConfigFirstPageGames struct { |
||||
ID int `gorm:"primarykey"` |
||||
Icon string `gorm:"column:icon;type:varchar(255);comment:游戏标题图标" web:"icon"` |
||||
Name string `gorm:"column:name;type:varchar(64);comment:游戏标题名" web:"name"` |
||||
JumpType int `gorm:"column:jump_type;default:1;type:int(11);comment:跳转类型 1type 2mark" web:"jump_type"` |
||||
JumpID int `gorm:"column:jump_id;default:1;type:int(11);comment:跳转查询id" web:"jump_id"` |
||||
Sort int `gorm:"column:sort;type:int(11);comment:排序" web:"sort"` |
||||
Open int `gorm:"column:open;type:int(11);default:0;comment:是否打开 1打开" web:"open"` |
||||
} |
||||
|
||||
func (c *ConfigFirstPageGames) TableName() string { |
||||
return "config_first_page_games" |
||||
} |
||||
|
||||
type ConfigBroadcast struct { |
||||
ID int `gorm:"primarykey"` |
||||
BroadcastID int `gorm:"column:broadcast_id;type:int(11);comment:广播类型id" web:"broadcast_id"` |
||||
Content string `gorm:"column:content;type:varchar(255);comment:广播正文" web:"content"` |
||||
Open int `gorm:"column:open;type:int(11);comment:是否打开 1打开" web:"open"` |
||||
Event int `gorm:"column:event;type:int(11);comment:事件" web:"event"` |
||||
TargetID int `gorm:"column:target_id;type:int(11);comment:跳转id" web:"target_id"` |
||||
Type int `gorm:"column:type;type:int(11);comment:类型" web:"type"` |
||||
Priority int `gorm:"column:priority;type:int(11);comment:优先级" web:"priority"` |
||||
LoopFrequency int `gorm:"column:loop_frequency;type:int(11);comment:循环次数" web:"loop_frequency"` |
||||
Interval int `gorm:"column:interval;type:int(11);comment:间隔" web:"interval"` |
||||
ConditionDown int `gorm:"column:condition_down;type:int(11);comment:触发条件下限" web:"condition_down"` |
||||
ConditionUp int `gorm:"column:condition_up;type:int(11);comment:触发条件上限" web:"condition_up"` |
||||
} |
||||
|
||||
func (c *ConfigBroadcast) TableName() string { |
||||
return "config_broadcast" |
||||
} |
||||
|
||||
type ConfigNotice struct { |
||||
ID int `gorm:"primarykey"` |
||||
Title1 string `gorm:"column:title1;type:varchar(255);comment:标题1" web:"title1"` // 公告标题_1(英语)
|
||||
Content1 string `gorm:"column:content1;type:varchar(255);comment:正文1" web:"content1"` // 公告内容_1(英语)
|
||||
Title2 string `gorm:"column:title2;type:varchar(255);comment:标题2" web:"title2"` // 公告标题_2
|
||||
Content2 string `gorm:"column:content2;type:varchar(255);comment:正文2" web:"content2"` // 公告内容_2
|
||||
Type int `gorm:"column:type;type:int(11);comment:公告类型 (1.紧急 2.常规)" web:"type"` // 公告类型 (1.紧急 2.常规)
|
||||
Open int `gorm:"column:open;type:int(11);comment:是否打开 1打开" web:"open"` // 是否发布
|
||||
Method int `gorm:"column:method;type:int(11);comment:发布方式" web:"method"` // 发布方式
|
||||
Time int64 `gorm:"column:time;type:int(11);comment:发布时间" web:"time"` // 发布时间
|
||||
Interval int `gorm:"column:interval;type:int(11);comment:间隔" web:"interval"` |
||||
PushTimes int `gorm:"column:push_times;type:int(11);comment:推送次数" web:"push_times"` // 推送次数
|
||||
} |
||||
|
||||
func (c *ConfigNotice) TableName() string { |
||||
return "config_notice" |
||||
} |
||||
|
||||
// 货币汇率(各种货币转换成美元的汇率)
|
||||
type ConfigCurrencyRateUSD struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"` |
||||
CurrencyType CurrencyType `gorm:"column:currency_type;type:int(11);default:1;comment:货币类型"` |
||||
Rate int64 `gorm:"column:rate;type:int(11);default:1;comment:汇率(万分位)"` |
||||
RefreshTime int64 `gorm:"column:refresh_time;type:bigint(20);default:0;comment:刷新时间,一天刷一次"` |
||||
} |
||||
|
||||
func (c *ConfigCurrencyRateUSD) TableName() string { |
||||
return "config_currency_rate_usd" |
||||
} |
||||
|
||||
type ConfigGameRoom struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"` |
||||
GameID int `gorm:"column:game_id;type:int(11);default:0;comment:游戏id" web:"game_id"` |
||||
RoomID int `gorm:"column:room_id;type:int(11);default:0;comment:房间id" web:"room_id"` |
||||
RoomName string `gorm:"column:room_name;type:varchar(64);default:0;comment:房间名字" web:"room_name"` |
||||
RoomType int `gorm:"column:room_type;type:int(11);default:0;comment:房间类型 1金币 2练习" web:"room_type"` |
||||
Open bool `gorm:"column:open;type:int(11);default:0;comment:是否开放 0不开 1开" web:"open"` |
||||
Initial int64 `gorm:"column:initial;type:int(11);default:0;comment:初始额度" web:"initial"` |
||||
BetTime int64 `gorm:"column:bet_time;type:int(11);default:0;comment:下注时长" web:"bet_time"` |
||||
SettleTime int64 `gorm:"column:settle_time;type:int(11);default:0;comment:结算时长" web:"settle_time"` |
||||
MaxSeats int `gorm:"column:max_seats;type:int(11);default:0;comment:座位数" web:"max_seats"` |
||||
BetLimitStr string `gorm:"column:bet_limit_str;type:varchar(256);default:'[0]';comment:下注限额数组形式[0,0]" web:"bet_limit_str"` |
||||
BetLimit []int64 `gorm:"-" json:"-"` |
||||
} |
||||
|
||||
func (c *ConfigGameRoom) TableName() string { |
||||
return "config_game_room" |
||||
} |
||||
|
||||
// 水位
|
||||
type ConfigWater struct { |
||||
ID int `gorm:"primarykey"` |
||||
GameID int `gorm:"column:game_id;not null;type:int(11);comment:游戏id" json:"GameID" web:"game_id"` |
||||
RoomID int `gorm:"column:room_id;not null;type:int(11);comment:房间id" json:"RoomID" web:"room_id"` |
||||
WaterLower int64 `gorm:"column:water_lower;not null;type:bigint(20);comment:下水位" json:"WaterLower" web:"water_lower"` |
||||
WaterUp int64 `gorm:"column:water_up;not null;type:bigint(20);comment:上水位" json:"WaterUp" web:"water_up"` |
||||
// ControlPer int `gorm:"column:control_per;not null;type:int(11);comment:控制概率" json:"ControlPer" web:"control_per"`
|
||||
// RebatePer int64 `gorm:"column:rebate_per;not null;type:int(11);comment:返税比例" json:"RebatePer" web:"rebate_per"`
|
||||
Value int64 `gorm:"column:vale;not null;type:bigint(20);comment:当前水位" web:"value"` |
||||
Rtp int64 `gorm:"column:rtp;not null;type:int(11);comment:正常时候的rtp,万分位" web:"rtp"` |
||||
DownRtp int64 `gorm:"column:down_rtp;not null;type:int(11);comment:下水位的rtp,万分位" web:"down_rtp"` |
||||
UpRtp int64 `gorm:"column:up_rtp;not null;type:int(11);comment:上水位的rtp,万分位" web:"up_rtp"` |
||||
} |
||||
|
||||
func (c *ConfigWater) TableName() string { |
||||
return "config_water" |
||||
} |
||||
|
||||
// 机器人
|
||||
type ConfigRobot struct { |
||||
ID int `gorm:"primarykey"` |
||||
Avatar string `gorm:"column:avatar;type:varchar(512);default:''" web:"avatar"` |
||||
Nick string `gorm:"column:nick;type:varchar(512);default:''" web:"nick"` |
||||
} |
||||
|
||||
func (c *ConfigRobot) TableName() string { |
||||
return "config_robot" |
||||
} |
||||
|
||||
// 下载app奖励转盘
|
||||
type ConfigAppSpin struct { |
||||
ID int `gorm:"primarykey"` |
||||
Amount int64 `gorm:"column:amount;type:bigint(20);default:0" web:"amount"` |
||||
CurrencyType CurrencyType `gorm:"column:type;type:int(11);default:1;comment:货币类型" web:"type"` |
||||
Sort int `gorm:"column:sort;type:int(11);default:1;comment:排序" web:"sort"` |
||||
Weight int `gorm:"column:weight;type:int(11);default:1;comment:权重" web:"weight"` |
||||
} |
||||
|
||||
func (c *ConfigAppSpin) TableName() string { |
||||
return "config_app_spin" |
||||
} |
||||
|
||||
// ConfigCurrencyResource 奖励来源配置
|
||||
type ConfigCurrencyResource struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"` |
||||
Type CurrencyRes `gorm:"column:type;type:int(11);default:0;uniqueIndex:type;comment:奖励类型" web:"type"` |
||||
Multiple int64 `gorm:"column:multiple;type:bigint(20);default:2000;comment:所需下注倍数,百分位" web:"multiple"` |
||||
} |
||||
|
||||
func (c *ConfigCurrencyResource) TableName() string { |
||||
return "config_Currency_resource" |
||||
} |
||||
@ -0,0 +1,239 @@ |
||||
package common |
||||
|
||||
import ( |
||||
"fmt" |
||||
"reflect" |
||||
"strconv" |
||||
"strings" |
||||
|
||||
"gorm.io/gorm" |
||||
) |
||||
|
||||
// 货币类型
|
||||
type CurrencyType int |
||||
|
||||
const ( |
||||
CurrencyTypeZero CurrencyType = iota |
||||
CurrencyBrazil |
||||
CurrencyUSDT |
||||
CurrencyAll |
||||
) |
||||
|
||||
type CurrencyRes int |
||||
|
||||
// 货币来源(会影响所需下注量)
|
||||
const ( |
||||
CurrencyResourceZero CurrencyRes = iota |
||||
CurrencyResourceRecharge // 一般充值
|
||||
CurrencyResourceBonus // 额外赠送
|
||||
CurrencyResourceAll |
||||
) |
||||
|
||||
const ( |
||||
USDTKindZero = iota |
||||
USDTKindTRC20 |
||||
USDTKindAll |
||||
) |
||||
|
||||
func (t CurrencyType) IsValid() bool { |
||||
return t > CurrencyTypeZero && t < CurrencyAll |
||||
} |
||||
|
||||
func (t CurrencyType) GetCurrencyName() string { |
||||
return strings.ToLower(reflect.TypeOf(PlayerCurrency{}).Field(int(t + 1)).Name) |
||||
} |
||||
|
||||
func (t CurrencyType) GetRechargeInfoTable() string { |
||||
return fmt.Sprintf("recharge_info_%s", t.GetCurrencyName()) |
||||
} |
||||
|
||||
func GetCurrencyID(currency string) CurrencyType { |
||||
str := strings.ToUpper(currency) |
||||
ref := reflect.ValueOf(PlayerCurrency{}) |
||||
reft := reflect.TypeOf(PlayerCurrency{}) |
||||
for i := 2; i < ref.NumField(); i++ { |
||||
if reft.Field(i).Name == str { |
||||
return CurrencyType(i - 1) |
||||
} |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
type CurrencyEvent int |
||||
|
||||
const ( |
||||
CurrencyEventZero CurrencyEvent = iota // 无意义
|
||||
CurrencyEventNewPlayer // 新注册赠送
|
||||
CurrencyEventGameSettle // 游戏场结算
|
||||
CurrencyEventGameBet // 游戏场牌局模式下注
|
||||
CurrencyEventGameCancelBet // 取消下注
|
||||
CurrencyEventReCharge // 充值
|
||||
CurrencyEventWithDraw // 退出
|
||||
CurrencyEventWithDrawBack // 退出失败退回
|
||||
CurrencyEventMailDraw // 邮件领取
|
||||
CurrencyEventGameVoidSettle // 游戏取消结算
|
||||
CurrencyEventGameActivity // 游戏场活动赠与
|
||||
CurrencyEventGameReSettle // 游戏场调整结算
|
||||
CurrencyEventGameAdjustment // 游戏场调整余额
|
||||
CurrencyEventBindPhone // 绑定手机奖励
|
||||
CurrencyEventVIPBonus // 领取vip等级奖励
|
||||
CurrencyEventVIPCashback // 领取vip返利
|
||||
CurrencyEventActivityAppSpin // 下载app转盘奖励
|
||||
CurrencyEventShareWithdraw // 分享奖励领取
|
||||
CurrencyEventActivityPdd // pdd分享奖励领取
|
||||
CurrencyEventGameAdjustBet // 投注额调整
|
||||
CurrencyEventGameBonus // 游戏场bonus
|
||||
CurrencyEventGameJackpot // 游戏场jackpot
|
||||
CurrencyEventGameBuyIn // 游戏场扣钱操作
|
||||
CurrencyEventGameBuyOut // 游戏场加钱操作
|
||||
CurrencyEventTask // 任务奖励
|
||||
CurrencyEventActivityFreeSpin // 免费旋转
|
||||
CurrencyEventActivityFirstRechargeBack // 首日充值返还
|
||||
CurrencyEventActivityLuckyCode // 兑换码活动
|
||||
CurrencyEventActivitySign // 签到活动
|
||||
CurrencyEventActivityBreakGift // 破产礼包活动
|
||||
CurrencyEventActivityWeekCard // 周卡
|
||||
CurrencyEventActivitySlots // slots奖池
|
||||
CurrencyEventActivitySuper // 超级1+2
|
||||
CurrencyEventAll |
||||
|
||||
CurrencyEventGM = 1000 // 后台修改货币
|
||||
CurrencyEventGMRecharge = 1001 // 后台模拟充值
|
||||
) |
||||
|
||||
func GetCurrencyTypeName(ct CurrencyEvent) string { |
||||
switch ct { |
||||
case CurrencyEventNewPlayer: |
||||
return "新增注册赠送" |
||||
case CurrencyEventGameSettle: |
||||
return "游戏场结算" |
||||
case CurrencyEventGameBet: |
||||
return "游戏场下注" |
||||
case CurrencyEventGameCancelBet: |
||||
return "游戏场取消下注" |
||||
case CurrencyEventReCharge: |
||||
return "充值" |
||||
case CurrencyEventWithDraw: |
||||
return "退出" |
||||
case CurrencyEventWithDrawBack: |
||||
return "退出失败返回" |
||||
case CurrencyEventMailDraw: |
||||
return "邮件领取" |
||||
case CurrencyEventGameVoidSettle: |
||||
return "游戏场取消结算" |
||||
case CurrencyEventGameActivity: |
||||
return "游戏场活动赠与" |
||||
case CurrencyEventGameReSettle: |
||||
return "游戏场调整结算" |
||||
case CurrencyEventGameAdjustment: |
||||
return "游戏场调整余额" |
||||
case CurrencyEventBindPhone: |
||||
return "绑定手机奖励" |
||||
case CurrencyEventVIPBonus: |
||||
return "领取vip等级奖励" |
||||
case CurrencyEventVIPCashback: |
||||
return "领取输钱返利" |
||||
case CurrencyEventActivityAppSpin: |
||||
return "下载转盘奖励" |
||||
case CurrencyEventShareWithdraw: |
||||
return "分享奖励领取" |
||||
case CurrencyEventActivityPdd: |
||||
return "拼多多奖励领取" |
||||
case CurrencyEventGameAdjustBet: |
||||
return "调整投注" |
||||
case CurrencyEventGameBonus: |
||||
return "游戏场bonus奖励" |
||||
case CurrencyEventGameJackpot: |
||||
return "游戏场jackpot奖励" |
||||
case CurrencyEventGameBuyIn: |
||||
return "游戏场扣钱操作" |
||||
case CurrencyEventGameBuyOut: |
||||
return "游戏场加钱操作" |
||||
case CurrencyEventGM: |
||||
return "后台修改货币" |
||||
case CurrencyEventGMRecharge: |
||||
return "后台模拟充值" |
||||
case CurrencyEventTask: |
||||
return "领取任务奖励" |
||||
case CurrencyEventActivityFreeSpin: |
||||
return "免费转盘" |
||||
case CurrencyEventActivityFirstRechargeBack: |
||||
return "首充返还" |
||||
case CurrencyEventActivityLuckyCode: |
||||
return "幸运码活动" |
||||
case CurrencyEventActivitySign: |
||||
return "签到" |
||||
case CurrencyEventActivityBreakGift: |
||||
return "破产礼包活动" |
||||
case CurrencyEventActivityWeekCard: |
||||
return "周卡活动" |
||||
case CurrencyEventActivitySlots: |
||||
return "slots奖池活动" |
||||
case CurrencyEventActivitySuper: |
||||
return "超级1+2活动" |
||||
} |
||||
return strconv.Itoa(int(ct)) |
||||
} |
||||
|
||||
func GetGameEvents() []interface{} { |
||||
return []interface{}{CurrencyEventGameSettle, CurrencyEventGameBet, CurrencyEventGameCancelBet, CurrencyEventGameVoidSettle, |
||||
CurrencyEventGameActivity, CurrencyEventGameReSettle, CurrencyEventGameAdjustment, CurrencyEventGameAdjustBet, |
||||
CurrencyEventGameBonus, CurrencyEventGameJackpot, CurrencyEventGameBuyIn, CurrencyEventGameBuyOut} |
||||
} |
||||
|
||||
// 游戏投入
|
||||
func GetGameInEvents() []interface{} { |
||||
return []interface{}{CurrencyEventGameBet, CurrencyEventGameCancelBet, CurrencyEventGameAdjustBet, CurrencyEventGameBuyIn} |
||||
} |
||||
|
||||
// 游戏产出
|
||||
func GetGameOutEvents() []interface{} { |
||||
return []interface{}{CurrencyEventGameSettle, CurrencyEventGameVoidSettle, |
||||
CurrencyEventGameActivity, CurrencyEventGameReSettle, CurrencyEventGameAdjustment, |
||||
CurrencyEventGameBonus, CurrencyEventGameJackpot, CurrencyEventGameBuyOut} |
||||
} |
||||
|
||||
// RoundCurrency 去除法币的无意义小数位数
|
||||
func RoundCurrency(t CurrencyType, amount int64) int64 { |
||||
switch t { |
||||
case CurrencyBrazil: |
||||
return amount / 1e6 * 1e6 |
||||
case CurrencyUSDT: |
||||
return amount / 100 * 100 |
||||
default: |
||||
return amount |
||||
} |
||||
} |
||||
|
||||
type UpdateCurrency struct { |
||||
NotNotify bool // 为true时不通知客户端
|
||||
Tx *gorm.DB |
||||
*CurrencyBalance |
||||
} |
||||
|
||||
// Time 时间
|
||||
// Value 变化的值
|
||||
// Event 事件
|
||||
// Type 货币类型
|
||||
type CurrencyBalance struct { |
||||
Id int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"id" redis:"id"` |
||||
UID int `gorm:"column:uid" json:"uid"` |
||||
Time int64 `gorm:"column:time" json:"time"` |
||||
Value int64 `gorm:"column:value" json:"value"` |
||||
Balance int64 `gorm:"column:balance;type:bigint(20);default:0" json:"balance"` |
||||
Event CurrencyEvent `gorm:"column:event" json:"event"` |
||||
Type CurrencyType `gorm:"column:type" json:"type"` |
||||
ChannelID int `gorm:"column:channel_id;type:bigint(20);default:1;comment:渠道id" json:"channel_id"` |
||||
NeedBet int64 `gorm:"column:resource;type:bigint(20);default:0;comment:本次流水增加的打码量" json:"need_bet"` |
||||
|
||||
Exi1 int `gorm:"column:exi1;type:bigint(20);default:0;comment:额外int字段1" json:"exi1"` |
||||
Exi2 int `gorm:"column:exi2;type:bigint(20);default:0;comment:额外int字段2" json:"exi2"` |
||||
Exi3 int `gorm:"column:exi3;type:bigint(11);default:0;comment:额外int字段3" json:"exi3"` |
||||
Exs1 string `gorm:"column:exs1;type:varchar(64);comment:额外string字段1" json:"exs1"` |
||||
Exs2 string `gorm:"column:exs2;type:varchar(64);comment:额外string字段2" json:"exs2"` |
||||
Exs3 string `gorm:"column:exs3;type:varchar(64);comment:额外string字段3" json:"exs3"` |
||||
} |
||||
|
||||
func (c *CurrencyBalance) TableName() string { |
||||
return fmt.Sprintf("currency_balance_%02d", c.UID%100) |
||||
} |
||||
@ -0,0 +1,89 @@ |
||||
package common |
||||
|
||||
import "server/pb" |
||||
|
||||
// type Mail struct {
|
||||
// ID int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"id" redis:"id"`
|
||||
// Sender int `gorm:"column:sender;type:int(11);default:0;comment:发件人uid,系统为0" json:"sender" redis:"sender"`
|
||||
// Receiver int `gorm:"column:receiver;type:int(11);default:0;comment:收件人uid,系统为0" json:"receiver" redis:"receiver"`
|
||||
// }
|
||||
|
||||
const ( |
||||
MailExpireTime = 30 * 24 * 60 * 60 // 30天
|
||||
MailMaxCount = 100 |
||||
) |
||||
|
||||
const ( |
||||
MailTypeNormal = iota + 1 |
||||
MailTypeUrgent |
||||
) |
||||
|
||||
const ( |
||||
MailSendMethodImmediately = iota + 1 |
||||
MailSendMethodTiming |
||||
) |
||||
|
||||
const ( |
||||
MailStatusDelete = iota |
||||
MailStatusNew |
||||
MailStatusRead |
||||
MailStatusDraw |
||||
) |
||||
|
||||
// Mail 邮件
|
||||
// DraftID 发送邮件的模板id
|
||||
// sender 发件人
|
||||
// Receiver 收件人uid 0是系统邮件
|
||||
// Type 邮件类型 1跳转游戏
|
||||
// Status 邮件状态 0删除 1未读 2已读未领取 3已领取
|
||||
// Time 收到邮件的时间
|
||||
type Mail struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"ID"` |
||||
DraftID string `gorm:"column:draft_id;type:varchar(256);comment:发送邮件的模板id" json:"DraftID"` |
||||
Sender string `gorm:"column:sender;type:varchar(64);default:0;comment:发件人名称" json:"Sender"` |
||||
Receiver int `gorm:"column:receiver;type:int(11);default:0;comment:收件人uid,系统为0" json:"Receiver"` |
||||
Tag int `gorm:"column:tag;type:int(11);default:1;comment:页签 1平台 2个人" json:"Tag"` |
||||
Type int `gorm:"column:type;type:int(11);default:0;comment:邮件类型 1正常 2紧急" json:"Type"` |
||||
Data string `gorm:"column:data;type:varchar(512);default:'';comment:数据" json:"Data"` |
||||
Title string `gorm:"column:title;type:varchar(256);default:0;comment:标题" json:"Title"` |
||||
Content string `gorm:"column:content;type:varchar(512);default:0;comment:正文" json:"Content"` |
||||
Status int `gorm:"column:status;type:tinyint(4);default:1;comment:邮件状态 0删除 1未读 2已读未领取 3已领取" json:"Status"` |
||||
Time int64 `gorm:"column:time;type:bigint(20);default:0;comment:收到邮件时间" json:"Time"` |
||||
} |
||||
|
||||
func (u *Mail) TableName() string { |
||||
return "mail" |
||||
} |
||||
|
||||
const ( |
||||
MailDraftStatusDelete = iota |
||||
MailDraftStatusNew |
||||
MailDraftStatusSent |
||||
MailDraftStatusBack // 撤销
|
||||
) |
||||
|
||||
// MailDraft 邮件草稿
|
||||
// ID 草稿ID
|
||||
// sender 发件人
|
||||
// Receiver 收件人uid(可以是数组),空数组代表所有人
|
||||
// Type 邮件类型 1正常 2紧急
|
||||
// Enclosure 附件
|
||||
// SendMethod 发送方式 1立刻 2定时
|
||||
// SendTime 发送时间
|
||||
// Status 邮件状态 0删除 1未发送 2已发送 3已撤销
|
||||
// Operator 操作人
|
||||
// Time 创建或修改的时间戳
|
||||
type MailDraft struct { |
||||
ID string |
||||
Sender string |
||||
Receiver []int |
||||
Type int |
||||
Title string |
||||
Content string |
||||
Enclosure []*pb.CurrencyPair |
||||
SendMethod int |
||||
SendTime int64 |
||||
Status int |
||||
Operator string |
||||
Time int64 |
||||
} |
||||
@ -0,0 +1,331 @@ |
||||
package common |
||||
|
||||
const ( |
||||
ESIndexBalance = "bal" // 流水记录,改为别名
|
||||
ESIndexJackpot = "jackpot" // 游戏奖池中奖记录
|
||||
ESIndexLongPay = "long_pay" // 充值返回速度过慢记录
|
||||
ESIndexTron = "tron" // tron转账记录
|
||||
ESIndexGameData = "game_data" // 玩家游戏记录
|
||||
ESIndexShareProfitReport = "share_profit_report" // 分享者每日收益汇总
|
||||
ESIndexShareProfitRecord = "share_profit_record" // 分享者所有推荐人贡献的每日收益详情
|
||||
) |
||||
|
||||
// backend
|
||||
const ( |
||||
ESIndexBackMailDraft = "back_mail_draft" // 后台邮件草稿
|
||||
ESIndexBackWhiteList = "back_white_list" // 后台白名单
|
||||
ESIndexBackPlayerOnline = "back_player_online" // 后台在线统计
|
||||
ESIndexBackExamineList = "back_examine_list" // 后台审核人员名单
|
||||
ESIndexBackWarn = "back_warn" // 后台预警
|
||||
ESIndexBackDailyData = "back_daily_data" // 后台每日统计数据
|
||||
ESIndexBackOpenRecord = "back_open_record" // 后台统计玩家打开安装数
|
||||
ESIndexBackIncomeStatistics = "back_income_statistics" // 后台收入统计
|
||||
ESIndexBackPlayerPayData = "back_player_pay_data" // 后台玩家充值/退出统计
|
||||
ESIndexBackReviewData = "back_review_data" // 数据概要
|
||||
ESIndexBackAppSummary = "back_app_summary" // 应用概要
|
||||
ESIndexBackRechargeFrequency = "back_recharge_frequency" // 付费分析
|
||||
ESIndexBackKeepData = "back_keep_data" // 留存
|
||||
ESIndexBackBlackList = "back_black_list" // 封号拉黑的玩家
|
||||
ESIndexBackABLog = "back_ab_log" // 玩家进入ab面统计
|
||||
ESIndexBackMillionGameRecord = "back_million_game_record" |
||||
ESIndexBackMillionPlayerRecord = "back_million_player_record" |
||||
ESIndexBackPddRecord = "back_pdd_record" |
||||
ESIndexBackFeedback = "back_feedback" |
||||
ESIndexBackActivity = "back_activity" |
||||
) |
||||
|
||||
// GroupBuckets group聚合查询对象
|
||||
type GroupBuckets struct { |
||||
Buckets []struct { |
||||
Key interface{} |
||||
Doc_count int |
||||
} |
||||
} |
||||
|
||||
// GroupCardBuckets group聚合查询对象
|
||||
type GroupCardBuckets struct { |
||||
Buckets []struct { |
||||
Key interface{} |
||||
Doc_count int |
||||
Sub struct { |
||||
Value int |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Group2CardBuckets group聚合查询对象
|
||||
type Group2CardBuckets struct { |
||||
Buckets []struct { |
||||
Key interface{} |
||||
Doc_count int |
||||
Sub1 struct { |
||||
Buckets []struct { |
||||
Key interface{} |
||||
Doc_count int |
||||
Sub2 struct { |
||||
Value int |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// GroupSumBuckets group聚合查询对象
|
||||
type GroupSumBuckets struct { |
||||
Buckets []struct { |
||||
Key interface{} |
||||
Doc_count int |
||||
Value struct { |
||||
Value float64 |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Group2SumBuckets group聚合查询对象
|
||||
type Group2SumBuckets struct { |
||||
Buckets []struct { |
||||
Key interface{} |
||||
Doc_count int |
||||
Sub1 struct { |
||||
Buckets []struct { |
||||
Key interface{} |
||||
Doc_count int |
||||
Sub2 struct { |
||||
Value float64 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// SumByResult sum聚合查询对象
|
||||
type SumByResult struct { |
||||
Value float64 |
||||
} |
||||
|
||||
// ESPlayerStats 玩家充值/退出记录表
|
||||
type ESPlayerPayData struct { |
||||
ID string `json:"-"` |
||||
UID int `json:"UID"` |
||||
Channel int `json:"Channel"` |
||||
Time int64 `json:"Time"` |
||||
IsNew bool `json:"IsNew"` |
||||
Type int `json:"Type"` // 类型 1充值 2退出
|
||||
CurrencyType CurrencyType `json:"CurrencyType"` |
||||
Amount int64 `json:"Amount"` // 充值/退出金额
|
||||
FirstAmount int64 `json:"FirstAmount"` // 是否是首次,如果是,则金额大于0
|
||||
} |
||||
|
||||
type ESNewOnline struct { |
||||
Channel int `json:"Channel"` |
||||
Time int64 `json:"Time"` |
||||
Total int `json:"Total"` |
||||
GameID int `json:"GameID"` |
||||
Recharge int `json:"Recharge"` |
||||
New int `json:"New"` |
||||
Old int `json:"Old"` |
||||
} |
||||
|
||||
// ESNewOnlineBucket 在线聚合对象
|
||||
type ESNewOnlineBucket struct { |
||||
Buckets []struct { |
||||
Key interface{} |
||||
Doc_count int |
||||
Total struct { |
||||
Value float64 |
||||
} |
||||
Recharge struct { |
||||
Value float64 |
||||
} |
||||
New struct { |
||||
Value float64 |
||||
} |
||||
Old struct { |
||||
Value float64 |
||||
} |
||||
} |
||||
} |
||||
|
||||
// ESDailySysData 每日系统统计的一些数据
|
||||
// USDT USDT总量
|
||||
// BRL BRL总量
|
||||
// Time 统计日零点时间戳
|
||||
// Date 日期
|
||||
type ESDailySysData struct { |
||||
Date string |
||||
Channel int |
||||
Time int64 |
||||
USDT int64 |
||||
BRL int64 |
||||
} |
||||
|
||||
// ESOpenRecord 统计安装打开app的数目
|
||||
type ESOpenRecord struct { |
||||
Time int64 |
||||
UUID string |
||||
Channel int |
||||
} |
||||
|
||||
// ESGameJackpot 游戏场jackpot大奖记录
|
||||
type ESGameJackpot struct { |
||||
UID int // 用户uid
|
||||
Nick string // 用户昵称
|
||||
Time int64 // 时间
|
||||
Avatar string // 用户头像
|
||||
Channel int // 渠道
|
||||
Bet int64 // 投注总额
|
||||
Get int64 // 获得的奖励
|
||||
Total int64 // 总奖励
|
||||
GameID int |
||||
RoomID int |
||||
Winners int // 瓜分奖池的总玩家
|
||||
Multi int // 倍率
|
||||
} |
||||
|
||||
// ESBlackList 游戏拉黑玩家
|
||||
type ESBlackList struct { |
||||
UID int // 用户uid
|
||||
Name string |
||||
Phone string |
||||
Email string |
||||
PayAccount string |
||||
Time int64 |
||||
} |
||||
|
||||
// ESLongPay 充值返回记录
|
||||
type ESLongPay struct { |
||||
Channel int |
||||
Time int64 |
||||
Date string |
||||
Cost int64 // 时间消耗单位毫秒
|
||||
UID int |
||||
Amount int64 |
||||
} |
||||
|
||||
// ESTron 转账记录
|
||||
type ESTron struct { |
||||
TxID string // 交易号
|
||||
From string |
||||
To string |
||||
OrderID string // 系统订单号
|
||||
Amount int64 |
||||
Time int64 |
||||
Type int // 1trx 2usdt
|
||||
Success bool |
||||
Status int // 1玩家退出打u 2系统自动从玩家地址转u回主地址 3后台转账操作
|
||||
} |
||||
|
||||
// ESABLog 进入ab面统计
|
||||
type ESABLog struct { |
||||
Channel int |
||||
Time int64 |
||||
DeviceID string |
||||
IsA bool // 是否进入A面
|
||||
Log string // 日志记录
|
||||
} |
||||
|
||||
// ESGameData 玩家游戏记录
|
||||
type ESGameData struct { |
||||
UID int // 用户uid
|
||||
Channel int |
||||
Provider int // 提供商
|
||||
GameID int // 游戏id
|
||||
UUID string // 厂商唯一id
|
||||
Type CurrencyType |
||||
BetAmount int64 // 下注金额
|
||||
SettleAmount int64 // 输赢金额
|
||||
MyUUID string // 自己的唯一id
|
||||
Time int64 |
||||
Birth int64 |
||||
PlayTime int64 |
||||
SubID int |
||||
IsNew bool |
||||
} |
||||
|
||||
// ESIncomeStatistics 收入统计
|
||||
// Investment 投入资金
|
||||
// Period 回本周期
|
||||
type ESIncomeStatistics struct { |
||||
Time int64 // 时间
|
||||
Channel int // 渠道
|
||||
Investment int64 // 投入资金
|
||||
Period int64 // 回本周期
|
||||
} |
||||
|
||||
// ESMillionGameRecord 百人模式游戏数据统计
|
||||
type ESMillionGameRecord struct { |
||||
Time int64 |
||||
GameID int // 游戏id
|
||||
RoomID int // 场次id
|
||||
UUID string |
||||
PlayerCount int // 本局总人数
|
||||
PlayerBet int64 // 用户下注金额
|
||||
Reward int64 // 发放金额
|
||||
Profit int64 // 盈亏
|
||||
Result string // 开奖结果
|
||||
ResultDetail string // 开奖结果 具体的牌/骰子
|
||||
Channel int |
||||
Area int // 区域
|
||||
IsWin bool // 该区域是否获胜
|
||||
} |
||||
|
||||
// ESMillionPlayerRecord 百人模式游戏数据统计
|
||||
type ESMillionPlayerRecord struct { |
||||
UID int |
||||
Time int64 |
||||
GameID int // 游戏id
|
||||
RoomID int // 场次id
|
||||
UUID string |
||||
Settle int64 // 本局结算结果
|
||||
Result string // 开奖结果
|
||||
Channel int |
||||
Bets []int64 |
||||
} |
||||
|
||||
// ESShareProfitReport 分享者每日分享收益记录
|
||||
type ESShareProfitReport struct { |
||||
UID int // 分享者
|
||||
Regist int64 // 注册人数
|
||||
Bet int64 // 有效下注
|
||||
Level int // 分享者等级
|
||||
Reward int64 |
||||
Date string |
||||
Time int64 |
||||
} |
||||
|
||||
// ESShareProfitRecord 分享推荐收益记录
|
||||
type ESShareProfitRecord struct { |
||||
UID int // 被分享人
|
||||
Bet int64 // 被分享人投注
|
||||
DownBet int64 // 被分享人的下级投注总和
|
||||
Up int // 分享者uid
|
||||
Reward int64 // 佣金
|
||||
Date string |
||||
Time int64 |
||||
} |
||||
|
||||
// UID int 被分享人
|
||||
// Referer int 分享人
|
||||
type ESPddRecord struct { |
||||
UID int // 被分享人
|
||||
Referer int // 分享人
|
||||
Time int64 |
||||
Nick string |
||||
Avatar string |
||||
} |
||||
|
||||
type ESFeedback struct { |
||||
UID int |
||||
QuestionIndex int |
||||
Choose int |
||||
Context string |
||||
Time int64 |
||||
} |
||||
|
||||
type ESActivity struct { |
||||
ActivityID int |
||||
UID int |
||||
Time int64 |
||||
Type int // 1点击 2参与
|
||||
Amount int64 // 赠送金额
|
||||
} |
||||
@ -0,0 +1,79 @@ |
||||
package common |
||||
|
||||
import "fmt" |
||||
|
||||
const ( |
||||
JackpotTypeActivity = iota + 1 |
||||
JackpotTypeGame |
||||
) |
||||
|
||||
var ( |
||||
GameModulePrefix = "game" // 游戏模块名字前缀
|
||||
) |
||||
|
||||
func GetGameModuleName(gid int) string { |
||||
return fmt.Sprintf("%v%v", GameModulePrefix, gid) |
||||
} |
||||
|
||||
// Jackpot 记录各个奖池
|
||||
type Jackpot struct { |
||||
ID int `gorm:"primarykey"` |
||||
Type int `gorm:"column:type;not null;type:int(11);comment:类型 活动1 游戏2" json:"Type"` |
||||
TypeID int `gorm:"column:type_id;not null;type:int(11);uniqueIndex:type_id;comment:奖池标记id,可以是活动id,游戏id" json:"TypeID"` |
||||
Amount int64 `gorm:"column:amount;type:bigint(20);default:0;comment:奖池" json:"Amount"` |
||||
Max int64 `gorm:"column:max;type:bigint(20);default:0;comment:奖池最大额度" json:"Max"` |
||||
} |
||||
|
||||
func (j *Jackpot) TableName() string { |
||||
return "jackpot" |
||||
} |
||||
|
||||
const ( |
||||
SessionTypeBet = iota + 1 |
||||
SessionTypeSettle |
||||
SessionTypeActivity |
||||
SessionTypeAdjustment // 调整玩家余额
|
||||
SessionTypeJackpot |
||||
SessionTypeBonus |
||||
SessionTypeBuyIn // 直接扣钱操作
|
||||
SessionTypeBuyOut // 直接加钱操作
|
||||
) |
||||
|
||||
// 提供商下单记录
|
||||
type ProviderBetRecord struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);index:uid;comment:uid"` |
||||
Provider int `gorm:"column:provider;not null;type:int(11);uniqueIndex:p_uuid;comment:供应商id"` |
||||
Currency string `gorm:"column:currency;type:varchar(64);comment:货币名称"` |
||||
CurrencyType CurrencyType `gorm:"column:currency_type;default:1;type:int(11);comment:货币id"` |
||||
GameID int `gorm:"column:game_id;not null;type:int(11);comment:游戏id"` |
||||
GameName string `gorm:"column:game_name;type:varchar(64);default:'';comment:游戏名"` |
||||
UUID string `gorm:"column:uuid;type:varchar(255);uniqueIndex:p_uuid;comment:供应商唯一识别值"` |
||||
SessionID string `gorm:"column:session_id;type:varchar(255);comment:牌局类型时的牌局id"` |
||||
Type int `gorm:"column:type;type:bigint(20);uniqueIndex:p_uuid;comment:类型 1下注 2结算"` |
||||
Time int64 `gorm:"column:time;type:bigint(20);default:0;comment:时间戳"` |
||||
ProviderTime int64 `gorm:"column:provider_time;type:bigint(20);default:0;comment:厂商时间戳"` |
||||
Amount int64 `gorm:"column:amount;type:bigint(20);default:0;comment:下注额"` |
||||
Settle int64 `gorm:"column:settle;type:bigint(20);default:0;comment:结算额"` |
||||
Preserve int64 `gorm:"column:preserve;type:bigint(20);default:0;comment:预扣款"` |
||||
TurnOver int64 `gorm:"column:turnover;type:bigint(20);default:0;comment:有效投注额"` |
||||
MyUUID int64 `gorm:"column:my_uuid;type:bigint(20);comment:我方唯一识别值"` |
||||
Esi int64 `gorm:"column:esi;type:bigint(20);default:1;comment:额外字段"` // tada 表示本局是否已失败 2已失败,后续不再接收
|
||||
Esi1 int64 `gorm:"column:esi1;type:bigint(20);default:1;comment:额外字段1"` // awc标识注单无效原因
|
||||
Ess string `gorm:"column:ess;type:varchar(64);default:'';comment:额外字符串字段"` // 活动时,标识活动代码
|
||||
} |
||||
|
||||
func (t *ProviderBetRecord) TableName() string { |
||||
return "provider_bet_record" |
||||
} |
||||
|
||||
const ( |
||||
GameType = iota |
||||
GameTypeInHouse |
||||
GameTypeSlots |
||||
GameTypeLive |
||||
GameTypeTable |
||||
GameTypeSpecial |
||||
GameTypeESport |
||||
GameTypeSportBook |
||||
) |
||||
@ -0,0 +1,20 @@ |
||||
package common |
||||
|
||||
const ( |
||||
EN = "en" |
||||
PT = "pt" |
||||
) |
||||
|
||||
func IsLangValid(lan string) bool { |
||||
if lan != EN && lan != PT { |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
|
||||
func CheckLang(lan string) string { |
||||
if lan != EN && lan != PT { |
||||
return EN |
||||
} |
||||
return lan |
||||
} |
||||
@ -0,0 +1,373 @@ |
||||
package common |
||||
|
||||
import ( |
||||
"fmt" |
||||
"server/util" |
||||
"strconv" |
||||
"strings" |
||||
) |
||||
|
||||
// 平台登录方式
|
||||
const ( |
||||
AccountTypeGuest = iota |
||||
AccountTypePhone |
||||
AccountTypeFacebook |
||||
AccountTypeGoogleplay |
||||
AccountTypeEmail |
||||
AccountTypeAccount |
||||
AccountTypeRobot = 100 |
||||
) |
||||
|
||||
// 账号状态
|
||||
const ( |
||||
AccountStatus = iota |
||||
AccountStatusNormal // 正常
|
||||
AccountStatusLimit // 封禁
|
||||
AccountStatusAll |
||||
) |
||||
|
||||
// 对账号进行操作
|
||||
const ( |
||||
OptPlayerType = iota |
||||
OptPlayerTypeKick // 踢出玩家
|
||||
OptPlayerTypeDisconnect // 操作玩家断线
|
||||
OptPlayerTypeAll |
||||
) |
||||
|
||||
const ( |
||||
LanguageEN = iota + 1 |
||||
LanguageHindi |
||||
) |
||||
|
||||
const ( |
||||
NewUser = iota + 1 // 新用户登录
|
||||
OldUser // 老用户登录
|
||||
) |
||||
|
||||
const ( |
||||
DecimalDigits = 100000000 // 计算时精确到小数点后8位
|
||||
) |
||||
|
||||
var ( |
||||
DecimalCounts = 0 |
||||
OneDay int64 = 24 * 60 * 60 // 一天的秒数
|
||||
) |
||||
|
||||
func init() { |
||||
tmp := DecimalDigits |
||||
for { |
||||
if tmp <= 1 { |
||||
break |
||||
} |
||||
tmp /= 10 |
||||
DecimalCounts++ |
||||
} |
||||
} |
||||
|
||||
func CashFloat64ToInt64(value float64) int64 { |
||||
negative := value < 0 |
||||
// 将浮点数转换为字符串
|
||||
text := fmt.Sprintf("%v", value) |
||||
// 查找小数点位置
|
||||
pointIndex := strings.Index(text, ".") |
||||
var left, right string |
||||
var big, small int64 |
||||
if pointIndex != -1 { |
||||
left = text[:pointIndex] |
||||
// 去除小数点后面尾随的0
|
||||
right = strings.TrimRight(text[pointIndex+1:], "0") |
||||
} else { |
||||
left = text |
||||
} |
||||
diff := len(right) - DecimalCounts |
||||
if diff > 0 { |
||||
right = right[:DecimalCounts] |
||||
} else { |
||||
for i := 0; i < -diff; i++ { |
||||
right += "0" |
||||
} |
||||
} |
||||
big, _ = strconv.ParseInt(left, 10, 64) |
||||
small, _ = strconv.ParseInt(right, 10, 64) |
||||
ret := util.Abs(big*DecimalDigits) + small |
||||
if negative { |
||||
return -ret |
||||
} |
||||
return ret |
||||
} |
||||
|
||||
const ( |
||||
DeviceType = iota |
||||
DeviceTypeMobile |
||||
DeviceTypePC |
||||
DeviceTypeWebview |
||||
DeviceTypeIOSH5 |
||||
DeviceTypeMac |
||||
DeviceTypePWA |
||||
DeviceTypeAll |
||||
) |
||||
|
||||
func IsPC(t int) bool { |
||||
return t == DeviceTypePC |
||||
} |
||||
|
||||
func GetAccountPre(t int) string { |
||||
switch t { |
||||
case AccountTypeGuest: |
||||
return "guest" |
||||
case AccountTypePhone: |
||||
return "phone" |
||||
case AccountTypeFacebook: |
||||
return "fb" |
||||
case AccountTypeGoogleplay: |
||||
return "gp" |
||||
case AccountTypeEmail: |
||||
return "email" |
||||
case AccountTypeAccount: |
||||
return "account" |
||||
case AccountTypeRobot: |
||||
return "robot" |
||||
} |
||||
return "" |
||||
} |
||||
|
||||
// 渠道号分区
|
||||
var ( |
||||
ChannelRegionGoogle = []int{2, 10000} |
||||
ChannelRegionVivo = []int{10001, 11000} |
||||
) |
||||
|
||||
const ( |
||||
BrocastIDAll = iota // 全服广播
|
||||
BrocastIDWithdraw // tx事件
|
||||
) |
||||
|
||||
// 平台号
|
||||
const ( |
||||
PlatformIDGoogle = iota + 1 |
||||
PlatformIDVivo |
||||
PlatformIDAll |
||||
) |
||||
|
||||
func GetRegionByPlatformID(id int) []int { |
||||
switch id { |
||||
case PlatformIDGoogle: |
||||
return ChannelRegionGoogle |
||||
case PlatformIDVivo: |
||||
return ChannelRegionVivo |
||||
default: |
||||
return nil |
||||
} |
||||
} |
||||
|
||||
type AdjustEventType int |
||||
|
||||
// adjust事件顺序
|
||||
const ( |
||||
AdjustEventFinishLoad AdjustEventType = iota // 加载完成
|
||||
AdjustEventFirstPage // 首屏加载
|
||||
AdjustEventClickDemo // 点击游戏demo
|
||||
AdjustEventClickPlay // 点击游戏play
|
||||
AdjustEventNewPay // 新用户付费
|
||||
AdjustEventAllPay // 所有用户付费
|
||||
AdjustEventNewPlayer // 注册完成
|
||||
) |
||||
|
||||
const ( |
||||
ADZero = iota |
||||
ADFB |
||||
ADKwai |
||||
ADJust |
||||
ADAll |
||||
) |
||||
|
||||
// Channel 渠道表
|
||||
// GameControlm 游戏控制,0关闭,1开启
|
||||
type Channel struct { |
||||
ID uint `gorm:"primarykey"` |
||||
IgnoreOrganic int `gorm:"column:ignore_organic;type:tinyint(4);default:1;comment:是否屏蔽自然量 1不屏蔽 2屏蔽" json:"ignore_organic"` |
||||
AdjustEventID string `gorm:"column:adjust_eventid;type:varchar(256);not null;comment:adjust事件id,按顺序隔开" json:"adjust_eventid"` |
||||
AdjustAppToken string `gorm:"column:adjust_app_token;type:varchar(256);not null;comment:adjust应用token" json:"adjust_app_token"` |
||||
AdjustAuth string `gorm:"column:adjust_auth;type:varchar(256);not null;comment:adjust验证码" json:"adjust_auth"` |
||||
Name string `gorm:"column:name;type:varchar(32);not null;comment:渠道" json:"name"` |
||||
PackName string `gorm:"column:pack_name;type:varchar(256);not null;comment:包名" json:"pack_name"` |
||||
Version int `gorm:"column:version;type:int(11);not null;comment:审核版本号" json:"version"` |
||||
MainVersion int `gorm:"column:main_version;type:int(11);not null;comment:正式服版本号" json:"main_version"` |
||||
ChannelID int `gorm:"column:channel_id;type:bigint(20);uniqueIndex:channel_id;comment:渠道id" json:"channel_id"` |
||||
PlatformID int `gorm:"column:platform_id;type:int(11);comment:平台id,1 googleplay 2 vivo" json:"platform_id"` |
||||
IsHot int `gorm:"column:ishot;type:tinyint(4);default:1;comment:是否热更,1不热更,2热更" json:"ishot"` |
||||
URL string `gorm:"column:url;type:varchar(64);not null;default:'';comment:域名" json:"url"` |
||||
Show int `gorm:"column:show;type:int(11);default:0;comment:是否打开,1不打开,2打开" json:"show"` |
||||
FBPixelID string `gorm:"column:fb_pixelid;type:varchar(256);not null;comment:fb像素id" json:"fb_pixelid"` |
||||
FBAccessToken string `gorm:"column:fb_accesstoken;type:varchar(256);not null;comment:fb验证码" json:"fb_accesstoken"` |
||||
UP int `gorm:"column:up;type:int(11);default:0;comment:上级渠道" json:"up"` |
||||
ADUpload int `gorm:"column:ad_upload;type:int(11);default:0;comment:上报事件的平台" json:"ad_upload"` |
||||
} |
||||
|
||||
func (c *Channel) TableName() string { |
||||
return "channel" |
||||
} |
||||
|
||||
// ServerVersion 服务器版本表
|
||||
// GameControlm 游戏控制,0关闭,1开启
|
||||
type ServerVersion struct { |
||||
ID uint `gorm:"primarykey"` |
||||
ServerID int `gorm:"column:server_id;type:int(11);uniqueIndex:server_id;default:0;comment:服务器id" json:"server_id" redis:"server_id"` |
||||
Version int `gorm:"column:version;type:int(11);default:0;comment:服务器最新版本" json:"version" redis:"version"` |
||||
} |
||||
|
||||
func (c *ServerVersion) TableName() string { |
||||
return "server_version" |
||||
} |
||||
|
||||
func (c *Channel) GetAdjustEventID(e int) string { |
||||
s := strings.Split(c.AdjustEventID, ",") |
||||
if e > len(s)-1 { |
||||
return "" |
||||
} |
||||
return s[e] |
||||
} |
||||
|
||||
// 红点提示
|
||||
const ( |
||||
RedpointMail = iota + 1 // 邮件
|
||||
) |
||||
|
||||
// WhiteList 白名单
|
||||
// ListType 名单类型 1白名单 2黑名单(当为0时,用作系统开关)
|
||||
// LimitType 限制类型 1ip限制 2设备限制(用作系统开关时 1开启 2关闭)
|
||||
// Content ip或者设备码
|
||||
// Platform 平台类型 facebook 2 gooleplay 3
|
||||
// Channel 渠道号
|
||||
// Version 版本号
|
||||
// CreateTime 创建时间
|
||||
// Operator 操作人
|
||||
// Powers 权限
|
||||
//
|
||||
// 第1位控制 手机/游客/渠道
|
||||
// 第2位控制 注册账号
|
||||
// 第3位控制 绑定账号
|
||||
// 第4位控制 账号充值
|
||||
// 第5位控制 账号退出
|
||||
// 第6位控制 游戏玩牌
|
||||
// 第7位控制 版本热更
|
||||
type WhiteList struct { |
||||
ID string |
||||
ListType int |
||||
LimitType int |
||||
Content string |
||||
Platform int |
||||
Channel int |
||||
Version int |
||||
Powers []int |
||||
CreateTime int64 |
||||
Operator string |
||||
} |
||||
|
||||
var ( |
||||
PowerMap = map[string]int{ |
||||
"/account/phoneCode/login": 0, |
||||
"/account/guestLogin": 0, |
||||
"/account/gpLogin": 0, |
||||
"/account/phoneCode/regist": 1, |
||||
"/account/phoneCode/bind": 2, |
||||
"/balance/recharge/do": 3, |
||||
"/balance/withdraw/do": 4, |
||||
"playCard": 5, |
||||
// "/sys/hotUpdate": 6,
|
||||
} |
||||
LimitMap = map[string]struct{}{ |
||||
"/sys/hotUpdate": {}, |
||||
} |
||||
) |
||||
|
||||
func IsLimitMap(path string) bool { |
||||
_, ok := LimitMap[path] |
||||
return ok |
||||
} |
||||
|
||||
// PowerPass 鉴权
|
||||
func (w *WhiteList) PowerPass(path string) bool { |
||||
po, ok := PowerMap[path] |
||||
if !ok { |
||||
index := -1 |
||||
for k, v := range PowerMap { |
||||
if strings.Contains(path, k) { |
||||
index = v |
||||
break |
||||
} |
||||
} |
||||
if index == -1 { |
||||
return true |
||||
} |
||||
po = index |
||||
} |
||||
if po > len(w.Powers) { |
||||
return false |
||||
} |
||||
power := w.Powers[po] |
||||
if po == 0 { |
||||
index := strings.LastIndex(path, "/") |
||||
newStr := path[index:] |
||||
switch newStr { |
||||
case "/login": |
||||
return power&4 == 4 |
||||
case "/guestLogin": |
||||
return power&2 == 2 |
||||
case "/gpLogin": |
||||
return power&1 == 1 |
||||
default: |
||||
return false |
||||
} |
||||
} |
||||
return power == 1 |
||||
} |
||||
|
||||
// ExamineList 审核人员列表
|
||||
type ExamineList struct { |
||||
Time int64 |
||||
} |
||||
|
||||
// LoginRecord 玩家登录记录表
|
||||
type LoginRecord struct { |
||||
ID int `gorm:"primarykey"` |
||||
FirstTime int64 `gorm:"column:first_time;default:0;type:bigint(20);comment:首次登录时间"` |
||||
Time int64 `gorm:"column:time;default:0;type:bigint(20);unixIndex:ut;comment:最后登录时间"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);unixIndex:ut;comment:玩家id"` |
||||
IP string `gorm:"column:ip;type:varchar(256);comment:玩家登录ip"` |
||||
Date string `gorm:"column:date;type:varchar(64);default:'';comment:日期"` |
||||
ChannelID int `gorm:"column:channel_id;type:bigint(20);default:0;comment:渠道id"` |
||||
Status int `gorm:"column:status;type:int(11);comment:1是新用户,2是老用户"` |
||||
Platform int `gorm:"column:platform;type:int(11);default:1;comment:最新登录平台"` |
||||
IsRecharge int `gorm:"column:is_recharge;type:tinyint(4);default:1;comment:1未充值,2已充值"` |
||||
} |
||||
|
||||
func (c *LoginRecord) TableName() string { |
||||
return "login_record" |
||||
} |
||||
|
||||
// RedisRealOnline 各场次实时在线
|
||||
type RedisRealOnline struct { |
||||
Total int // 总在线人数
|
||||
New int // 新用户在线人数
|
||||
} |
||||
|
||||
// IsShareChannel 是否是分享渠道
|
||||
func IsShareChannel(cid int) bool { |
||||
return cid > 10000 |
||||
} |
||||
|
||||
// BlackList 黑名单
|
||||
type BlackList struct { |
||||
ID int `gorm:"primarykey"` |
||||
Name string `gorm:"column:name;type:varchar(64);default:'';not null;uniqueIndex:black_all;comment:名字" json:"Name" web:"name"` |
||||
Phone string `gorm:"column:phone;type:varchar(64);default:'';not null;uniqueIndex:black_all;comment:手机号" json:"Phone" web:"phone"` |
||||
Email string `gorm:"column:email;type:varchar(64);default:'';not null;uniqueIndex:black_all;comment:email" json:"Email" web:"email"` |
||||
PayAccount string `gorm:"column:pay_account;type:varchar(255);default:'';not null;uniqueIndex:black_all;comment:支付账号" json:"PayAccount" web:"pay_account"` |
||||
DeviceID string `gorm:"column:deviceid;type:varchar(255);default:'';not null;uniqueIndex:black_all;comment:设备号" json:"DeviceID" web:"deviceid"` |
||||
IP string `gorm:"column:ip;type:varchar(64);default:'';not null;uniqueIndex:black_all;comment:ip" json:"IP" web:"ip"` |
||||
} |
||||
|
||||
func (c *BlackList) TableName() string { |
||||
return "black_list" |
||||
} |
||||
@ -0,0 +1,309 @@ |
||||
package common |
||||
|
||||
import ( |
||||
"fmt" |
||||
"reflect" |
||||
) |
||||
|
||||
// 账号身份
|
||||
const ( |
||||
PlayerRoleNormal = iota |
||||
PlayerRoleRobot = 100 |
||||
) |
||||
|
||||
// 玩家状态
|
||||
const ( |
||||
PlayerStatusNormal = iota + 1 |
||||
PlayerStatusMatching |
||||
PlayerStatusPlaying |
||||
) |
||||
|
||||
// 玩家是否在线
|
||||
const ( |
||||
PlayerOnline = iota + 1 |
||||
PlayerOffline |
||||
) |
||||
|
||||
type PlayerDBInfo struct { |
||||
Id int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"id" redis:"id"` |
||||
ADID string `gorm:"column:adid;type:varchar(256);comment:玩家adjustID" json:"adid" redis:"adid"` |
||||
GPSADID string `gorm:"column:gps_adid;type:varchar(256);comment:玩家google广告ID" json:"gps_adid" redis:"gps_adid"` |
||||
Openid *string `gorm:"column:openid;type:varchar(128);uniqueIndex:channel_openid;comment:唯一识别号" json:"-" redis:"openid"` |
||||
IP string `gorm:"column:ip;type:varchar(256);comment:玩家登录ip" json:"ip" redis:"ip"` |
||||
Pass string `gorm:"column:pass;type:varchar(64)" json:"pass" redis:"pass"` |
||||
Nick string `gorm:"column:nick;type:varchar(64)" json:"nick" redis:"nick"` |
||||
Mobile string `gorm:"column:mobile;default:null;type:varchar(64);uniqueIndex:channel_mobile" json:"mobile" redis:"mobile"` |
||||
Avatar string `gorm:"column:avatar;type:varchar(512);default:''" json:"avatar" redis:"avatar"` |
||||
DeviceId string `gorm:"column:deviceid;type:varchar(256);default:'';comment:设备号" json:"deviceid" redis:"deviceid"` |
||||
SessionID string `gorm:"-" json:"sessionID" redis:"sessionID"` |
||||
AccountName string `gorm:"column:account_name;default:null;uniqueIndex:channel_account_name;commont:账户名" json:"account_name" redis:"account_name"` |
||||
GateID string `gorm:"-" json:"gateID" redis:"gateID"` |
||||
Token string `gorm:"-" json:"token" redis:"token"` |
||||
Birth int64 `gorm:"column:birth;type:bigint(20);default:0;comment:账号创建时间,时间戳" json:"birth" redis:"birth"` |
||||
Role int `gorm:"column:role;type:smallint(8);default:0;comment:玩家角色0普通玩家,100机器人" json:"role" redis:"role"` |
||||
ChannelID int `gorm:"column:channel_id;type:bigint(20);uniqueIndex:channel_openid;uniqueIndex:channel_mobile;uniqueIndex:channel_account_name;default:1;comment:渠道id" json:"channel_id" redis:"channel_id"` |
||||
AccountType int `gorm:"column:account_type;comment:0游客,1fb,2gp" json:"account_type" redis:"account_type"` |
||||
Status int `gorm:"column:status;type:tinyint(4);default:1;comment:账号状态,1正常,2封禁" json:"status" redis:"status"` |
||||
Online int `gorm:"column:online;type:tinyint(4);default:2;comment:是否在线,1在线,2不在线" json:"online" redis:"online"` |
||||
Tag string `gorm:"column:tag; type:varchar(512);default:'';comment:后台管理给账户打的标签,用户不可见" json:"tag" redis:"tag"` |
||||
Platform int `gorm:"column:platform;type:int(11);default:1;comment:最新登录平台" json:"platform" redis:"platform"` |
||||
LastLogin int64 `gorm:"column:last_login;type:bigint(20);default:0;comment:最近登录时间" json:"last_login" redis:"last_login"` |
||||
Country string `gorm:"column:country;type:varchar(64);default:'';comment:国家" json:"country" redis:"country"` |
||||
} |
||||
|
||||
func (u *PlayerDBInfo) TableName() string { |
||||
return "users" |
||||
} |
||||
|
||||
// PlayerSession 玩家会话信息
|
||||
type PlayerSession struct { |
||||
SessionID string `json:"sessionID" redis:"sessionID"` |
||||
GateID string `json:"gateID" redis:"gateID"` |
||||
Nick string `json:"nick" redis:"nick"` |
||||
} |
||||
|
||||
// FacebookUserInfo facebook返回的登录接口
|
||||
type FacebookUserInfo struct { |
||||
ID string |
||||
Name string |
||||
Picture struct { |
||||
Data struct { |
||||
URL string `json:"url"` |
||||
Height int |
||||
Width int |
||||
IsSilhouette bool |
||||
} `json:"data"` |
||||
} `json:"picture"` |
||||
} |
||||
|
||||
// GooglePlayUserInfo googlePlay返回的登录接口
|
||||
type GooglePlayUserInfo struct { |
||||
ID string `json:"sub"` |
||||
Email string |
||||
Name string |
||||
Given_name string |
||||
Family_name string |
||||
Picture string |
||||
Locale string |
||||
Verified_email bool |
||||
} |
||||
|
||||
// PlayerStatus 玩家状态
|
||||
// type PlayerStatus struct {
|
||||
// GameName string `json:"GameName" redis:"GameName"`
|
||||
// UUID string `json:"UUID" redis:"UUID"`
|
||||
// TableID string `json:"TableID" redis:"TableID"`
|
||||
// ActiveTime int64 `json:"ActiveTime" redis:"ActiveTime"`
|
||||
// WorkID int `json:"WorkID" redis:"WorkID"`
|
||||
// MatchID uint32 `json:"MatchID" redis:"MatchID"`
|
||||
// Status uint32 `json:"Status" redis:"Status"`
|
||||
// GameID uint32 `json:"GameID" redis:"GameID"`
|
||||
// }
|
||||
|
||||
// func (s *PlayerStatus) MarshalBinary() ([]byte, error) {
|
||||
// return json.Marshal(s)
|
||||
// }
|
||||
|
||||
// func (s *PlayerStatus) UnmarshalBinary(data []byte) error {
|
||||
// return json.Unmarshal(data, s)
|
||||
// }
|
||||
|
||||
// NormalPlayerSql 返回查询正常用户的sql条件语句
|
||||
func NormalPlayerSql(channel ...*int) string { |
||||
sql := "" |
||||
for _, v := range channel { |
||||
if v == nil { |
||||
continue |
||||
} |
||||
if sql == "" { |
||||
sql += fmt.Sprintf("(channel_id = %v", *v) |
||||
} else { |
||||
sql += fmt.Sprintf(" or channel_id = %v", *v) |
||||
} |
||||
} |
||||
if len(sql) > 0 { |
||||
sql += ")" |
||||
} |
||||
sql += fmt.Sprintf(" and role <> %v and status = %v", PlayerRoleRobot, AccountStatusNormal) |
||||
return sql |
||||
} |
||||
|
||||
// PlayerData 保存一些玩家记录
|
||||
type PlayerData struct { |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
LastSysEmailDraw int64 `gorm:"column:last_sys_email_draw;type:bigint(20);default:0;comment:最近一次接收系统邮件的时间"` |
||||
LastAppSpinDraw int64 `gorm:"column:last_app_spin_draw;type:bigint(20);default:0;comment:上次领取app下载转盘的时间"` |
||||
FeedbackTime int64 `gorm:"column:feedback_time;type:bigint(20);default:0;comment:完成问卷调查的时间"` |
||||
} |
||||
|
||||
func (u *PlayerData) TableName() string { |
||||
return "player_data" |
||||
} |
||||
|
||||
// PlayerRed 玩家红点信息
|
||||
type PlayerRed struct { |
||||
ID uint `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
Mail int `gorm:"column:mail;type:int(11);comment:未读取邮件数" json:"Mail"` |
||||
} |
||||
|
||||
func (u *PlayerRed) TableName() string { |
||||
return "player_red" |
||||
} |
||||
|
||||
const ( |
||||
ItemStatusZero = iota |
||||
ItemStatusNormal // 正常
|
||||
ItemStatusInvalid // 不可用
|
||||
ItemStatusAll |
||||
) |
||||
|
||||
// 物品的枚举
|
||||
const ( |
||||
ItemZero = iota |
||||
ItemDiscountTicket |
||||
ItemAll |
||||
) |
||||
|
||||
// PlayerItems 玩家道具
|
||||
type PlayerItems struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;type:int(11)"` |
||||
ItemID int `gorm:"column:item_id;default:0;comment:物品id"` |
||||
Time int64 `gorm:"column:time;type:bigint(20);default:0;comment:获得的时间"` |
||||
Status int `gorm:"column:status;type:int(11);default:0;comment:物品状态"` |
||||
Exi1 int `gorm:"column:exi1;type:int(11);default:0;comment:物品标识字段1"` |
||||
} |
||||
|
||||
func (p *PlayerItems) TableName() string { |
||||
return "player_items" |
||||
} |
||||
|
||||
// PlayerH5Data 玩家H5数据
|
||||
type PlayerH5Data struct { |
||||
UID int `gorm:"primary_key;column:uid;type:int(11)"` |
||||
Collect int `gorm:"column:collect;type:int(11);default:1;comment:是否已领取H5收藏奖励,1未领取,2已领取"` |
||||
Download int `gorm:"column:download;type:int(11);default:1;comment:是否已领取H5下载奖励,1未领取,2已领取"` |
||||
} |
||||
|
||||
func (p *PlayerH5Data) TableName() string { |
||||
return "player_h5data" |
||||
} |
||||
|
||||
var ( |
||||
PlayerRechargeTableName = "player_currency_recharge" // 玩家充值账户
|
||||
) |
||||
|
||||
// PlayerCurrency 玩家货币数据(此结构只能往后新增字段,前面字段不能修改顺序)
|
||||
type PlayerCurrency struct { |
||||
UID int `gorm:"primary_key;column:uid;type:int(11)"` |
||||
ChannelID int `gorm:"column:channel_id;type:bigint(20);default:1;comment:渠道id"` |
||||
BRL int64 `gorm:"column:brl;type:bigint(20);default:0;comment:雷亚尔"` |
||||
USDT int64 `gorm:"column:usdt;type:bigint(20);default:0;comment:usdt"` |
||||
} |
||||
|
||||
func (p *PlayerCurrency) TableName() string { |
||||
return "player_currency" |
||||
} |
||||
|
||||
func (p *PlayerCurrency) GetBalanceByType(ct CurrencyType) int64 { |
||||
ref := reflect.ValueOf(p).Elem() |
||||
val := ref.Field(int(ct) + 1) |
||||
if val.IsValid() { |
||||
return val.Int() |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
func (p *PlayerCurrency) SetBalance(ct CurrencyType, value int64) { |
||||
ref := reflect.ValueOf(p).Elem() |
||||
val := ref.Field(int(ct) + 1) |
||||
if val.IsValid() { |
||||
val.SetInt(value) |
||||
} |
||||
} |
||||
|
||||
// PlayerProfile 玩家生涯数据
|
||||
type PlayerProfile struct { |
||||
UID int `gorm:"primary_key;column:uid;type:int(11)"` |
||||
ChannelID int `gorm:"column:channel_id;type:bigint(20);default:1;comment:渠道id"` |
||||
NeedBet int64 `gorm:"column:need_bet;type:bigint(20);comment:当前所需下注量"` |
||||
TotalBet int64 `gorm:"column:total_bet;type:bigint(20);comment:总下注"` |
||||
TotalCounts int64 `gorm:"column:total_counts;type:bigint(20);comment:总下注次数"` |
||||
TotalSettle int64 `gorm:"column:total_settle;type:bigint(20);comment:总派发"` |
||||
} |
||||
|
||||
func (p *PlayerProfile) TableName() string { |
||||
return "player_profile" |
||||
} |
||||
|
||||
// Level vip等级
|
||||
// Bet 下注额
|
||||
// Exp vip经验
|
||||
// Draws 已经领取的vip等级奖励,从右至左,等级低到高
|
||||
//
|
||||
// Cashback 当前可领取的cashback
|
||||
type VipData struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"ID"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid" json:"UID"` |
||||
Level int `gorm:"column:level;not null;type:int(11);default:0;comment:vip等级" json:"Level"` |
||||
Bet int64 `gorm:"column:bet;not null;type:bigint(20);default:0;comment:下注额" json:"Bet"` |
||||
Exp int64 `gorm:"column:exp;not null;type:bigint(20);default:0;comment:vip经验" json:"Exp"` |
||||
Draws int64 `gorm:"column:draws;not null;type:bigint(20);default:0;comment:已经领取的vip等级奖励,从右至左,等级低到高" json:"Draws"` |
||||
Profit int64 `gorm:"column:profit;not null;type:bigint(20);default:0;comment:计算周期内的盈亏" json:"Profit"` |
||||
ProfitTime int64 `gorm:"column:profit_time;not null;type:bigint(20);default:0;comment:开始计算时间节点" json:"ProfitTime"` |
||||
Cashback int64 `gorm:"column:cashback;not null;type:bigint(20);default:0;comment:当前可领取的cashback" json:"Cashback"` |
||||
} |
||||
|
||||
func (c *VipData) TableName() string { |
||||
return "vip_data" |
||||
} |
||||
|
||||
type TronData struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
Addr string `gorm:"column:addr; type:varchar(256);default:'';comment:钱包地址"` |
||||
Usdt int64 `gorm:"column:usdt;type:bigint(20);default:0;comment:地址里的u存量,单位1e6"` |
||||
} |
||||
|
||||
func (c *TronData) TableName() string { |
||||
return "tron_data" |
||||
} |
||||
|
||||
// PlayerStatus 玩家状态
|
||||
type PlayerStatus struct { |
||||
ModuleName string `json:"ModuleName" redis:"ModuleName"` |
||||
WorkID int `json:"WorkID" redis:"WorkID"` |
||||
GameID int `json:"GameID" redis:"GameID"` |
||||
SubID int `json:"SubID" redis:"SubID"` |
||||
TableID string `json:"TableID" redis:"TableID"` |
||||
} |
||||
|
||||
// 玩家广告相关数据
|
||||
type PlayerADData struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;type:int(11);index:uid"` |
||||
IP string `gorm:"column:ip;type:varchar(256);comment:玩家ip"` |
||||
FBC string `gorm:"column:fbc;type:varchar(256);comment:玩家点击识别号"` |
||||
FBP string `gorm:"column:fbp;type:varchar(256);comment:玩家浏览器识别号"` |
||||
ChannelID int `gorm:"column:channel_id;type:bigint(20);default:1000;comment:渠道id"` |
||||
UserAgent string `gorm:"column:user_agent;type:varchar(256);comment:玩家浏览器版本"` |
||||
} |
||||
|
||||
func (c *PlayerADData) TableName() string { |
||||
return "player_ad_data" |
||||
} |
||||
|
||||
// 玩家购买记录
|
||||
type PlayerPayData struct { |
||||
ID uint `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
BreakGift string `gorm:"column:break_gift;type:varchar(256);default:'';comment:已购买破产礼包的档位"` |
||||
SubBreakGift []int `gorm:"-"` |
||||
// FirstPay string `gorm:"column:first_pay;default:'';type:varchar(256);comment:首次购买商品记录"`
|
||||
// SubFirstPay []int `gorm:"-"`
|
||||
} |
||||
|
||||
func (c *PlayerPayData) TableName() string { |
||||
return "player_pay_data" |
||||
} |
||||
@ -0,0 +1,67 @@ |
||||
package common |
||||
|
||||
import "server/config" |
||||
|
||||
const ( |
||||
ProviderZero = iota |
||||
ProviderInhouse |
||||
ProviderTada |
||||
ProviderSexy |
||||
ProviderPGSoft |
||||
ProviderEvolutionGaming |
||||
ProviderAllBet |
||||
ProviderBigGaming |
||||
ProviderSAGaming |
||||
ProviderPragmaticPlay |
||||
ProviderCQ9 |
||||
ProviderPlayTech |
||||
ProviderJoker |
||||
ProviderDragonSoft |
||||
ProviderTFGaming |
||||
ProviderWMCasino |
||||
ProviderKing855 |
||||
ProviderAMAYA |
||||
ProviderHabanero |
||||
ProviderIBC |
||||
ProviderReevo |
||||
ProviderEvoPlay |
||||
ProviderPlayStar |
||||
ProviderDreamGaming |
||||
ProviderNexus4D |
||||
ProviderSlotXo |
||||
ProviderBTI |
||||
ProviderEzugi |
||||
ProviderAll |
||||
) |
||||
|
||||
const ( |
||||
ProviderAPIType = iota |
||||
ProviderAPITypeJson |
||||
ProviderAPITypePostform |
||||
ProviderAPITypeAll |
||||
) |
||||
|
||||
// ConfigServerFlag 配置服务器编号配置
|
||||
type ConfigServerFlag struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id"` |
||||
Flag string `gorm:"column:flag;type:varchar(255);default:'b';uniqueIndex:flag;comment:服务器编号" web:"flag"` |
||||
APIURL string `gorm:"column:api_url;type:varchar(255);default:'';comment:api请求地址" web:"api_url"` |
||||
} |
||||
|
||||
func (c *ConfigServerFlag) TableName() string { |
||||
return "config_server_flag" |
||||
} |
||||
|
||||
func GetProviderUserName(name string) string { |
||||
if config.GetBase().ServerFlag != "a" { |
||||
name = config.GetBase().ServerFlag + name |
||||
} |
||||
return name |
||||
} |
||||
|
||||
func GetProviderUserToken(token string) string { |
||||
if config.GetBase().ServerFlag != "a" { |
||||
token = config.GetBase().ServerFlag + token |
||||
} |
||||
return token |
||||
} |
||||
@ -0,0 +1,235 @@ |
||||
package common |
||||
|
||||
const ( |
||||
StatusROrderWaitting = iota // 等待提交状态
|
||||
StatusROrderCreate |
||||
StatusROrderPay |
||||
StatusROrderFinish |
||||
StatusROrderFail |
||||
StatusROrderRefuse |
||||
StatusROrderPending // 挂起
|
||||
StatusROrderAll |
||||
) |
||||
|
||||
type PayType int |
||||
|
||||
// 支付类型,巴西代表cpf|cnpj|email|phone|evp
|
||||
const ( |
||||
PayTypeInvalid PayType = iota |
||||
PayTypeCPF |
||||
PayTypeCNPJ |
||||
PayTypePhone |
||||
PayTypeEmail |
||||
PayTypeEVP |
||||
PayTypeAll |
||||
) |
||||
|
||||
func (p PayType) Isvalid() bool { |
||||
return p > PayTypeInvalid && p < PayTypeAll |
||||
} |
||||
|
||||
func (p PayType) String() string { |
||||
switch p { |
||||
case PayTypeCPF: |
||||
return "CPF" |
||||
case PayTypeCNPJ: |
||||
return "CNPJ" |
||||
case PayTypePhone: |
||||
return "PHONE" |
||||
case PayTypeEmail: |
||||
return "EMAIL" |
||||
case PayTypeEVP: |
||||
return "EVP" |
||||
default: |
||||
return "" |
||||
} |
||||
} |
||||
|
||||
// ProductTypeRechargeWait 商品类型id
|
||||
const ( |
||||
ProductTypeRechargeWait = iota + 1 |
||||
ProductTypeAll |
||||
) |
||||
|
||||
// 非常规支付方式
|
||||
const ( |
||||
PayTypePerson = -1 // 个卡支付
|
||||
) |
||||
|
||||
// 首充活动id
|
||||
const ( |
||||
WelcomeBonusProductID = 1111 |
||||
) |
||||
|
||||
// 支付方式
|
||||
const ( |
||||
PaySourceZero = iota + 1 |
||||
PaySourceModulePay // pay模块支付
|
||||
PaySourceBlockPay // 区块链支付
|
||||
PaySourceAll |
||||
) |
||||
|
||||
// 用于记录商品id对应的购买次数,一个bigint可记录最多16个商品的最多15次购买记录
|
||||
var ( |
||||
ProductIDMap = map[int]int{} |
||||
) |
||||
|
||||
func GetProductPayCount(total int64, id int) int { |
||||
// log.Debug("total%v,id:%v", total, id)
|
||||
tmp, ok := ProductIDMap[id] |
||||
if !ok { |
||||
return 0 |
||||
} |
||||
return int((total >> (tmp * 4)) & 15) |
||||
} |
||||
|
||||
func AddProductPayCount(total int64, id int) int64 { |
||||
tmp, ok := ProductIDMap[id] |
||||
if !ok { |
||||
return total |
||||
} |
||||
// 右移,将当前需要操作的商品移动到最右侧
|
||||
pos := tmp * 4 |
||||
num := total >> (pos) |
||||
|
||||
// 拿到操作商品右侧的商品信息值
|
||||
right := 1 |
||||
for i := 0; i < pos; i++ { |
||||
right *= 2 |
||||
} |
||||
right-- |
||||
rightNum := total & int64(right) |
||||
|
||||
// 拿到需要操作的商品真实次数
|
||||
realNum := num & 15 |
||||
if realNum >= 15 { |
||||
return total |
||||
} |
||||
num++ |
||||
return rightNum | (num << (pos)) |
||||
} |
||||
|
||||
type RechargeOrder struct { |
||||
ID uint `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);index:uid"` |
||||
CreateTime int64 `gorm:"column:create_time;type:bigint(20);comment:创建时间" redis:"create_time"` |
||||
OrderID string `gorm:"column:orderid;not null;type:varchar(255);uniqueIndex:orderid;comment:本地ID"` |
||||
APIPayID string `gorm:"column:apipayid;not null;type:varchar(255);comment:支付第三方生成的id"` |
||||
Extra string `gorm:"column:extra;type:varchar(255);comment:额外信息字段"` |
||||
PayAccount string `gorm:"column:payaccount;not null;type:varchar(512);comment:支付账户"` |
||||
Amount int64 `gorm:"column:amount;not null;type:bigint(20);comment:单位8位小数"` |
||||
PaySource int `gorm:"column:pay_source;not null;type:int(11);comment:支付来源"` |
||||
PayChannel int `gorm:"column:pay_channel;type:int(11);comment:具体支付渠道"` |
||||
Event int `gorm:"column:event;not null;type:smallint(4);comment:事件类型"` |
||||
CurrencyType CurrencyType `gorm:"column:currency_type;not null;type:int(11);comment:货币类型"` |
||||
ProductID int `gorm:"column:productid;not null;type:int(11)"` |
||||
Status uint8 `gorm:"column:status;not null;type:tinyint(4);comment:1新建,2支付完成,3发货完成,4支付失败,5取消"` |
||||
FailReason string `gorm:"column:fail_reason;type:varchar(255);comment:失败原因"` |
||||
ChannelID int `gorm:"column:channel_id;type:bigint(20);default:1;comment:渠道id" redis:"channel_id"` |
||||
Remarks string `gorm:"column:remarks;type:varchar(255);comment:备注" redis:"remarks"` |
||||
CallbackTime int64 `gorm:"column:callback_time;type:bigint(20);comment:到账时间" redis:"callback_time"` |
||||
UPI int `gorm:"column:upi;not null;type:int(11);comment:玩家选择的upi"` |
||||
} |
||||
|
||||
func (r *RechargeOrder) TableName() string { |
||||
return "recharge_order" |
||||
} |
||||
|
||||
const ( |
||||
WithdrawOrderTypeZero = iota |
||||
WithdrawOrderTypeNormal |
||||
WithdrawOrderTypeShare |
||||
WithdrawOrderTypeAll |
||||
) |
||||
|
||||
type WithdrawOrder struct { |
||||
ID uint `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11)"` |
||||
CreateTime int64 `gorm:"column:create_time;type:bigint(20);comment:创建时间"` |
||||
OrderID string `gorm:"column:orderid;not null;type:varchar(255);uniqueIndex:orderid;comment:本地ID"` |
||||
APIPayID string `gorm:"column:apipayid;not null;type:varchar(255);comment:支付第三方生成的id"` |
||||
Extra string `gorm:"column:extra;type:varchar(64);comment:额外信息字段"` |
||||
PayAccount string `gorm:"column:payaccount;not null;type:varchar(512);comment:支付账户"` |
||||
Amount int64 `gorm:"column:amount;not null;type:bigint(20);comment:单位分"` |
||||
WithdrawCash int64 `gorm:"column:withdraw_cash;type:bigint(20);default:0;comment:退出扣除的金币"` |
||||
PaySource int `gorm:"column:pay_source;not null;type:int(11);comment:支付来源"` |
||||
CurrencyType CurrencyType `gorm:"column:currency_type;not null;type:int(11);comment:货币类型"` |
||||
PayChannel int `gorm:"column:pay_channel;type:int(11);comment:具体支付渠道"` |
||||
Event int `gorm:"column:event;not null;type:smallint(4);comment:事件类型"` |
||||
ProductID int `gorm:"column:productid;not null;type:int(11)"` |
||||
Status uint8 `gorm:"column:status;not null;type:tinyint(4);comment:1新建,2支付完成,3发货完成,4支付失败,5取消"` |
||||
FailReason string `gorm:"column:fail_reason;type:varchar(255);comment:失败原因"` |
||||
ChannelID int `gorm:"column:channel_id;type:bigint(20);default:1;comment:渠道id"` |
||||
Remarks string `gorm:"column:remarks;type:varchar(255);comment:备注"` |
||||
AuditTime int64 `gorm:"column:audit_time;type:bigint(20);comment:审核时间"` |
||||
CallbackTime int64 `gorm:"column:callback_time;type:bigint(20);comment:到账时间"` |
||||
UPI int `gorm:"column:upi;not null;type:int(11);comment:玩家选择的upi"` |
||||
Operator string `gorm:"column:operator;type:varchar(255);comment:操作人账号名"` |
||||
OrderType int `gorm:"column:order_type;default:1;type:int(11);comment:订单类型 1普通 2分享单"` |
||||
} |
||||
|
||||
func (r *WithdrawOrder) TableName() string { |
||||
return "withdraw_order" |
||||
} |
||||
|
||||
// RechargeInfo 玩家充值信息记录表
|
||||
type RechargeInfo struct { |
||||
ID uint `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
ProductPayCount int64 `gorm:"column:product_paycount;type:bigint(20);default:0;comment:记录玩家购买商品次数,映射表在代码里"` |
||||
DayRecharge int64 `gorm:"column:day_recharge;type:bigint(20);default:0;comment:日充值"` |
||||
TotalRechargeCount int64 `gorm:"column:total_recharge_count;type:bigint(20);default:0;comment:总充值次数"` |
||||
LastRecharge int64 `gorm:"column:last_recharge;type:bigint(20);default:0;comment:最近一次充值的时间戳"` |
||||
TotalRecharge int64 `gorm:"column:total_recharge;type:bigint(20);default:0;comment:总充值数额,不论货币"` |
||||
TotalWithdrawCount int64 `gorm:"column:total_withdraw_count;type:bigint(20);default:0;comment:总退出次数"` |
||||
TotalWithdraw int64 `gorm:"column:total_withdraw;type:bigint(20);default:0;comment:总退出数额,不论货币"` |
||||
TotalWithdrawing int64 `gorm:"column:total_withdrawing;type:bigint(20);default:0;comment:提现中的钱"` |
||||
DayWithdraw int64 `gorm:"column:day_withdraw;type:bigint(20);default:0;comment:当日退出数额,不论货币"` |
||||
LastWithdraw int64 `gorm:"column:last_withdraw;type:bigint(20);default:0;comment:最近一次退出的时间戳"` |
||||
WithdrawCount int `gorm:"column:withdraw_count;type:int(11);default:0;comment:当天累计退出次数"` |
||||
WithdrawingCash int64 `gorm:"column:withdrawing_cash;type:bigint(20);default:0;comment:提现中的金币" json:"withdrawing_cash"` |
||||
} |
||||
|
||||
func (r *RechargeInfo) TableName() string { |
||||
return "recharge_info" |
||||
} |
||||
|
||||
// RechargeInfoCurrency 玩家各货币充值信息记录表模板
|
||||
type RechargeInfoCurrency struct { |
||||
ID uint `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
TotalRecharge int64 `gorm:"column:total_recharge;type:bigint(20);default:0;comment:总充值" json:"total_recharge"` |
||||
TotoalWithdraw int64 `gorm:"column:total_withdraw;type:bigint(20);default:0;comment:总退出" json:"total_withdraw"` |
||||
TotoalWithdrawing int64 `gorm:"column:total_withdrawing;type:bigint(20);default:0;comment:总退出中" json:"total_withdrawing"` |
||||
} |
||||
|
||||
// PayInfo 支付信息
|
||||
// Name 收款人姓名
|
||||
// Mobile 收款人手机号码
|
||||
// Email 收款人邮箱
|
||||
// PayType 收款方式
|
||||
// Number 卡号或收款信息
|
||||
type PayInfo struct { |
||||
ID uint `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
Name string `gorm:"column:name;default:'';type:varchar(256);comment:收款人姓名"` |
||||
Mobile string `gorm:"column:mobile;default:'';type:varchar(256);comment:收款人手机号码"` |
||||
Email string `gorm:"column:email;default:'';type:varchar(256);comment:收款人邮箱"` |
||||
PayType PayType `gorm:"column:pay_type;default:1;type:int(11);comment:收款方式"` |
||||
Number string `gorm:"column:number;default:'';type:varchar(256);comment:卡号或收款信息"` |
||||
} |
||||
|
||||
func (p *PayInfo) TableName() string { |
||||
return "pay_info" |
||||
} |
||||
|
||||
// WithdrawCommon 支付信息公共部分 地址格式{"city":"Mumbai","street":"sarang street","houseNumber":"-54/a"}
|
||||
type WithdrawCommon struct { |
||||
Name string // 收款人姓名
|
||||
Mobile string // 收款人手机号码
|
||||
Email string // 收款人邮箱
|
||||
PayType PayType |
||||
Number string |
||||
Address string |
||||
IP string |
||||
} |
||||
@ -0,0 +1,191 @@ |
||||
package common |
||||
|
||||
import ( |
||||
"fmt" |
||||
"time" |
||||
) |
||||
|
||||
const ( |
||||
RedisExpireLock = 10 * time.Second |
||||
RedisExpireToken = 7 * 24 * time.Hour |
||||
RedisExpireCode = 180 * time.Second |
||||
RedisExpireCodeCD = 60 * time.Second |
||||
RedisExpireMail = 3 * time.Second |
||||
RedisExpireControl = 30 * 24 * time.Hour |
||||
RedisExpireActivityRed = 1 * time.Minute // 红包雨活动,给予客户端1分钟去做领取
|
||||
RedisExpireGameEnter = 12 * time.Hour // 进入游戏记录玩家币种的超时时间
|
||||
) |
||||
|
||||
const ( |
||||
RedisTimeoutTx = 10 * time.Second |
||||
) |
||||
|
||||
const ( |
||||
RedisKeyUser = "user" |
||||
RedisKeyCode = "Code" |
||||
RedisKeyCodeCD = "CodeCD" |
||||
RedisKeyToken = "token" |
||||
RedisKeyPlayerStatus = "playerStatus" // 玩家当前游戏状态, 用于断线重连
|
||||
RedisKeyRobotPlaying = "robotPlaying" // 已使用的机器人
|
||||
RedisKeyGameFlow = "gameFlow" // 游戏流水总额统计,用于调控
|
||||
// RedisKeyPlayerControl = "playerControl" // 玩家幸运值/愤怒值
|
||||
RedisKeyWarn = "warn" // 后台预警
|
||||
RedisKeyActivityRed = "activityRed" // 红包雨活动
|
||||
RedisOnline = "online" // 实时在线
|
||||
RedisWaterLevel = "waterLevel" // 水位
|
||||
RedisKeyPayWeight = "payWeight" // 支付渠道权重
|
||||
RedisKeyWitdhrawWeight = "withrawWeight" // 支付渠道权重
|
||||
RedisKeyGamePlay = "gamePlay" // 各游戏玩家游戏局数
|
||||
RedisKeyGameResult = "gameResult" // 记录牌局结果,重启时直接拉取恢复
|
||||
RedisKeyGameWinner = "gameWinner" // 记录历史牌局大赢家
|
||||
RedisKeyCollectCardLottery = "collectCardLottery" // 本次大奖开奖控制
|
||||
RedisKeyCollectCardLotteryCards = "collectCardLotteryCards" // 本次大奖结果
|
||||
RedisKeyPayStatus = "payStatus" // 支付渠道策略
|
||||
RedisKeyRealMail = "realMail" // 给玩家发真实邮件控制
|
||||
// RedisKeyPlayerPay = "playerPay" // 玩家10分钟内付费拉起的渠道记录
|
||||
RedisKeyPlayerPayInterval = "playerPayInterval" // 玩家拉单间隔限制
|
||||
RedisKeyGameCurrency = "gameCurrency" // 玩家进入游戏时选择的币种
|
||||
) |
||||
|
||||
const ( |
||||
RedisLockKeyIP = "lockKeyIP" // 玩家操作频率限制
|
||||
RedisLockKeyEnter = "lockKeyEnter" // 玩家进游戏锁
|
||||
RedisLockKeyControl = "lockKeyControl" // 玩家更新控制参数锁
|
||||
) |
||||
|
||||
func GetRedisKeyGameCurrency(uid int) string { |
||||
return fmt.Sprintf("%v:%v", RedisKeyGameCurrency, uid) |
||||
} |
||||
|
||||
func GetRedisKeyPlayerPayInterval(uid int) string { |
||||
return fmt.Sprintf("%v:%v", RedisKeyPlayerPayInterval, uid) |
||||
} |
||||
|
||||
// func GetRedisKeyPlayerPay(uid int) string {
|
||||
// return fmt.Sprintf("%v:%v", RedisKeyPlayerPay, uid)
|
||||
// }
|
||||
|
||||
// status 发邮件的模板,0是失败邮件,1是成功邮件
|
||||
func GetRedisKeyRealMail(uid int, status int) string { |
||||
desc := "fail" |
||||
if status == 1 { |
||||
desc = "success" |
||||
} |
||||
return fmt.Sprintf("%v:%v:%v", RedisKeyRealMail, desc, uid) |
||||
} |
||||
|
||||
func GetRedisKeyGameWinner(gid int) string { |
||||
return fmt.Sprintf("%v:%v", RedisKeyGameWinner, gid) |
||||
} |
||||
|
||||
func GetRedisKeyGameResult(gid, rid int) string { |
||||
return fmt.Sprintf("%v:%v:%v", RedisKeyGameResult, gid, rid) |
||||
} |
||||
|
||||
func GetRedisKeyWaterLevel(gid, rid int) string { |
||||
return fmt.Sprintf("%v:%v:%v", RedisWaterLevel, gid, rid) |
||||
} |
||||
|
||||
func GetActivityRedKey(uid int) string { |
||||
return fmt.Sprintf("%v:%v", RedisKeyActivityRed, uid) |
||||
} |
||||
|
||||
func GetRedisKeyOnlineKey(field string) string { |
||||
return fmt.Sprintf("%v:%v", RedisOnline, field) |
||||
} |
||||
|
||||
func GetWarnKey(id int) string { |
||||
return fmt.Sprintf("%v:%v", RedisKeyWarn, id) |
||||
} |
||||
|
||||
func GetRedisLockKeyControl(uid int) string { |
||||
return fmt.Sprintf("%v:%v", RedisLockKeyControl, uid) |
||||
} |
||||
|
||||
func GetRedisLockKeyEnter(uid int) string { |
||||
return fmt.Sprintf("%v:%v", RedisLockKeyEnter, uid) |
||||
} |
||||
|
||||
func GetRedisLockKeyIP(ip string) string { |
||||
return fmt.Sprintf("%v:%v", RedisLockKeyIP, ip) |
||||
} |
||||
|
||||
// func GetRedisKeyPlayerControl(uid int) string {
|
||||
// return fmt.Sprintf("%v:%v", RedisKeyPlayerControl, uid)
|
||||
// }
|
||||
|
||||
func GetRedisKeyRobotPlaying(rid int) string { |
||||
return fmt.Sprintf("%v:%v", RedisKeyRobotPlaying, rid) |
||||
} |
||||
|
||||
func GetRedisKeyCode(content string) string { |
||||
return RedisKeyCode + ":" + content |
||||
} |
||||
|
||||
func GetRedisKeyCodeCD(content string) string { |
||||
return RedisKeyCodeCD + ":" + content |
||||
} |
||||
|
||||
func GetRedisKeyUser(uid int) string { |
||||
return fmt.Sprintf("%s:%d", RedisKeyUser, uid) |
||||
} |
||||
|
||||
func GetRedisKeyToken(token string) string { |
||||
return RedisKeyToken + ":" + token |
||||
} |
||||
|
||||
func GetRedisKeyPlayerStatus(uid int) string { |
||||
return fmt.Sprintf("%v:%v", RedisKeyPlayerStatus, uid) |
||||
} |
||||
|
||||
const ( |
||||
EventTrackDataVersion = "EventTrackDataVersion" // 打点数据version存入redis的key hash
|
||||
) |
||||
|
||||
// ==============================================================配置文件
|
||||
const ( |
||||
RedisKeyConfigRoom = "config:Room" |
||||
RedisKeyConfigMillionRobotBet = "config:MillionRobotBet" |
||||
RedisKeyConfigRoomChat = "config:RoomChat" |
||||
RedisKeyConfigRecharge = "config:Recharge" |
||||
RedisKeyConfigRobotConfig = "config:RobotConfig" |
||||
RedisKeyConfigRobotPlayConfig = "config:RobotPlayConfig" |
||||
RedisKeyConfigTPRobotOperate = "config:TPRobotOperate" |
||||
RedisKeyConfigRobotTeenpatti = "config:RobotTeenpatti" |
||||
RedisKeyConfigRobotAKTeenpatti = "config:RobotAKTeenpatti" |
||||
RedisKeyConfigRobotJTeenpatti = "config:RobotJTeenpatti" |
||||
RedisKeyConfigWithdrawAmount = "config:WithdrawAmount" |
||||
RedisKeyConfigWithdrawCondition = "config:WithdrawCondition" |
||||
RedisKeyConfigActivityConfig = "config:ActivityConfig" |
||||
RedisKeyConfigReportActivityConfig = "config:ReportActivityConfig" |
||||
RedisKeyConfigRecharge1ActivityConfig = "config:Recharge1ActivityConfig" |
||||
RedisKeyConfigGoodsConfig = "config:GoodsConfig" |
||||
RedisKeyConfigMatchingTableConfig = "config:MatchingTableConfig" |
||||
RedisKeyConfigNoticeConfig = "config:NoticeConfig" |
||||
RedisKeyConfigBroadcastConfig = "config:BroadcastConfig" |
||||
RedisKeyConfigHelpConfig = "config:HelpConfig" |
||||
RedisKeyConfigDramaAction = "config:DramaAction" |
||||
RedisKeyConfigDramaDeal = "config:DramaDeal" |
||||
) |
||||
|
||||
func GetRedisKeyTPRobotOperateConfig(gameID, roomID int) string { |
||||
return fmt.Sprintf("%v:%v:%v", RedisKeyConfigTPRobotOperate, gameID, roomID) |
||||
} |
||||
|
||||
// ==============================================================后台
|
||||
const ( |
||||
BackendToken = "backendToken" |
||||
BackendReview = "backendReview" |
||||
) |
||||
|
||||
func GetBackendTokenKey(token string) string { |
||||
return BackendToken + ":" + token |
||||
} |
||||
|
||||
func GetBackendReviewKey(date string, channel *int) string { |
||||
ret := fmt.Sprintf("%v:%v", BackendReview, date) |
||||
if channel != nil { |
||||
ret += fmt.Sprintf(":%v", *channel) |
||||
} |
||||
return ret |
||||
} |
||||
@ -0,0 +1,9 @@ |
||||
package common |
||||
|
||||
import ( |
||||
"github.com/gin-gonic/gin" |
||||
) |
||||
|
||||
func HealthCheck(c *gin.Context) { |
||||
c.String(200, "ok") |
||||
} |
||||
@ -0,0 +1,109 @@ |
||||
package common |
||||
|
||||
// 分享配置
|
||||
type ConfigShare struct { |
||||
ID int `gorm:"primarykey"` |
||||
Level int `gorm:"column:level;type:int(11);default:0;comment:等级" web:"level"` |
||||
Bet int64 `gorm:"column:bet;type:bigint(20);default:0;comment:档次投注额" web:"bet"` |
||||
Per int64 `gorm:"column:per;type:bigint(20);default:0;comment:佣金比例,万分位" web:"per"` |
||||
} |
||||
|
||||
func (c *ConfigShare) TableName() string { |
||||
return "config_share" |
||||
} |
||||
|
||||
// 分享配置
|
||||
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"` |
||||
} |
||||
|
||||
func (c *ConfigShareSys) TableName() string { |
||||
return "config_share_sys" |
||||
} |
||||
|
||||
// 绑定关系
|
||||
type ShareInfo struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"` |
||||
Share string `gorm:"column:share;not null;type:varchar(64);uniqueIndex:share;comment:分享码"` |
||||
// UP int `gorm:"column:up;not null;type:int(11);comment:上级"`
|
||||
UP1 int `gorm:"column:up1;type:int(11);default:0;comment:一级"` |
||||
UP2 int `gorm:"column:up2;type:int(11);default:0;comment:二级"` |
||||
UP3 int `gorm:"column:up3;type:int(11);default:0;comment:三级"` |
||||
ChannelID int `gorm:"column:channel_id;type:int(11);default:0;comment:渠道id"` |
||||
Invites int `gorm:"column:invites;type:int(11);default:0;comment:邀请人数"` |
||||
InvaidInvites int `gorm:"column:invalid_invites;type:int(11);default:0;comment:有效邀请人数"` |
||||
InviteReward int64 `gorm:"column:invite_reward;type:bigint(20);default:0;comment:邀请获得的奖励金额"` |
||||
BetReward int64 `gorm:"column:bet_reward;type:bigint(20);default:0;comment:邀请人下注获得的金额"` |
||||
AvailableReward int64 `gorm:"column:available_reward;type:bigint(20);default:0;comment:可支配佣金"` |
||||
Time int64 `gorm:"column:time;type:bigint(20);default:0;comment:加入的时间"` |
||||
} |
||||
|
||||
// 绑定关系
|
||||
// type ShareInfo struct {
|
||||
// ID int `gorm:"primarykey"`
|
||||
// UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid"`
|
||||
// Share string `gorm:"column:share;not null;type:varchar(64);uniqueIndex:share;comment:分享码"`
|
||||
// UP int `gorm:"column:up;not null;type:int(11);comment:上级"`
|
||||
// Level int `gorm:"column:level;default:1;type:int(11);comment:等级"`
|
||||
// ChannelID int `gorm:"column:channel_id;type:bigint(20);comment:渠道id"`
|
||||
|
||||
// Bet int64 `gorm:"column:bet;type:bigint(20);default:0;comment:待结算下注额,结算后会清零"`
|
||||
// TodayBet int64 `gorm:"column:today_bet;type:bigint(20);default:0;comment:今日总下注"`
|
||||
// TotalBet int64 `gorm:"column:total_bet;type:bigint(20);default:0;comment:总下注"`
|
||||
|
||||
// TodayAgentsBet int64 `gorm:"column:today_agents_bet;type:decimal(38);default:0;comment:团队今日下注"`
|
||||
// TotalAgentsBet int64 `gorm:"column:total_agents_bet;type:decimal(38);default:0;comment:团队总下注"`
|
||||
|
||||
// TodayAgents int64 `gorm:"column:today_agents;type:bigint(20);default:0;comment:今日下级数量"`
|
||||
// TotalAgents int64 `gorm:"column:total_agents;type:bigint(20);default:0;comment:总下级数量"`
|
||||
|
||||
// TodayRealAgents int64 `gorm:"column:today_real_agents;type:bigint(20);default:0;comment:今日有效下级数量"`
|
||||
// TotalRealAgents int64 `gorm:"column:total_real_agents;type:bigint(20);default:0;comment:总有效下级数量"`
|
||||
|
||||
// TodayReward int64 `gorm:"column:today_reward;type:bigint(20);default:0;comment:今日佣金"`
|
||||
// TotalReward int64 `gorm:"column:total_reward;type:bigint(20);default:0;comment:总佣金"`
|
||||
|
||||
// TodayUpReward int64 `gorm:"column:today_up_reward;type:bigint(20);default:0;comment:今日给上级创造的佣金"`
|
||||
// AvailableReward int64 `gorm:"column:available_reward;type:bigint(20);default:0;comment:可支配佣金"`
|
||||
// Time int64 `gorm:"column:time;type:bigint(20);default:0;comment:加入的时间"`
|
||||
// }
|
||||
|
||||
func (a *ShareInfo) TableName() string { |
||||
return "share_info" |
||||
} |
||||
|
||||
type ShareOrder struct { |
||||
ID int `gorm:"primarykey"` |
||||
UID int `gorm:"column:uid;not null;type:int(11)"` |
||||
CreateTime int64 `gorm:"column:create_time;type:bigint(20);comment:创建时间"` |
||||
ExamineTime int64 `gorm:"column:examine_time;type:bigint(20);default:0;comment:审核时间"` |
||||
OrderID string `gorm:"column:orderid;not null;type:varchar(255);uniqueIndex:orderid;comment:本地ID"` |
||||
Amount int64 `gorm:"column:amount;not null;type:bigint(20);comment:单位8位小数"` |
||||
ChannelID int `gorm:"column:channel_id;type:bigint(20);comment:渠道id"` |
||||
Status int `gorm:"column:status;not null;type:tinyint(4);comment:1新建,2支付完成,3发货完成,4支付失败,5取消"` |
||||
} |
||||
|
||||
func (a *ShareOrder) TableName() string { |
||||
return "share_order" |
||||
} |
||||
|
||||
// 机器人
|
||||
type ConfigShareRobot struct { |
||||
ID int `gorm:"primarykey"` |
||||
RobotID int `gorm:"column:robot_id;type:int(11);default:0" web:"robot_id"` |
||||
Avatar string `gorm:"column:avatar;type:varchar(255);default:''" web:"avatar"` |
||||
Nick string `gorm:"column:nick;type:varchar(255);default:''" web:"nick"` |
||||
InitCash int64 `gorm:"column:init_cash;type:bigint(20);default:0;comment:初始金币" web:"init_cash"` |
||||
DayCashDown int64 `gorm:"column:day_cash_down;type:bigint(20);default:0;comment:每日增加金币数下限" web:"day_cash_down"` |
||||
DayCashUp int64 `gorm:"column:day_cash_up;type:bigint(20);default:0;comment:每日增加金币数上限" web:"day_cash_up"` |
||||
} |
||||
|
||||
func (c *ConfigShareRobot) TableName() string { |
||||
return "config_share_robot" |
||||
} |
||||
@ -0,0 +1,66 @@ |
||||
package common |
||||
|
||||
const ( |
||||
TaskTypeZero = iota |
||||
TaskTypeRegist // 注册任务
|
||||
TaskTypeDownload // 下载app任务
|
||||
TaskTypeTotalRecharge // 累充任务
|
||||
TaskTypeOnceRecharge // 单次充值任务
|
||||
TaskTypeFirstRecharge // 首次充值任务
|
||||
TaskTypeAll |
||||
) |
||||
|
||||
// 判读任务的目标是否是次数
|
||||
func IsNumTaskType(t int) bool { |
||||
return t == TaskTypeRegist || t == TaskTypeDownload |
||||
} |
||||
|
||||
func GetTaskTitle(task *ConfigTask) string { |
||||
// switch task.Type {
|
||||
// case TaskTypeTotalRecharge:
|
||||
// return fmt.Sprintf(task.Title, task.Target/DecimalDigits)
|
||||
// case TaskTypeOnceRecharge:
|
||||
// return fmt.Sprintf(task.Title, task.Target/DecimalDigits)
|
||||
// }
|
||||
return task.Title |
||||
} |
||||
|
||||
const ( |
||||
TaskKindZero = iota |
||||
TaskKindOnce |
||||
TaskKindCycle |
||||
TaskKindAll |
||||
) |
||||
|
||||
// ConfigTask 任务配置
|
||||
// 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"` |
||||
} |
||||
|
||||
func (c *ConfigTask) TableName() string { |
||||
return "config_task" |
||||
} |
||||
|
||||
type TaskData struct { |
||||
ID int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"ID"` |
||||
UID int `gorm:"column:uid;not null;type:int(11);uniqueIndex:uid" json:"UID"` |
||||
Time int64 `gorm:"column:time;not null;type:bigint(20);default:0;comment:任务生成时间" json:"Time"` |
||||
TaskID int `gorm:"column:task_id;type:int(11);default:0;uniqueIndex:uid;comment:任务id" web:"task_id"` |
||||
Progress int64 `gorm:"column:progress;type:bigint(20);default:0;comment:进度" web:"progress"` |
||||
} |
||||
|
||||
func (c *TaskData) TableName() string { |
||||
return "task_data" |
||||
} |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue