dev_aagame_provider
zhora 2 months ago
parent 66c8ffa2b7
commit b5a3e29bf1
  1. 160
      call/config.go
  2. 22
      call/share.go
  3. 34
      call/user.go
  4. 1
      common/share.go
  5. 2
      db/mysql/mysql_exec.go
  6. 14
      modules/backend/handler/examine/examine.go
  7. 3
      modules/backend/values/gameuser.go
  8. 226
      modules/customer/app/response.go
  9. 21
      modules/customer/bdb/exec.go
  10. 35
      modules/customer/bdb/mysql.go
  11. 21
      modules/customer/config.go
  12. 81
      modules/customer/handler/account/account.go
  13. 414
      modules/customer/handler/chat/chat.go
  14. 216
      modules/customer/handler/common/common.go
  15. 451
      modules/customer/handler/gm/gm.go
  16. 12
      modules/customer/handler/gm/values.go
  17. 122
      modules/customer/handler/guser/activeUserList.go
  18. 87
      modules/customer/handler/guser/addUserBlackList.go
  19. 31
      modules/customer/handler/guser/addUserTag.go
  20. 58
      modules/customer/handler/guser/banUserList.go
  21. 1
      modules/customer/handler/guser/bigRUserData.go
  22. 81
      modules/customer/handler/guser/controlCardData.go
  23. 53
      modules/customer/handler/guser/editGameUserGold.go
  24. 56
      modules/customer/handler/guser/editGameUserStatus.go
  25. 34
      modules/customer/handler/guser/getGameUserAllBalance.go
  26. 47
      modules/customer/handler/guser/getGameUserControlBalance.go
  27. 183
      modules/customer/handler/guser/getGameUserInfo.go
  28. 206
      modules/customer/handler/guser/getGameUserList.go
  29. 52
      modules/customer/handler/guser/getGameUserPlayData.go
  30. 67
      modules/customer/handler/guser/getGameUserPlayDetail.go
  31. 63
      modules/customer/handler/guser/getGameUserRechargeHistory.go
  32. 67
      modules/customer/handler/guser/getGameUserWithdrawHistory.go
  33. 113
      modules/customer/handler/guser/lostPlayerData.go
  34. 242
      modules/customer/handler/guser/lostUserData.go
  35. 39
      modules/customer/handler/guser/lostUserDetail.go
  36. 96
      modules/customer/handler/guser/rechargeRank.go
  37. 208
      modules/customer/handler/power/power.go
  38. 48
      modules/customer/middleware/cross.go
  39. 68
      modules/customer/middleware/power.go
  40. 90
      modules/customer/middleware/token.go
  41. 114
      modules/customer/module.go
  42. 41
      modules/customer/routers/routers.go
  43. 14
      modules/customer/routers/routers_account.go
  44. 42
      modules/customer/routers/routers_chat.go
  45. 23
      modules/customer/routers/routers_common.go
  46. 31
      modules/customer/routers/routers_gm.go
  47. 26
      modules/customer/routers/routers_guser.go
  48. 12
      modules/customer/routers/routers_mail.go
  49. 16
      modules/customer/routers/routers_power.go
  50. 113
      modules/customer/timer.go
  51. 34
      modules/customer/values/account.go
  52. 122
      modules/customer/values/chat.go
  53. 63
      modules/customer/values/common.go
  54. 10
      modules/customer/values/errorCode.go
  55. 96
      modules/customer/values/gm.go
  56. 111
      modules/customer/values/powers.go
  57. 53
      modules/customer/values/tables.go
  58. 3
      modules/pay/allpay/all.go
  59. 15
      modules/pay/antpay/base.go
  60. 13
      modules/pay/ddaypay/base.go
  61. 21
      modules/pay/feipay/base.go
  62. 21
      modules/pay/foxpay/base.go
  63. 17
      modules/pay/fpay/base.go
  64. 19
      modules/pay/gallopay/base.go
  65. 15
      modules/pay/hongxinpay/base.go
  66. 17
      modules/pay/jjpay/base.go
  67. 1
      modules/pay/kingpay/base.go
  68. 2
      modules/pay/luckyinpay/base.go
  69. 23
      modules/pay/mlpay2/base.go
  70. 2
      modules/pay/payplus/base.go
  71. 15
      modules/pay/propay/base.go
  72. 21
      modules/pay/richpay/base.go
  73. 23
      modules/pay/superpay/base.go
  74. 3
      modules/pay/timer.go
  75. 18
      modules/pay/tkpay/base.go
  76. 81
      modules/pay/values/values.go
  77. 20
      modules/pay/virgopay/base.go
  78. 27
      modules/web/app/account.go
  79. 2
      modules/web/app/response.go
  80. 18
      modules/web/handler/share.go
  81. 7
      modules/web/handler/user.go
  82. 1
      modules/web/middleware/token.go
  83. 2
      modules/web/providers/jin/base.go
  84. 6
      modules/web/providers/jin/handler.go

@ -448,6 +448,165 @@ func GetConfigWithdrawChannels() []*common.ConfigWithdrawChannels {
return ret
}
func GetWithdrawChannelName(channelId int) string {
var name string
switch channelId {
case 0:
name = "FunzonePay"
case 1:
name = "WellPay"
case 2:
name = "OctroPay"
case 3:
name = "IGeekPay"
case 4:
name = "CloudPay"
case 5:
name = "VSPay"
case 6:
name = "JoyPay"
case 7:
name = "FFPay"
case 8:
name = "BestPay"
case 9:
name = "HXPay"
case 10:
name = "MGPay"
case 11:
name = "OOPay"
case 12:
name = "ZWPay"
case 13:
name = "FastPay"
case 14:
name = "HaoPay"
case 15:
name = "QPPay"
case 16:
name = "OwlPay"
case 17:
name = "SkyPay"
case 18:
name = "GrePay"
case 19:
name = "MoonPay"
case 20:
name = "Acepay"
case 21:
name = "MccPay"
case 22:
name = "YoduPay"
case 23:
name = "WordPay"
case 24:
name = "HWPay"
case 25:
name = "JJPay"
case 26:
name = "AntPay"
case 27:
name = "MlPay"
case 28:
name = "RojPay"
case 29:
name = "QuantaPay"
case 30:
name = "InnoPay"
case 31:
name = "PePay"
case 32:
name = "FF8Pay"
case 33:
name = "flapay"
case 34:
name = "DidaPay"
case 35:
name = "CYGGPay"
case 36:
name = "ZPay"
case 37:
name = "HappyPay"
case 38:
name = "FastPlusPay"
case 39:
name = "GoPay"
case 40:
name = "LemonPay"
case 41:
name = "CamelPay"
case 42:
name = "MoonPay2"
case 43:
name = "Spay"
case 44:
name = "VendooPay"
case 45:
name = "EaniPay"
case 46:
name = "AgroPay"
case 47:
name = "H4pay"
case 48:
name = "NativePay"
case 49:
name = "FeiPay"
case 50:
name = "VTPay"
case 51:
name = "NewbePay"
case 52:
name = "RoosPay"
case 53:
name = "ProPay"
case 54:
name = "FoxPay"
case 55:
name = "SuperPay"
case 56:
name = "STGoPay"
case 57:
name = "QeelinPay"
case 58:
name = "airpay"
case 59:
name = "NSpay"
case 60:
name = "RupeePay"
case 61:
name = "Fpay"
case 62:
name = "kingpay"
case 63:
name = "tkpay"
case 64:
name = "GalloPay"
case 65:
name = "MLPay2"
case 66:
name = "GlobalPay"
case 67:
name = "DDayPay"
case 68:
name = "HongxinPay"
case 69:
name = "Richpay"
case 70:
name = "MoneydealerPay"
case 71:
name = "MtxxPay"
case 72:
name = "robus"
case 73:
name = "MoneydealerNatviePay"
case 74:
name = "Virgopay"
default:
name = "unknown name"
}
return name
}
// GetConfigWithdrawLimits 获取赠送上下限配置
func GetConfigWithdrawLimits() (down, up int64) {
for _, v := range configWithdrawChannels {
@ -2307,6 +2466,7 @@ func GetShareWithdrawInfo(uid int) *common.ShareWithdrawInfo {
}
if !util.IsSameDayTimeStamp(now, info.DayTime) {
info.DayCount = 0
info.TodayWithdraw = 0
}
if info.DayCount < 0 {
info.DayCount = 0

@ -113,14 +113,26 @@ func ShareBind(share string, isOld bool, uid, cid int) {
}
}
// 更新上级的下级数
ref := reflect.ValueOf(upInfo).Elem()
for i := 1; i <= 4; i++ {
upUid := int(ref.FieldByName(fmt.Sprintf("UP%d", i)).Int())
ref := reflect.ValueOf(upInfo).Elem() // 上级的1-5级
for i := 0; i <= 4; i++ {
var upUid int
if i == 0 {
upUid = upInfo.UID
} else {
upUid = int(ref.FieldByName(fmt.Sprintf("UP%d", i)).Int())
}
if uid == 0 {
break
continue
}
field := fmt.Sprintf("down%d", i+1)
db.Mysql().Update(&common.ShareInfo{UID: upUid}, map[string]interface{}{field: gorm.Expr(fmt.Sprintf("%s + 1", field))})
log.Debug("uid:%d, field:%s", upUid, field)
updateErr := db.Mysql().C().Model(&common.ShareInfo{}).Where("uid = ?", upUid).Updates(map[string]interface{}{
field: gorm.Expr(fmt.Sprintf("`%s` + 1", field)),
}).Error
if updateErr != nil {
log.Error("update share info err, %s", updateErr.Error())
}
//db.Mysql().Update(&common.ShareInfo{UID: upUid}, map[string]interface{}{field:})
}
// todo

@ -164,28 +164,30 @@ func NewUser(info *common.PlayerDBInfo, ip, share, fbc, fbp, agent string) error
// 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)
ShareBind(share, isOld, uid, cid)
// 新手赠送
first := GetConfigPlatform().NewPlayerGift
if first > 0 {
UpdateCurrencyPro(&common.UpdateCurrency{
CurrencyBalance: &common.CurrencyBalance{
UID: uid,
Value: first,
ChannelID: info.ChannelID,
Type: common.CurrencyINR,
Event: common.CurrencyEventNewPlayer,
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, first),
},
})
}
util.Go(func() {
initPlayer(uid, cid)
UploadAdjust(common.AdjustEventNewPlayer, info, nil)
ShareBind(share, isOld, uid, cid)
// 新手赠送
first := GetConfigPlatform().NewPlayerGift
if first > 0 {
UpdateCurrencyPro(&common.UpdateCurrency{
CurrencyBalance: &common.CurrencyBalance{
UID: uid,
Value: first,
ChannelID: info.ChannelID,
Type: common.CurrencyINR,
Event: common.CurrencyEventNewPlayer,
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, first),
},
})
}
FBBind(ip, uid, cid, fbc, fbp, agent)
UploadFB(uid, FBEventRegist, 0)
UploadKwai(uid, KwaiEventRegist, 0)
})
//})
return nil
}

@ -385,6 +385,7 @@ type ShareWithdrawInfo struct {
DayCount int `gorm:"column:day_count;type:int(11);default:0;comment:日退出次数"`
DayTime int64 `gorm:"column:day_time;type:bigint(20);default:0;comment:日退出时间标记"`
Record string `gorm:"column:record;type:varchar(256);default:'';comment:已退出金额标记"`
TodayWithdraw int64 `gorm:"column:today_withdraw;type:int(11);default:0;comment:已退出总数(今天)"`
TotalWithdraw int64 `gorm:"column:total_withdraw;type:int(11);default:0;comment:已退出总数"`
SubRecord map[int64]int `gorm:"-"`
}

@ -304,7 +304,7 @@ func (u *MysqlClient) QueryPlayerRWHistory(uid *int, channel *int, page, num int
}
}
if status != nil && status[0] != nil {
query += fmt.Sprintf(" and status = %v", *status[0])
query += fmt.Sprintf(" and `status` = %v", *status[0])
}
if uid != nil {
query += fmt.Sprintf(" and uid = %v", *uid)

@ -106,15 +106,11 @@ func WithdrawList(c *gin.Context) {
a.Code = values.CodeRetry
return
}
payList := map[int]string{
18: "GrePay",
27: "MLPay",
39: "GoPay",
42: "MoonPay",
43: "PayPlus",
44: "LuckinPay",
45: "EaniPay",
46: "AgroPay",
payList := make(map[int]string)
withdrawChannels := call.GetConfigWithdrawChannels()
for _, v := range withdrawChannels {
payList[v.ChannelID] = call.GetWithdrawChannelName(v.ChannelID)
}
a.Data = values.WithdrawListResp{List: WithdrawOrderArr, Count: count, PayList: payList}
}

@ -207,12 +207,13 @@ type GetGameUserPlayDataResp struct {
// ProviderID
type OneGameUserPlayData struct {
Time int64
GameID int
RoomName int
Value int64
Balance int64
UUID string
ProviderID int
GameID int
GameName string
}
// GetGameUserControlBalanceReq 获取游戏玩家控杀流水

@ -0,0 +1,226 @@
package app
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"server/db"
"server/modules/customer/bdb"
"server/modules/customer/values"
"server/util"
"time"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"gorm.io/gorm"
)
type Gin struct {
C *gin.Context
R
User *values.User
}
type R struct {
Data interface{} `json:"data"`
Msg string `json:"msg"`
Code int `json:"code"`
}
func NewApp(c *gin.Context) *Gin {
g := &Gin{C: c, R: R{Code: values.CodeOK, Msg: "ok"}}
user, ex := c.Get("user")
if ex {
g.User = user.(*values.User)
if len(g.User.Channels) > 0 {
json.Unmarshal([]byte(g.User.Channels), &g.User.SChannels)
}
}
return g
}
// Response setting gin.JSON
func (g *Gin) Response() {
if g.Code == values.CodeRetry {
g.Msg = "内部错误"
} else if g.Code == values.CodePower {
g.Msg = "您无权操作此项"
}
g.C.JSON(http.StatusOK, g.R)
}
func (g *Gin) RecordEdit(t int, detail string) {
u, _ := g.C.Get("user")
user := u.(*values.User)
one := &values.EditHistory{Model: t, Detail: detail, Time: time.Now().Unix(), Operator: user.Name, UID: int(user.ID)}
bdb.BackDB.Create(one)
}
func (g *Gin) S(one interface{}) (pass bool) {
err := g.C.ShouldBind(one)
if err != nil {
g.R.Code = values.CodeParam
g.R.Msg = err.Error()
log.Error("bind %v err:%v", reflect.TypeOf(one), err)
return
}
pass = true
return
}
// U 统一json解析方法
func (g *Gin) U(src []byte, tar interface{}) (pass bool) {
err := json.Unmarshal(src, tar)
if err != nil {
log.Error("%v err:%v", reflect.TypeOf(tar), err)
g.R.Code = values.CodeRetry
g.R.Msg = err.Error()
return
}
pass = true
return
}
// MCommit 提交事务
func (g *Gin) MCommit(tx *gorm.DB) {
if g.Code == values.CodeOK {
if err := tx.Commit().Error; err != nil {
tx.Rollback()
return
}
} else {
tx.Rollback()
return
}
}
// CheckPower 检查权限是否合法
func (g *Gin) CheckPower(power string) bool {
newMap := map[int][]int{}
if err := json.Unmarshal([]byte(power), &newMap); err != nil {
log.Error("err:%v", err)
g.Code = values.CodeParam
g.Msg = err.Error()
return false
}
for i := range newMap {
if !values.IsValidPower(i) {
log.Error("invalid power:%v", i)
g.Code = values.CodeParam
g.Msg = fmt.Sprintf("未知权限参数%v", i)
return false
}
}
return true
}
// 从数据库中读取数据
func (g *Gin) MGetSqlAll(model, tar interface{}, condition map[string]interface{}) (pass bool) {
sql := ""
mod := reflect.TypeOf(model).Elem()
for k, v := range condition {
tmp, ok := mod.FieldByName(k)
if !ok {
log.Error("invalid model:%v,condition:%v", model, condition)
continue
}
tag := tmp.Tag.Get("web")
if tag == "" || tag == "-" {
log.Error("invalid model:%v,condition:%v", model, condition)
continue
}
reft := reflect.TypeOf(v)
ref := reflect.ValueOf(v)
if reft.Kind() == reflect.Slice {
if ref.Len() != 2 {
log.Error("invalid model:%v,condition:%v", model, condition)
continue
}
if len(sql) > 0 {
sql += " and "
}
sql += fmt.Sprintf("%s >= %v and %s <= %v", tag, ref.Index(0).Interface(), tag, ref.Index(1).Interface())
} else {
if len(sql) > 0 {
sql += " and "
}
sql += fmt.Sprintf("%s = %v", tag, ref.Interface())
}
}
if _, err := db.Mysql().QueryAll(sql, "", model, tar); err != nil {
log.Error("err:%v", err)
g.Code = values.CodeRetry
g.R.Msg = err.Error()
return
}
pass = true
return
}
func (g *Gin) MUpdateAll(updates []map[string]interface{}, element interface{}) (pass bool) {
for _, v := range updates {
tmp := reflect.New(reflect.TypeOf(element).Elem()).Interface()
// log.Debug("%v", v)
tmpbyte, _ := json.Marshal(v)
err := json.Unmarshal(tmpbyte, &tmp)
if err != nil {
log.Error("err%v", err)
return
}
ref := reflect.ValueOf(tmp).Elem()
reft := reflect.TypeOf(tmp).Elem()
id := ref.FieldByName("ID").Int()
if id == 0 {
if err := db.Mysql().Create(tmp); err != nil {
g.Code = values.CodeRetry
return
}
} else {
update := map[string]interface{}{}
for k := range v {
field, ok := reft.FieldByName(k)
if !ok {
field, ok = util.GetStructFieldByJsonTag(tmp, k)
if !ok {
continue
}
k = field.Name
}
tag := field.Tag.Get("web")
if tag == "" || tag == "-" {
continue
}
update[tag] = ref.FieldByName(k).Interface()
}
// update := util.StructToMap(tmp, "web")
model := reflect.New(reflect.TypeOf(element).Elem())
model.Elem().FieldByName("ID").SetInt(id)
// log.Debug("element:%v", element)
log.Debug("update:%v", update)
log.Debug("model:%v", model)
if err := db.Mysql().Update(model.Interface(), update); err != nil {
g.Code = values.CodeRetry
return
}
}
}
pass = true
return
}
func (g *Gin) MDel(id int, element interface{}) (pass bool) {
tmp := reflect.New(reflect.TypeOf(element).Elem())
tmp.Elem().FieldByName("ID").SetInt(int64(id))
if !db.Mysql().Exist(tmp.Interface()) {
g.Code = values.CodeParam
g.Msg = "该id不存在"
return
}
if err := db.Mysql().Del(tmp.Interface()); err != nil {
g.Code = values.CodeRetry
return
}
pass = true
return
}

@ -0,0 +1,21 @@
package bdb
import (
"encoding/json"
"server/modules/customer/values"
"github.com/liangdas/mqant/log"
)
func GetPowerByRole(role int) map[int][]int {
one := &values.Role{Role: role}
BackDB.Get(one)
ret := map[int][]int{}
if len(one.Power) > 0 {
err := json.Unmarshal([]byte(one.Power), &ret)
if err != nil {
log.Error("err:%v", err)
}
}
return ret
}

@ -0,0 +1,35 @@
package bdb
import (
"fmt"
"server/config"
mdb "server/db/mysql"
"server/modules/customer/values"
)
var BackDB *mdb.MysqlClient
func InitMysql() {
var err error
fmt.Println(config.GetConfig().Customer.DB)
BackDB, err = mdb.InitMysqlClient(config.GetConfig().Customer.DB, false)
if err != nil {
panic(err)
}
}
// MigrateDB 自动数据库迁移
func MigrateDB() {
err := BackDB.C().AutoMigrate(new(values.User))
if err != nil {
panic(err)
}
err = BackDB.C().AutoMigrate(new(values.EditHistory))
if err != nil {
panic(err)
}
err = BackDB.C().AutoMigrate(new(values.Role))
if err != nil {
panic(err)
}
}

@ -0,0 +1,21 @@
package customer
import (
"server/call"
"server/common"
"server/pb"
)
func loadConfig() error {
c := map[int][]func(*pb.ReloadGameConfig) error{}
c[common.ReloadTypeExcel] = []func(*pb.ReloadGameConfig) error{ReloadExcel}
call.LoadConfigs(c)
return nil
}
func ReloadExcel(c *pb.ReloadGameConfig) error {
if err := call.LoadGoodsConfig(); err != nil {
return err
}
return nil
}

@ -0,0 +1,81 @@
// 账号相关的接口实现
package handler
import (
"fmt"
"server/common"
"server/db"
"server/modules/customer/app"
"server/modules/customer/bdb"
"server/modules/customer/values"
"server/util"
"github.com/liangdas/mqant/log"
"github.com/gin-gonic/gin"
)
func Login(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.LoginReq)
if !a.S(req) {
return
}
one := &values.User{Account: req.Account, Password: req.Pass}
if err := bdb.BackDB.Get(one); err != nil {
a.Code = values.CodeParam
a.Msg = "账号不存在"
return
}
token := util.GetSimpleRandomString(6)
err := db.Redis().SetJsonData(common.GetBackendTokenKey(token), one, values.RedisTokenEx)
if err != nil {
log.Error(err.Error())
}
a.Data = values.LoginResp{Role: one.Role, Token: token, Power: one.Power, Id: int(one.ID)}
}
// 操作 1上线 2下线
type OnlineReq struct {
Opt int
}
func Online(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
// if a.User.Role != values.UserRole2 {
// return
// }
req := new(OnlineReq)
if !a.S(req) {
return
}
str := "上线"
opt := 1
if req.Opt == 2 {
str = "下线"
opt = 0
}
bdb.BackDB.Update(&values.User{ID: a.User.ID}, map[string]interface{}{"online": opt})
a.RecordEdit(values.PowerGM, fmt.Sprintf("客服%s", str))
}
type OnlineResp struct {
Status int
}
func OnlineStatus(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
user := &values.User{ID: a.User.ID}
bdb.BackDB.Get(user)
resp := OnlineResp{Status: user.Online}
a.Data = resp
}

@ -0,0 +1,414 @@
package chat
import (
"fmt"
"server/call"
"server/common"
"server/db"
"server/modules/customer/app"
"server/modules/customer/values"
"server/pb"
"time"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"gorm.io/gorm"
)
// 获取聊天历史
func GetCustomerHistory(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.GetCustomerHistoryReq)
if !a.S(req) {
return
}
var resp values.GetCustomerHistoryResp
Count, err := db.Mysql().QueryList(req.Page-1, req.Num, fmt.Sprintf("title = %v", req.Title), "time DESC", &common.CustomerChatData{}, &resp.List)
if err != nil {
if err != gorm.ErrRecordNotFound {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
}
resp.Count = Count
a.Data = resp
}
// 消息已读
func ReadMessage(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.ReadMessageReq{}
if !a.S(req) {
return
}
for i := 0; i < len(req.List); i++ {
err := db.Mysql().Update(&common.CustomerChatData{ID: req.List[i], Title: req.Title}, map[string]interface{}{"is_read": true})
if err != nil {
log.Error(err.Error())
}
}
if req.OrderId != 0 {
db.Mysql().Update(&common.CustomerOrder{ID: req.OrderId}, map[string]interface{}{
"un_read": 0,
})
}
// 需要通知在线玩家刷新客服消息
//session := call.GetUserSession(req.Title)
//if session == nil {
// return
//}
//call.SendSS(session, int(pb.ServerCommonCmd_CMD_BS_CustomerMsgResp), nil, "common")
}
// 玩家发送消息
func SendMessage(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.SendMessageReq{}
if !a.S(req) {
return
}
req.Time = time.Now().Unix()
err := db.Mysql().Create(&req)
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
list := []common.CustomerOrder{}
db.Mysql().QueryList(0, 100, fmt.Sprintf("uid = %d and reply = 0", req.Title), "", &common.CustomerOrder{}, &list)
for _, v := range list {
u := map[string]interface{}{"is_read": false, "reply": true}
if v.FirstReplyTime == 0 {
u["first_reply_time"] = req.Time
}
db.Mysql().Update(&common.CustomerOrder{ID: v.ID}, u)
}
// 客服回复后,标记玩家读取状态为未读
// db.Mysql().Update(&common.CustomerOrder{Uid: req.Title}, map[string]interface{}{"is_read": false, "reply": true})
// 需要通知在线玩家刷新客服消息
session := call.GetUserSession(req.Title)
if session == nil {
return
}
call.SendSS(session, int(pb.ServerCommonCmd_CMD_BS_CustomerMsgResp), nil, "common")
}
// 根据订单状态获取订单列表
func GetCustomerOrder(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.GetCustomerOrderReq{}
if !a.S(req) {
return
}
var resp values.GetCustomerOrderResp
var flag bool
var query string
if req.Label != 0 {
query += fmt.Sprintf(" (label1 = %v OR label2 = %v OR label3 = %v OR label4 = %v OR label5 = %v) ", req.Label, req.Label, req.Label, req.Label, req.Label)
flag = true
}
if req.Uid != 0 {
if flag {
query += " AND "
}
query += fmt.Sprintf(" uid = %v ", req.Uid)
flag = true
} else {
if req.CustomerUid != 0 {
if flag {
query += " AND "
}
query += fmt.Sprintf(" customer_uid = %v ", req.CustomerUid)
flag = true
} else if a.User.Role == values.UserRole2 {
if flag {
query += " AND "
}
query += fmt.Sprintf(" customer_uid = %v ", a.User.ID)
flag = true
}
}
if req.Status != 0 {
if flag {
query += " AND "
}
query = fmt.Sprintf(" status = %v", req.Status)
flag = true
} else {
if req.Status2 != 0 {
if flag {
query += " AND "
}
query = fmt.Sprintf(" status <= %v", req.Status2)
flag = true
}
}
if req.Vip != 0 {
if flag {
query += " AND "
}
query += fmt.Sprintf(" vip >= %v ", req.Vip)
flag = true
}
if req.Reply > 0 {
if flag {
query += " AND "
}
if req.Reply == 1 {
query += fmt.Sprintf(" reply = %d ", 1)
} else {
query += fmt.Sprintf(" reply = %d ", 0)
}
flag = true
}
if req.Recharge {
if flag {
query += " AND "
}
query += " order_id != ''"
flag = true
}
var order = "start DESC"
if req.Order == 2 {
order = "start ASC"
}
if req.Order == 3 {
order = "un_read DESC"
}
count, err := db.Mysql().QueryList(req.Page-1, req.Num, query, order, &common.CustomerOrder{}, &resp.List)
if err != nil && err != gorm.ErrRecordNotFound {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
resp.Count = count
a.Data = resp
}
// 工单处理状态改变
func ChangeCustomerOrderStatus(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.ChangeCustomerOrderReq{}
if !a.S(req) {
return
}
for i := 0; i < len(req.List); i++ {
update := make(map[string]interface{})
/*if req.List[i].Status != 0 {
update["status"] = req.List[i].Status
}
if req.List[i].Label1 != 0 {
update["label1"] = req.List[i].Label1
}
if req.List[i].Label2 != 0 {
update["label2"] = req.List[i].Label2
}
if req.List[i].Label3 != 0 {
update["label3"] = req.List[i].Label3
}
if req.List[i].Label4 != 0 {
update["label4"] = req.List[i].Label4
}
if req.List[i].Label5 != 0 {
update["label5"] = req.List[i].Label5
}
if len(update) < 1 {
continue
}*/
if req.List[i].Status == common.CustomerOrderComplete {
order := &common.CustomerOrder{ID: req.List[i].Id}
db.Mysql().Get(order)
if !order.Reply {
a.Code = values.CodeParam
a.Msg = fmt.Sprintf("玩家%d的订单还未回复,不能修改为完成状态", order.Uid)
return
}
}
update["status"] = req.List[i].Status
update["label1"] = req.List[i].Label1
update["label2"] = req.List[i].Label2
update["label3"] = req.List[i].Label3
update["label4"] = req.List[i].Label4
update["label5"] = req.List[i].Label5
// if req.List[i].Remark != "" {
update["remark"] = req.List[i].Remark
// }
// 完成工单
update["end"] = time.Now().Unix()
update["un_read"] = 0
err := db.Mysql().Update(&common.CustomerOrder{ID: req.List[i].Id}, update)
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
}
}
// 分配工单到客服人员
func CustomerOrderAllocate(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.CustomerOrderAllocateReq{}
if !a.S(req) {
return
}
tx := db.Mysql().Begin()
defer a.MCommit(tx)
for i := 0; i < len(req.List); i++ {
err := tx.Exec("UPDATE customer_order SET customer_uid = ?, status = ? WHERE id = ? AND status != ?", req.List[i].Uid, common.CustomerOrderAllocate, req.List[i].OrderId, common.CustomerOrderComplete).Error
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
}
}
}
// 编辑标签
func EditCustomerOrderLabel(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.EditCustomerOrderLabelReq{}
if !a.S(req) {
return
}
update := make(map[string]interface{})
update["label1"] = req.LabelId1
update["label2"] = req.LabelId2
update["label3"] = req.LabelId3
update["label4"] = req.LabelId4
update["label5"] = req.LabelId5
err := db.Mysql().Update(&common.CustomerOrder{ID: req.OrderId}, update)
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
}
// 获取玩家信息
func GetPlayerInfo(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.GetPlayerInfoReq{}
if !a.S(req) {
return
}
var resp values.GetPlayerInfoResp
// 玩家信息
player, err := call.GetUserXInfo(req.Uid, "channel_id", "nick", "avatar", "birth", "mobile")
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
resp.Uid = req.Uid
resp.Nick = player.Nick
resp.Avatar = player.Avatar
resp.Birth = player.Birth
resp.Phone = player.Mobile
resp.Channel = player.ChannelID
// 渠道信息
channel := &common.Channel{ChannelID: player.ChannelID}
err = db.Mysql().Get(channel)
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
resp.Package = channel.PackName
// vip
resp.Vip = call.GetVIP(req.Uid).Level
order := &common.RechargeInfo{UID: req.Uid}
err = db.Mysql().Get(order)
if err != nil {
log.Error(err.Error())
}
resp.Withdraw = order.TotalWithdraw
resp.Recharge = order.TotalRecharge
if db.Mysql().Exist(&common.CustomerBlackUser{Uid: req.Uid}) {
resp.CustomerBlack = true
}
a.Data = resp
}
// 玩家历史客诉记录
func ComplaintHistory(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.ComplaintHistoryReq{}
if !a.S(req) {
return
}
var resp values.ComplaintHistoryResp
count, err := db.Mysql().QueryList(req.Page-1, req.Num, fmt.Sprintf("uid = %v", req.Uid), "", &common.CustomerOrder{}, &resp.List)
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
resp.Count = count
a.Data = resp
}

@ -0,0 +1,216 @@
package common
import (
"fmt"
"io"
"mime"
"net/http"
"os"
"server/call"
"server/config"
"server/modules/customer/app"
"server/modules/customer/bdb"
"server/modules/customer/values"
"server/util"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
// 上传图片 并返回图片地址
func UploadImage(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
// 解析请求中的 multipart/form-data
err := c.Request.ParseMultipartForm(10 << 20) // 限制上传文件的大小为 10MB
if err != nil {
log.Error("图片超过10Mb, err:%v", err.Error())
a.Code = values.CodeParam
return
}
// 打开上传的文件
file, header, err := c.Request.FormFile("file")
if err != nil {
log.Error("打开上传图片失败, err:%v", err.Error())
a.Code = values.CodeParam
return
}
defer file.Close()
// 获取上传文件的 MIME 类型
contentType := header.Header.Get("Content-Type")
// 根据 MIME 类型获取文件扩展名
ext, err := mime.ExtensionsByType(contentType)
if err != nil || len(ext) == 0 {
log.Error("获取上传图片格式失败, err:%v", err.Error())
a.Code = values.CodeParam
return
}
imageName := call.SnowNode().Generate().String() + ext[0]
// 读取上传的文件内容
data, err := io.ReadAll(file)
if err != nil {
log.Error("读取图片内容失败, err:%v", err.Error())
a.Code = values.CodeRetry
return
}
// 获取当前本地时间
now := time.Now()
zeroTime := now.Format("20060102")
rounded := now.Hour()
dir := fmt.Sprintf("%v/%v/%v", values.ImagePath, zeroTime, rounded)
// 创建保存文件的目标文件
err = createDirIfNotExist(dir)
if err != nil {
log.Error("创建图片保存目录, err:%v", err.Error())
a.Code = values.CodeParam
return
}
// 将上传的文件复制到目标文件
err = os.WriteFile(dir+"/"+imageName, data, 0644) // 写入文件
if err != nil {
a.Code = values.CodeRetry
return
}
name := strings.Replace(dir+"/"+imageName, "/", ",", -1)
a.Data = config.GetConfig().Customer.ImageURL + name
}
// 检测文件目录是否存在
func createDirIfNotExist(path string) error {
// 检查目录是否存在
_, err := os.Stat(path)
if err == nil {
// 目录已存在,直接返回
return nil
}
// 目录不存在,创建目录
if os.IsNotExist(err) {
err = os.MkdirAll(path, 0755)
if err != nil {
return err
}
}
return nil
}
// 返回图片
func DownImage(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
//req := &values.DownLoadImageReq{}
//if !a.S(req) {
// return
//}
name := c.Query("path")
path := strings.Replace(name, ",", "/", -1)
// 打开要返回的图片文件
file, err := os.Open(path)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
defer file.Close()
// 读取图片文件的内容
data, err := io.ReadAll(file)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
arr := strings.Split(path, ".")
// 返回图片
c.Data(http.StatusOK, "image/"+arr[len(arr)-1], data)
}
// OptList 操作日志
func OptList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.EditHistoryListReq)
if !a.S(req) {
return
}
resp := values.EditHistoryListResp{}
if err := bdb.BackDB.C().Order("time Desc").Limit(int(req.Num)).Offset(int((req.Page - 1) * req.Num)).Find(&resp.List).Error; err != nil {
log.Error("err:%v", err)
}
resp.Count = bdb.BackDB.Count(&values.EditHistory{}, "")
a.Data = resp
}
func GoodList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
goods := call.GetGoodsConfig()
resp := &values.GoodListResp{List: goods}
a.Data = resp
}
func ProductList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
products := call.GetConfigPayProduct()
resp := &values.ProductListResp{List: products}
a.Data = resp
}
func ChannelList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
ret := call.GetChannelListReal()
if ret == nil {
a.Code = values.CodeRetry
return
}
resp := values.ChannelListResp{}
for _, v := range ret {
if v.Show != 2 {
continue
}
if len(a.User.SChannels) > 0 {
if !util.SliceContain(a.User.SChannels, v.ChannelID) {
continue
}
}
resp.List = append(resp.List, v)
}
a.Data = resp
}
func UserInfo(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
resp := values.UserInfoResp{Name: a.User.Name, Role: a.User.Role, Power: a.User.Power}
a.Data = resp
}

@ -0,0 +1,451 @@
package gm
import (
"fmt"
"server/call"
"server/common"
"server/db"
"server/modules/customer/app"
"server/modules/customer/values"
"server/natsClient"
"server/pb"
"server/util"
"strings"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
// 获取客服机器人消息
func GetCustomerRobot(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.GetCustomerRobotReq{}
if !a.S(req) {
return
}
resp := values.GetCustomerRobotResp{}
if _, err := db.Mysql().QueryAll(fmt.Sprintf("parent_id = %v", req.ParentId), "", &common.ConfigCustomerRobot{}, &resp.List); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
a.Data = resp
}
// 编辑客服机器人消息
func EditCustomerRobot(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.EditCustomerRobotReq{}
if !a.S(req) {
return
}
var resp values.EditCustomerRobotResp
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
// 新增
if req.List[i].ID == 0 {
log.Debug("req:%+v", req.List[i])
err := db.Mysql().Create(req.List[i])
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
log.Debug("req:%+v", req.List[i])
resp.List = append(resp.List, req.List[i])
} else {
// 修改
log.Debug("req:%+v", req.List[i])
u := &common.ConfigCustomerRobot{}
u.ID = req.List[i].ID
update := util.StructToMap(req.List[i], "json")
if err := db.Mysql().Update(u, update); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
}
}
}
err := call.Publish(natsClient.TopicReloadConfig, &pb.ReloadGameConfig{Type: common.ReloadConfigCustomerRobot})
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
// 写入日志
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
a.RecordEdit(values.PowerGM, fmt.Sprintf("编辑客服机器人配置:%v", *req.List[i]))
}
}
a.Data = resp
}
// 删除客服机器人消息
func DelCustomerRobot(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.DelCustomerRobotReq{}
if !a.S(req) {
return
}
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
log.Debug("req:%+v", *req.List[i])
err := db.Mysql().Del(&common.ConfigCustomerRobot{}, " id = ?", *req.List[i])
if err != nil {
log.Error(err.Error())
}
}
}
err := call.Publish(natsClient.TopicReloadConfig, &pb.ReloadGameConfig{Type: common.ReloadConfigCustomerRobot})
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
}
// 写入日志
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
a.RecordEdit(values.PowerGM, fmt.Sprintf("删除客服机器人配置:%v", *req.List[i]))
}
}
}
// 获取标签
func GetCustomerLabel(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
resp := values.GetCustomerLabelResp{}
if _, err := db.Mysql().QueryAll("", "", &common.CustomerOrderLabel{}, &resp.List); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
a.Data = resp
}
// 编辑标签
func EditCustomerLabel(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.EditCustomerLabelReq{}
if !a.S(req) {
return
}
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
// 新增
if req.List[i].ID == 0 {
log.Debug("req:%+v", req.List[i])
err := db.Mysql().Create(req.List[i])
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
} else {
// 修改
log.Debug("req:%+v", req.List[i])
u := &common.CustomerOrderLabel{}
u.ID = req.List[i].ID
update := util.StructToMap(req.List[i], "json")
if err := db.Mysql().Update(u, update); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
}
}
}
err := call.Publish(natsClient.TopicReloadConfig, &pb.ReloadGameConfig{Type: common.ReloadConfigCustomerLabel})
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
}
// 写入日志
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
a.RecordEdit(values.PowerGM, fmt.Sprintf("编辑工单标签配置:%v", *req.List[i]))
}
}
}
// 删除标签
func DelCustomerLabel(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.DelCustomerLabelReq{}
if !a.S(req) {
return
}
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
log.Debug("req:%+v", req.List[i])
err := db.Mysql().Del(&common.ConfigCustomerRobot{}, " id = ?", *req.List[i])
if err != nil {
log.Error(err.Error())
}
}
}
err := call.Publish(natsClient.TopicReloadConfig, &pb.ReloadGameConfig{Type: common.ReloadConfigCustomerLabel})
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
}
// 写入日志
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
a.RecordEdit(values.PowerGM, fmt.Sprintf("删除工单标签配置:%v", *req.List[i]))
}
}
}
// 客服系统配置
func GetConfigCustomer(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
resp := values.GetConfigCustomerResp{}
if _, err := db.Mysql().QueryAll("", "", &common.ConfigCustomer{}, &resp.List); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
a.Data = resp
}
// 客服系统配置
func EditConfigCustomer(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.EditConfigCustomerReq{}
if !a.S(req) {
return
}
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
// 新增
if req.List[i].ID == 0 {
log.Debug("req:%+v", req.List[i])
err := db.Mysql().Create(req.List[i])
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
} else {
// 修改
log.Debug("req:%+v", req.List[i])
u := &common.ConfigCustomer{}
u.ID = req.List[i].ID
update := util.StructToMap(req.List[i], "json")
if err := db.Mysql().Update(u, update); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
}
}
}
err := call.Publish(natsClient.TopicReloadConfig, &pb.ReloadGameConfig{Type: common.ReloadConfigCustomer})
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
}
// 写入日志
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
a.RecordEdit(values.PowerGM, fmt.Sprintf("编辑客服系统配置:%v", *req.List[i]))
}
}
}
// 客服系统配置
func DelConfigCustomer(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.DelConfigCustomerReq{}
if !a.S(req) {
return
}
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
log.Debug("req:%+v", req.List[i])
err := db.Mysql().Del(&common.ConfigCustomer{}, " id = ?", *req.List[i])
if err != nil {
log.Error(err.Error())
}
}
}
err := call.Publish(natsClient.TopicReloadConfig, &pb.ReloadGameConfig{Type: common.ReloadConfigCustomer})
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
}
// 写入日志
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
a.RecordEdit(values.PowerGM, fmt.Sprintf("删除客服系统配置:%v", *req.List[i]))
}
}
}
// 客服黑名单
func GetCustomerBlackUser(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.CustomerBlackUserReq{}
if !a.S(req) {
return
}
var resp values.CustomerBlackUserResp
count, err := db.Mysql().QueryList(req.Page-1, req.Num, "", "", &common.CustomerBlackUser{}, &resp.List)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
resp.Count = count
a.Data = resp
}
// 客服黑名单
func EditCustomerBlackUser(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := &values.EditCustomerBlackUserReq{}
if !a.S(req) {
return
}
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
log.Debug("opt:%v, req:%+v", req.Opt, *req.List[i])
if req.Opt == 1 {
err := db.Mysql().Create(&common.CustomerBlackUser{Uid: *req.List[i]})
if err != nil {
log.Error(err.Error())
}
} else {
data := &common.CustomerBlackUser{Uid: *req.List[i]}
err := db.Mysql().Get(data)
if err == nil {
db.Mysql().Del(data)
}
}
}
}
var str string
if req.Opt == 1 {
str = "添加"
} else {
str = "删除"
}
// 写入日志
for i := 0; i < len(req.List); i++ {
if req.List[i] != nil {
a.RecordEdit(values.PowerGM, fmt.Sprintf("%v客服系统黑名单 uid:%v", str, *req.List[i]))
}
}
}
// ConfigControlCommon 所有调控配置通用逻辑
func ConfigControlCommon(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
path := c.Request.URL.Path
path = strings.ReplaceAll(path, "/gm/control/", "")
all := strings.Split(path, "/")
if len(all) > 2 {
a.Code = values.CodeRetry
return
}
t := all[0]
opt := all[1]
element, list := GetElementByPath(t)
var resp interface{}
if opt == "list" {
req := &values.GMConfigCommonListReq{
Condition: map[string]interface{}{},
}
a.S(req)
if !a.MGetSqlAll(element, list, req.Condition) {
return
}
resp = values.GMConfigCommonListResp{Config: list}
} else if opt == "edit" {
req := new(values.GMConfigCommonEditReq)
if !a.S(req) {
return
}
if !a.MUpdateAll(req.Config, element) {
return
}
// call.Publish(natsClient.TopicReloadConfig, &pb.ReloadGameConfig{Type: int32(reloadType)})
} else if opt == "del" {
req := new(values.GMConfigCommonDelReq)
if !a.S(req) {
return
}
if !a.MDel(req.ID, element) {
return
}
// call.Publish(natsClient.TopicReloadConfig, &pb.ReloadGameConfig{Type: int32(reloadType)})
}
a.Data = resp
}

@ -0,0 +1,12 @@
package gm
import "server/common"
func GetElementByPath(path string) (interface{}, interface{}) {
switch path {
case "customerPhrases":
return &common.ConfigCustomerPhrases{}, &[]common.ConfigCustomerPhrases{}
default:
return nil, nil
}
}

@ -0,0 +1,122 @@
package guser
import (
"fmt"
"server/common"
"server/db"
utils "server/modules/backend/util"
"server/modules/backend/values"
"server/modules/customer/app"
"server/util"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"github.com/olivere/elastic/v7"
)
func ActiveUserList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.ActiveUserListReq)
if !a.S(req) {
return
}
var resp values.ActiveUserListResp
su, eu := utils.GetQueryUnix(req.Start, req.End)
queryCount := " SELECT COUNT(*) FROM login_record WHERE "
str := fmt.Sprintf(" time >= %d AND time < %d ", su, eu)
if req.Channel != nil {
str += fmt.Sprintf(" AND channel_id = %d ", *req.Channel)
}
if req.Status != nil {
str += fmt.Sprintf(" AND status = %v ", req.Status)
}
var count int64
err := db.Mysql().QueryBySql(queryCount+str, &count)
if err != nil {
log.Error(err.Error())
}
sql := fmt.Sprintf(
`SELECT d.id,d.nick,d.status,d.birth,d.cash,d.bind_cash,d.online,d.time,IFNULL(c.total_charge,0) as total_charge,IFNULL(c.total_withdraw,0) as total_withdraw from
(SELECT id,nick,status,birth,cash,bind_cash,online,b.time from users as a
INNER JOIN
(SELECT uid,max(time) as time from login_record WHERE time >= %d and time < %d GROUP BY uid) as b
on a.id = b.uid
LIMIT %d,%d
) as d
LEFT JOIN
(SELECT uid,total_charge,total_withdraw from recharge_info) as c
on d.id = c.uid`, su, eu, (req.Page-1)*req.Num, req.Num)
list := []values.ActiveUserOne{}
if err := db.Mysql().C().Raw(sql).Scan(&list).Error; err != nil {
log.Error("err:%v", err)
}
uids := []interface{}{}
for _, v := range list {
uids = append(uids, v.ID)
resp.List = append(resp.List, values.ActiveUserInfo{
UID: int64(v.ID),
Nick: v.Nick,
Status: v.Status,
Birth: v.Birth,
LastLogin: v.Time,
Recharge: v.TotalCharge,
Withdraw: v.TotalWithdraw,
Cash: v.Cash,
TotalCash: v.Cash + v.BindCash,
Online: v.Online,
})
}
q := elastic.NewBoolQuery()
q.Filter(elastic.NewRangeQuery("time").Gte(list[0].Birth))
q.Filter(elastic.NewRangeQuery("event").Gte(common.CurrencyEventGameSettle))
q.Filter(elastic.NewRangeQuery("event").Lt(common.CurrencyEventGameBet))
q.Filter(elastic.NewTermsQuery("uid", uids...))
totalGameCount, _ := db.ES().GroupBy(common.ESIndexBalance, "uid", q, len(list))
q.Filter(elastic.NewRangeQuery("value").Gt(0))
winGameCount, _ := db.ES().GroupBy(common.ESIndexBalance, "uid", q, len(list))
q = elastic.NewBoolQuery()
q.Filter(elastic.NewRangeQuery("time").Gte(su))
q.Filter(elastic.NewRangeQuery("time").Lt(eu))
q.Filter(elastic.NewRangeQuery("event").Gte(common.CurrencyEventGameSettle))
q.Filter(elastic.NewRangeQuery("event").Lt(common.CurrencyEventGameBet))
q.Filter(elastic.NewTermsQuery("uid", uids...))
todayGameCount, _ := db.ES().GroupBy(common.ESIndexBalance, "uid", q, len(list))
for i, v := range resp.List {
for _, u := range totalGameCount.Buckets {
if util.GetInt64(u.Key) == v.UID {
resp.List[i].GameCount = int64(u.Doc_count)
break
}
}
var winCount int64
for _, u := range winGameCount.Buckets {
if util.GetInt64(u.Key) == v.UID {
winCount = int64(u.Doc_count)
break
}
}
resp.List[i].WinPer = utils.GetPer(winCount, resp.List[i].GameCount)
for _, u := range todayGameCount.Buckets {
if util.GetInt64(u.Key) == v.UID {
resp.List[i].TodayCount = int64(u.Doc_count)
break
}
}
}
resp.Count = count
a.Data = resp
}

@ -0,0 +1,87 @@
package guser
import (
"encoding/json"
"fmt"
"server/call"
"server/common"
"server/db"
"server/modules/backend/values"
"server/modules/customer/app"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
// 将用户相关信息拉入黑名单
func AddUserBlackList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.AddUserBlackListReq)
if !a.S(req) {
return
}
user, err := call.GetUserInfo(req.UID)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
list := []common.RechargeOrder{}
db.Mysql().QueryList(0, 20, fmt.Sprintf("uid = %v and event = %v", user.Id, common.CurrencyEventWithDraw), "", common.RechargeOrder{}, &list)
banAccounts := map[string]struct{}{}
for _, v := range list {
info := common.WithdrawCommon{}
json.Unmarshal([]byte(v.PayAccount), &info)
acc := info.BankCardNo
//if info.DrawType == common.WithdrawTypeBank {
// if info.BankCardNo != "" {
// acc = info.BankCardNo
// }
//} else if info.DrawType == common.WithdrawTypeUPI {
// if info.BankCode != "" {
// acc = info.BankCode
// }
//}
if acc == "" {
continue
}
if _, ok := banAccounts[acc]; !ok {
banAccounts[acc] = struct{}{}
}
}
if len(banAccounts) == 0 {
black := &common.BlackList{
Phone: user.Mobile,
IP: user.IP,
}
if user.DeviceId != "00000000-0000-0000-0000-000000000000" {
black.DeviceID = user.DeviceId
}
err := db.Mysql().Create(black)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeParam
a.Msg = "该用户信息已在黑名单里"
}
} else {
for k := range banAccounts {
black := &common.BlackList{
Phone: user.Mobile,
IP: user.IP,
PayAccount: k,
}
if user.DeviceId != "00000000-0000-0000-0000-000000000000" {
black.DeviceID = user.DeviceId
}
err := db.Mysql().Create(black)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeParam
a.Msg = "该用户信息已在黑名单里"
}
}
}
}

@ -0,0 +1,31 @@
package guser
import (
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"server/common"
"server/db"
"server/modules/customer/app"
"server/modules/backend/values"
)
func AddUserTag(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.UserTagReq)
if !a.S(req) {
return
}
err := db.Mysql().C().Model(&common.PlayerDBInfo{}).Where("id = ?", req.Uid).Updates(map[string]interface{}{
"tag": req.Tag,
}).Error
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
}

@ -0,0 +1,58 @@
package guser
import (
"server/call"
"server/common"
"server/db"
"server/modules/backend/models"
utils "server/modules/backend/util"
"server/modules/backend/values"
"server/modules/customer/app"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"github.com/olivere/elastic/v7"
)
func BanUserList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.BanUserListReq)
if !a.S(req) {
return
}
var resp values.BanUserListResp
su, eu := utils.GetQueryUnix(req.Start, req.End)
q := elastic.NewBoolQuery()
q.Filter(elastic.NewRangeQuery("Time").Gt(su))
q.Filter(elastic.NewRangeQuery("Time").Lt(eu))
var list []*common.ESBlackList
count, err := db.ES().QueryList(common.ESIndexBackBlackList, req.Page-1, req.Num, q, &list, "Time", false)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
for i := 0; i < len(list); i++ {
user, err := call.GetUserInfo(list[i].UID)
if err != nil {
log.Error(err.Error())
continue
}
resp.List = append(resp.List, &values.BanUserInfo{
ESBlackList: *list[i],
Birth: user.Birth,
Recharge: models.GetRechargeTotalByUid(&user.Id),
Withdraw: models.GetWithdrawTotalByUid(&user.Id),
Channel: user.ChannelID,
})
}
resp.Count = count
a.Data = resp
}

@ -0,0 +1,81 @@
package guser
import (
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"server/common"
"server/modules/backend/models"
utils "server/modules/backend/util"
"server/modules/backend/values"
"server/modules/customer/app"
)
func ControlCardData(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.ControlCardDataReq)
if !a.S(req) {
return
}
var resp values.ControlCardDataResp
event := int(common.CurrencyEventGameSettle)
s, e := utils.GetQueryUnix(req.Start, req.End)
var balance []common.CurrencyBalance
count, err := models.QueryPlayerAllBalance(req.Uid, req.Page-1, req.Num, &s, &e, req.GameId, req.RoomId, req.ControlType, req.Channel, &event, &balance)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
//MillionGameIdMap := make(map[string]bool)
//for i := 0; i < len(common.MillionGameIDs); i++ {
// MillionGameIdMap[strconv.Itoa(common.MillionGameIDs[i].(int))] = true
//}
//
//for i := 0; i < len(balance); i++ {
// var playerBalance values.PlayerBalance
// playerBalance.CurrencyBalance = balance[i]
//
// if _, ok := MillionGameIdMap[balance[i].Desc]; ok {
// playerBalance.MillionBetArea, playerBalance.Result = getMillionBetArea(balance[i].Extern, balance[i].Uid)
// }
//
// resp.List = append(resp.List, playerBalance)
//}
resp.Total = count
a.Data = resp
}
func getAndarBaharArea(res int) string {
if 1 <= res && res <= 5 {
return "2"
}
if 6 <= res && res <= 10 {
return "3"
}
if 11 <= res && res <= 15 {
return "4"
}
if 16 <= res && res <= 25 {
return "5"
}
if 26 <= res && res <= 30 {
return "6"
}
if 31 <= res && res <= 35 {
return "7"
}
if 36 <= res && res <= 40 {
return "8"
}
if 41 <= res && res <= 100 {
return "9"
}
return "-1"
}

@ -0,0 +1,53 @@
package guser
import (
"fmt"
"server/call"
"server/common"
"server/modules/backend/values"
"server/modules/customer/app"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
// 修改玩家金币
func EditGameUserGold(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.EditGameUserGoldReq)
if !a.S(req) {
return
}
//var ct common.CurrencyType
//switch req.Type {
//case 1:
// ct = common.CurrencyTypeBindCash
//case 2:
// ct = common.CurrencyTypeCash
//default:
// a.Code = values.CodeParam
// a.Msg = "非法请求类型"
// return
//}
user, _ := call.GetUserXInfo(req.UID, "channel_id")
_ = user
_, err := call.UpdateCurrencyPro(&common.UpdateCurrency{
CurrencyBalance: &common.CurrencyBalance{
UID: req.UID,
Event: common.CurrencyEventGM,
Type: common.CurrencyINR,
Value: req.Amount,
ChannelID: user.ChannelID,
//NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, conf.Reward),
},
})
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
a.RecordEdit(values.PowerGUser, fmt.Sprintf("修改玩家%v金币:%v", req.UID, req.Amount))
}

@ -0,0 +1,56 @@
package guser
import (
"fmt"
"server/call"
"server/common"
"server/db"
"server/modules/customer/app"
"server/modules/backend/values"
"server/natsClient"
"server/pb"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
func EditGameUserStatus(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.EditGameUserStatusReq)
if !a.S(req) {
return
}
if req.Status <= common.AccountStatus || req.Status >= common.AccountStatusAll {
a.Code = values.CodeParam
a.Msg = "请求状态不合法"
return
}
user, err := call.GetUserInfo(req.UID)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
if user.Status == req.Status {
a.Code = values.CodeParam
a.Msg = "无内容修改"
return
}
if err = call.UpdateUserXInfo(&common.PlayerDBInfo{Id: req.UID}, map[string]interface{}{"status": req.Status}); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
if req.Status == common.AccountStatusLimit { // 封禁账号要通知全服,踢出玩家
db.Redis().Delkey(common.GetRedisKeyToken(db.Redis().GetUserToken(req.UID)))
db.Redis().Delkey(common.GetRedisKeyUser(req.UID))
err = call.Publish(natsClient.TopicInnerOptPlayer, &pb.InnerOptPlayer{UID: uint32(req.UID), Opt: common.OptPlayerTypeKick})
if err != nil {
log.Error(err.Error())
}
}
a.RecordEdit(values.PowerGUser, fmt.Sprintf("修改玩家%v状态:%v", req.UID, req.Status))
}

@ -0,0 +1,34 @@
package guser
import (
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"server/common"
"server/db"
"server/modules/customer/app"
"server/modules/backend/values"
)
func GetGameUserAllBalance(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.GetGameUserAllBalanceReq)
if !a.S(req) {
return
}
resp := values.GetGameUserAllBalanceResp{
List: []common.CurrencyBalance{},
}
var count int64
var err error
count, err = db.ES().QueryPlayerAllBalance(&req.UID, req.Page-1, req.Num, req.Start, req.End, &resp.List)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
resp.Count = count
a.Data = resp
}

@ -0,0 +1,47 @@
package guser
import (
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"server/common"
"server/db"
"server/modules/customer/app"
"server/modules/backend/models"
utils "server/modules/backend/util"
"server/modules/backend/values"
)
func GetGameUserControlBalance(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.GetGameUserControlBalanceReq)
if !a.S(req) {
return
}
resp := values.GetGameUserControlBalanceResp{
List: []common.CurrencyBalance{},
}
s, e := utils.GetQueryUnix(req.Start, req.End)
count, err := db.ES().QueryPlayerControlBalance(req.UID, req.Page-1, req.Num, &s, &e, &resp.List, req.ControlType)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
resp.Count = count
event := int(common.CurrencyEventGameSettle)
// 查询控杀次数
resp.ControlCount = models.GetControlCount(&s, &e, &req.UID, &event, false)
loseCount := models.GetControlCount(&s, &e, &req.UID, &event, true)
resp.ControlPer = utils.GetPer(loseCount, resp.ControlCount)
// 幸运次数
resp.LuckCount = models.GetLuckCount(&s, &e, &req.UID, nil, &event, false, false)
winCount := models.GetLuckCount(&s, &e, &req.UID, nil, &event, true, false)
resp.LuckPer = utils.GetPer(winCount, resp.LuckCount)
a.Data = resp
}

@ -0,0 +1,183 @@
package guser
import (
"fmt"
"github.com/olivere/elastic/v7"
"server/call"
"server/common"
"server/db"
"server/modules/backend/values"
"server/modules/customer/app"
"strconv"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
uutil "server/util"
)
func GetGameUserInfo(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.GetGameUserInfoReq)
if !a.S(req) {
return
}
user := &common.PlayerDBInfo{}
switch req.Data.(type) {
case int, int64, float32, float64:
id := uutil.GetInt(req.Data)
if id <= 999999999 {
user.Id = id
} else {
user.Mobile = strconv.Itoa(id)
}
case string:
str := req.Data.(string)
if len(str) == 10 {
user.Mobile = str
} else {
id, err := strconv.Atoi(str)
if err != nil {
a.Code = values.CodeParam
a.Msg = "玩家不存在"
return
}
user.Id = id
}
}
err := db.Mysql().Get(user)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeParam
a.Msg = "玩家不存在"
return
}
uid := user.Id
ur, _ := call.GetUserXInfo(uid, "online")
info := &common.RechargeInfo{UID: uid}
err = db.Mysql().Get(info)
if err != nil {
log.Error(err.Error())
}
// control := &common.PlayerControl{UID: uid}
// err = db.Mysql().Get(control)
// if err != nil {
// log.Error(err.Error())
// }
// lg := &common.LoginRecord{UID: uid}
// err = db.Mysql().GetLast(lg)
// if err != nil {
// log.Error(err.Error())
// }
//pointControl := &common.ConfigPointControl{UID: uid}
//db.Mysql().Get(pointControl)
// per := 0
// tar := ""
// if control.NewControlFin == 1 {
// if control.NewControlLevel == 0 {
// control.NewControlLevel = 1
// }
// con := call.GetNewControlConfigByID(control.NewControlLevel)
// if con != nil {
// control.TargetValue = con.ControlNum
// per = con.ControlPer
// tar = fmt.Sprintf("%v", control.TargetValue)
// }
// } else {
// if control.ControlSection > 0 {
// re := &common.RechargeInfo{UID: uid}
// db.Mysql().Get(re)
// con := call.GetSignleControlConfigByRecharge(re.TotalCharge)
// if con != nil {
// rcon := reflect.ValueOf(con).Elem()
// per = int(rcon.FieldByName(fmt.Sprintf("ControlPer%v", control.ControlSection)).Int())
// }
// }
// tar = uutil.FormatFloat(float64(control.TargetValue)/100, 2)
// }
//black := &common.ConfigMillionBlack{UID: uid}
//db.Mysql().Get(black)
resp := values.GetGameUserInfoResp{
UID: user.Id,
Nick: user.Nick,
//Recharge: info.TotalCharge,
//Withdraw: info.TotoalWithdraw,
Channel: user.ChannelID,
Phone: user.Mobile,
OpenID: *user.Openid,
//Cash: user.Cash,
//Total: user.BindCash + user.Cash,
Online: ur.Online == common.PlayerOnline,
Status: user.Status,
Birth: user.Birth,
// PlayCount: util.GetGUserPlayCount(uid),
IP: user.IP,
LastLogin: user.LastLogin,
Tag: user.Tag,
// IsFinishNewControl: control.NewControlFin == 2,
// NewControlLevel: control.NewControlLevel,
// ControlLevel: control.ControlLevel,
// ControlSection: control.ControlSection,
// ControlValue: uutil.FormatFloat(float64(control.ControlValue)/100, 2),
// ControlPer: per,
// TargetValue: tar,
// FreeAmount: uutil.FormatFloat(float64(control.FreeAmount)/100, 2),
//PointControlValue: uutil.FormatFloat(float64(pointControl.CurControlNum)/100, 2),
//PointControlTargetValue: uutil.FormatFloat(float64(pointControl.ControlNum), 2),
//PointControlPer: pointControl.ControlPer,
UserGameData: GetUserGameInfo(user.Id),
//Gpsadid: user.DeviceId,
//Black: black,
}
var tmpUser []common.PlayerDBInfo
_, err = db.Mysql().QueryAll(fmt.Sprintf("deviceid = '%s'", user.DeviceId), "", &common.PlayerDBInfo{}, &tmpUser)
if err != nil {
log.Error(err.Error())
}
for _, v := range tmpUser {
resp.SubAccount = append(resp.SubAccount, v.Id)
}
a.Data = resp
}
// 获取用户游戏信息
func GetUserGameInfo(uid int) map[string][]values.UserGameInfo {
q := elastic.NewBoolQuery()
q.Filter(elastic.NewTermQuery("uid", uid))
q.Filter(elastic.NewTermsQuery("event", common.GetGameEvents()...))
buk, err := db.ES().Group2SumBy(common.ESIndexBalance, "exi1", "exi2", "value", q, "", false, 0)
if err != nil {
log.Error("err:%v", err)
}
ret := map[string][]values.UserGameInfo{}
var totalCount, totalProfit int64
for _, v := range buk.Buckets {
provider := call.GetConfigGameProvider(uutil.GetInt(v.Key))
if provider == nil {
continue
}
games := []values.UserGameInfo{}
for _, k := range v.Sub1.Buckets {
thisGame := call.GetConfigGameListByID(provider.ProviderID, uutil.GetInt(k.Key))
if thisGame == nil {
continue
}
count := uutil.GetInt64(k.Doc_count)
profit := uutil.GetInt64(k.Sub2.Value)
totalCount += count
totalProfit += profit
games = append(games, values.UserGameInfo{
GameName: thisGame.Name + fmt.Sprintf("(%d)", thisGame.GameID),
GameCount: count,
Profit: profit,
})
}
ret[provider.ProviderName] = games
}
ret["总计"] = []values.UserGameInfo{{GameCount: totalCount, Profit: totalProfit}}
return ret
}

@ -0,0 +1,206 @@
package guser
import (
"fmt"
"server/common"
"server/db"
"server/modules/backend/models"
utils "server/modules/backend/util"
"server/modules/backend/values"
"server/modules/customer/app"
"server/util"
"time"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"github.com/olivere/elastic/v7"
)
func GetGameUserList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.GetGameUserListReq)
if !a.S(req) {
return
}
su, eu := utils.GetQueryUnix(req.Start, req.End)
var sqlList, sqlTotal, sqlCount string
// list
sqlList = fmt.Sprintf("SELECT a.id AS UID,"+ // 用户uid
"a.nick AS Nick,"+ // 用户昵称
"a.status AS Status,"+ // 用户状态
"a.mobile AS Phone,"+ // 用户手机号
"a.birth AS Birth,"+ // 用户生日
"(a.cash+a.bind_cash) AS TotalCash,"+ // 用户总金额
"a.cash AS Cash,"+ // 用户可提现现金
"IFNULL(b.total_charge,0) AS Recharge,"+ // 用户充值金额
"IFNULL(b.total_withdraw,0) AS Withdraw,"+ // 用户提现金额
"a.online AS Online "+ // 用户是否在线
"FROM users AS a LEFT JOIN recharge_info AS b ON a.id = b.uid WHERE a.role <> 100 AND a.birth >= %d AND a.birth < %d", su, eu)
// total
sqlTotal = fmt.Sprintf("SELECT SUM(a.cash+a.bind_cash) AS CashTotal,"+ // 总金额
"SUM(a.cash) AS WithdrawableTotal,"+ // 总可提现现金
"SUM(b.total_charge) AS RechargeTotal,"+ // 总充值
"SUM(b.total_withdraw) AS WithdrawHistoryTotal, "+ // 历史提现
"COUNT((IF(a.cash>=10000,TRUE,NULL))) AS WithdrawPlayerCount "+ // 提现玩家数量
"FROM users AS a LEFT JOIN recharge_info AS b ON a.id = b.uid WHERE a.role <> 100 AND a.birth >= %d AND a.birth < %d", su, eu)
// count
sqlCount = fmt.Sprintf("SELECT count(*) FROM users WHERE role<>100 AND birth >= %d AND birth < %d", su, eu)
order := "a.birth"
sort := ""
if req.Order != 0 {
if req.Order < 0 {
sort = " desc"
req.Order = -req.Order
}
switch req.Order {
case 1: // 1是按玩家充值金额排序
order = "b.total_charge"
case 2: // 2是按金币数量排序
order = "a.cash+a.bind_cash"
case 3: // 3是按可提现总额排序
order = "a.cash"
case 4: // 4是按历史提现金额排序
order = "b.total_withdraw"
case 5: // 5是按注册时间排序
order = "a.birth"
default:
a.Code = values.CodeParam
a.Msg = "排序参数不合法"
return
}
}
if req.Channel != 0 {
sqlList += fmt.Sprintf(" and a.channel_id = %d ", req.Channel)
sqlTotal += fmt.Sprintf(" and a.channel_id = %d ", req.Channel)
sqlCount += fmt.Sprintf(" and channel_id = %d ", req.Channel)
}
if req.Status != 0 {
sqlList += fmt.Sprintf(" and a.status = %v", req.Status)
sqlCount += fmt.Sprintf(" and status = %v", req.Status)
sqlTotal += fmt.Sprintf(" and status = %v", req.Status)
}
if req.Online != 0 {
sqlList += fmt.Sprintf(" and a.online = %v", req.Online)
sqlCount += fmt.Sprintf(" and online = %v", req.Online)
sqlTotal += fmt.Sprintf(" and online = %v", req.Online)
}
//if req.CoinLimit != nil {
// CoinLimit := *req.CoinLimit
// if len(CoinLimit) < 2 {
// sqlList += fmt.Sprintf(" and %d <= (a.cash + a.bind_cash) and (a.cash + a.bind_cash) <= %d", 0, 3000)
// sqlCount += fmt.Sprintf(" and %d <= (cash + bind_cash) and (cash + bind_cash) <= %d", 0, 3000)
// sqlTotal += fmt.Sprintf(" and %d <= (cash + bind_cash) and (cash + bind_cash) <= %d", 0, 3000)
// } else {
// if CoinLimit[1] == 0 {
// sqlList += fmt.Sprintf(" and %d <= (a.cash + a.bind_cash) ", CoinLimit[0])
// sqlCount += fmt.Sprintf(" and %d <= (cash + bind_cash) ", CoinLimit[0])
// sqlTotal += fmt.Sprintf(" and %d <= (cash + bind_cash) ", CoinLimit[0])
// } else {
// sqlList += fmt.Sprintf(" and %d <= (a.cash + a.bind_cash) and (a.cash + a.bind_cash) <= %d", CoinLimit[0], CoinLimit[1])
// sqlCount += fmt.Sprintf(" and %d <= (cash + bind_cash) and (cash + bind_cash) <= %d", CoinLimit[0], CoinLimit[1])
// sqlTotal += fmt.Sprintf(" and %d <= (cash + bind_cash) and (cash + bind_cash) <= %d", CoinLimit[0], CoinLimit[1])
// }
// }
//}
sqlList += fmt.Sprintf(" ORDER BY %v %v LIMIT %v OFFSET %v", order, sort, req.Num, (req.Page-1)*req.Num)
resp := values.GetGameUserListResp{}
if err := db.Mysql().C().Raw(sqlList).Scan(&resp.List).Error; err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
// isWin := true
uids := []interface{}{}
for i, v := range resp.List {
lg := &common.LoginRecord{UID: v.UID}
err := db.Mysql().GetLast(lg)
if err != nil {
log.Error(err.Error())
}
resp.List[i].LastLogin = lg.Time
uids = append(uids, v.UID)
// winCount := models.GetWinGameCountByBalance(nil, nil, &resp.List[i].UID, req.Channel, nil, nil, &isWin)
// resp.List[i].GameCount = models.GetGameCountByBalance(nil, nil, &resp.List[i].UID, req.Channel, nil, nil)
// resp.List[i].WinPer = utils.GetPer(winCount, resp.List[i].GameCount)
// controlInfo := &common.PlayerControl{UID: v.UID}
// err = db.Mysql().GetLast(controlInfo)
// if err != nil {
// log.Error(err.Error())
// }
// resp.List[i].ControlInfo = *controlInfo
data := common.CurrencyBalance{}
q := elastic.NewBoolQuery()
q.Filter(elastic.NewRangeQuery("uid").Gte(resp.List[i].UID))
q.Filter(elastic.NewRangeQuery("uid").Lt(resp.List[i].UID + 1))
q.Filter(elastic.NewRangeQuery("event").Gte(common.CurrencyEventGameSettle))
q.Filter(elastic.NewRangeQuery("event").Lt(common.CurrencyEventGameBet))
err = db.ES().QueryOne(common.ESIndexBalance, q, &data, "id", false)
if err != nil {
log.Error("err:%v", err)
//resp.List[i].PlayerStatus = nil
} else {
if data.Time >= (time.Now().Unix() - 60) {
//resp.List[i].PlayerStatus = map[string]string{
// "gameId": data.Desc,
// "roomId": data.RoomName,
//}
}
}
//user, _ := call.GetUserInfo(v.UID)
//resp.List[i].AccountCount = int(db.Mysql().Count(&common.PlayerDBInfo{}, fmt.Sprintf("deviceid = '%v'", user.DeviceId)))
}
total := models.GetGameCountByUIDs(uids, false)
win := models.GetGameCountByUIDs(uids, true)
for i, v := range resp.List {
_ = i
for _, u := range total.Buckets {
if util.GetInt(u.Key) == v.UID {
//resp.List[i].GameCount = int64(u.Doc_count)
break
}
}
//var winCount int64
for _, u := range win.Buckets {
if util.GetInt(u.Key) == v.UID {
//winCount = int64(u.Doc_count)
break
}
}
//resp.List[i].WinPer = utils.GetPer(winCount, resp.List[i].GameCount)
}
if err := db.Mysql().C().Raw(sqlCount).Scan(&resp.Count).Error; err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
//if err := db.Mysql().C().Raw(sqlTotal).Scan(&resp.Total).Error; err != nil {
// log.Error("err:%v", err)
// a.Code = values.CodeRetry
// return
//}
//
//resp.Total.WithdrawPlayerPer = utils.GetPer(resp.Total.WithdrawPlayerCount, resp.Count)
//
//resp.Total.UnRechargePlayerCash, resp.Total.UnRechargePlayerAmount = models.GetUnRechargePlayerAmount(req.Channel, su, eu)
a.Data = resp
}

@ -0,0 +1,52 @@
package guser
import (
"server/common"
"server/db"
"server/modules/backend/values"
"server/modules/customer/app"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
func GetGameUserPlayData(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.GetGameUserPlayDataReq)
if !a.S(req) {
return
}
var ret []common.CurrencyBalance
var count int64
var err error
if req.Games != nil {
count, err = db.ES().QueryPlayerBalance(req.UID, req.Page-1, req.Num, int(common.CurrencyEventGameSettle), req.Start, req.End, &ret, *req.Games)
} else {
count, err = db.ES().QueryPlayerBalance(req.UID, req.Page-1, req.Num, int(common.CurrencyEventGameSettle), req.Start, req.End, &ret)
}
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
resp := values.GetGameUserPlayDataResp{
List: []values.OneGameUserPlayData{},
Count: count,
}
for _, v := range ret {
resp.List = append(resp.List, values.OneGameUserPlayData{
Time: v.Time,
Value: v.Value,
Balance: v.Balance,
UUID: v.Exs1,
ProviderID: v.Exi1,
GameID: v.Exi2,
GameName: v.Exs4,
})
}
a.Data = resp
}

@ -0,0 +1,67 @@
package guser
import (
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"github.com/olivere/elastic/v7"
"server/common"
"server/db"
"server/modules/backend/values"
"server/modules/customer/app"
)
func GetGameUserPlayDetail(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.GetGameUserPlayDetailReq)
if !a.S(req) {
return
}
data := common.CurrencyBalance{}
q := elastic.NewBoolQuery()
q.Filter(elastic.NewTermQuery("extern.keyword", req.UUID))
q.Filter(elastic.NewTermQuery("event", common.CurrencyEventGameSettle))
err := db.ES().QueryOne(common.ESIndexBalance, q, &data)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
//gameId, err := strconv.Atoi(data.Desc)
//if err != nil {
// log.Error("err:%v", err)
// a.Code = values.CodeRetry
// return
//}
resp := values.GetGameUserPlayDetailResp{}
//resp.GameId = gameId
a.Data = resp
//if data.Desc == fmt.Sprintf("%d", common.GameIDDragon) || data.Desc == fmt.Sprintf("%d", common.GameIDSeven) {
// res, err := getDVTGameUserPlayDetail(req.UUID, req.UID)
// if err != nil {
// log.Error("查询百人模式游戏数据统计失败, error : [%s]", err.Error())
// a.Code = values.CodeRetry
// return
// }
// resp.Result = res
// a.Data = resp
//} else {
//
// if 2001 <= gameId && gameId < 3000 {
// Result, History := getESTeenpattiOperateLog(req.UUID)
// resp.Result = Result
// resp.History = History
// }
//
// if 3001 <= gameId && gameId < 4000 {
// Result, History := getESRummyOperateLog(req.UUID)
// resp.Result = Result
// resp.History = History
// }
//
// a.Data = resp
//}
}

@ -0,0 +1,63 @@
package guser
import (
"fmt"
"server/common"
"server/db"
utils "server/modules/backend/util"
"server/modules/backend/values"
"server/modules/customer/app"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
func GetGameUserRechargeHistory(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.GetGameUserRechargeHistoryReq)
if !a.S(req) {
return
}
log.Debug("req:")
resp := values.GetGameUserRechargeHistoryResp{}
var ret []common.RechargeOrder
if req.UID > 0 {
count, err := db.Mysql().QueryPlayerRWHistory(&req.UID, nil, req.Page-1, req.Num, []int{int(common.CurrencyEventReCharge), common.CurrencyEventGMRecharge}, req.Start, req.End, &common.RechargeOrder{}, &ret, req.Status)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
resp.Count = count
for _, v := range ret {
resp.List = append(resp.List, values.OneRechargeList{UID: v.UID, Time: v.CreatedAt.Unix(), CallbackTime: v.CallbackTime,
Amount: v.Amount, Status: int(v.Status), MyOrderID: v.OrderID, OrderID: v.APIPayID, PayChannel: v.PayChannel, PaySource: v.PaySource})
}
resp.RechargeCount = db.Mysql().Count(&common.RechargeOrder{}, fmt.Sprintf("uid = %v and (event = %v or event = %v)", req.UID, common.CurrencyEventReCharge, common.CurrencyEventGMRecharge))
re := &common.RechargeInfo{UID: req.UID}
err = db.Mysql().Get(re)
if err != nil {
log.Error(err.Error())
}
resp.RechargeTotal = re.TotalRecharge
successCount := db.Mysql().Count(&common.RechargeOrder{}, fmt.Sprintf("uid = %v and (event = %v or event = %v) and status = %v", req.UID, common.CurrencyEventReCharge, common.CurrencyEventGMRecharge, common.StatusROrderPay))
resp.RechargeSuccessPer = utils.GetPer(successCount, resp.RechargeCount)
} else if req.OrderID != "" {
resp.Count, _ = db.Mysql().QueryList(req.Page-1, req.Num, fmt.Sprintf(`event = %v and (apipayid = "%v" or orderid = "%v")`, common.CurrencyEventReCharge, req.OrderID, req.OrderID), "created_at desc", &common.RechargeOrder{}, &ret)
// log.Debug("ret:%v", ret)
for _, v := range ret {
resp.List = append(resp.List, values.OneRechargeList{UID: v.UID, Time: v.CreatedAt.Unix(), CallbackTime: v.CallbackTime,
MyOrderID: v.OrderID, OrderID: v.APIPayID, Amount: v.Amount, Status: int(v.Status), PayChannel: v.PayChannel, PaySource: v.PaySource})
}
} else {
a.Code = values.CodeParam
a.Msg = "查询条件有误"
return
}
a.Data = resp
}

@ -0,0 +1,67 @@
package guser
import (
"fmt"
"server/common"
"server/db"
"server/modules/backend/models"
utils "server/modules/backend/util"
"server/modules/backend/values"
"server/modules/customer/app"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
func GetGameUserWithdrawHistory(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.GetGameUserWithdrawHistoryReq)
if !a.S(req) {
return
}
resp := values.GetGameUserWithdrawHistoryResp{}
var ret []common.WithdrawOrder
if req.UID > 0 {
count, err := db.Mysql().QueryPlayerRWHistory(&req.UID, nil, req.Page-1, req.Num, []int{int(common.CurrencyEventWithDraw)}, req.Start, req.End, &common.WithdrawOrder{}, &ret)
if err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
resp.Count = count
for _, v := range ret {
resp.List = append(resp.List, values.OneWithdrawList{UID: v.UID, Time: v.CreateTime, PayAccount: v.PayAccount,
Amount: v.Amount, Status: int(v.Status), OrderID: v.APIPayID, MyOrderID: v.OrderID, FailReason: v.FailReason, OrderCreateAt: v.CreateTime,
AuditTime: 0, CallbackTime: v.CallbackTime, Channel: v.PayChannel})
}
resp.WithdrawCount = db.Mysql().Count(&common.WithdrawOrder{}, fmt.Sprintf("uid = %v and event = %v", req.UID, common.CurrencyEventWithDraw))
re := &common.RechargeInfo{UID: req.UID}
err = db.Mysql().Get(re)
if err != nil {
log.Error(err.Error())
}
resp.WithdrawTotal = re.TotalWithdraw
successCount := db.Mysql().Count(&common.WithdrawOrder{}, fmt.Sprintf("uid = %v and event = %v and status = %v", req.UID, common.CurrencyEventWithDraw, common.StatusROrderFinish))
resp.WithdrawSuccessPer = utils.GetPer(successCount, resp.WithdrawCount)
resp.WithdrawCash = db.Mysql().Sum(&common.WithdrawOrder{}, fmt.Sprintf("uid = %v and event = %v and status = %v", req.UID, common.CurrencyEventWithDraw, common.StatusROrderFinish), "withdraw_cash")
resp.WithdrawTax = resp.WithdrawCash - resp.WithdrawTotal*100
resp.RechargeTotal = models.GetRechargeTotalByUid(&req.UID)
resp.WithDrawPer = utils.GetPer(resp.WithdrawTotal, resp.RechargeTotal)
} else if req.Data != "" {
resp.Count, _ = db.Mysql().QueryList(req.Page-1, req.Num, fmt.Sprintf(`event = %v and (apipayid = "%v" or orderid = '%v')`, common.CurrencyEventWithDraw, req.Data, req.Data), "created_at desc", &common.WithdrawOrder{}, &ret)
for _, v := range ret {
resp.List = append(resp.List, values.OneWithdrawList{UID: v.UID, Time: v.CreateTime, PayAccount: v.PayAccount,
Amount: v.Amount, Status: int(v.Status), OrderID: v.APIPayID, MyOrderID: v.OrderID, FailReason: v.FailReason, OrderCreateAt: v.CreateTime,
AuditTime: 0, CallbackTime: v.CallbackTime, Channel: v.PayChannel})
}
} else {
a.Code = values.CodeParam
a.Msg = "查询条件有误"
return
}
a.Data = resp
}

@ -0,0 +1,113 @@
package guser
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"server/call"
"server/common"
"server/db"
"server/modules/backend/models"
utils "server/modules/backend/util"
"server/modules/backend/values"
"server/modules/customer/app"
"strconv"
"time"
)
func LostPlayerData(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.LostPlayerDataReq)
if !a.S(req) {
return
}
resp := values.LostPlayerDataResp{}
su, eu := utils.GetQueryUnix(req.Start, req.End)
var oneDay int64 = 24 * 60 * 60
now := time.Now().Unix()
queryUser := " SELECT u.id, u.nick, u.bind_cash, u.cash, u.birth FROM users u LEFT JOIN (SELECT a.* FROM login_record a INNER JOIN ( SELECT uid, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON a.uid = b.uid AND a.created_at = b.created_at WHERE a.uid = b.uid AND a.created_at = b.created_at AND UNIX_TIMESTAMP(a.date) >= %d) r ON u.id = r.uid WHERE "
queryCount := " SELECT COUNT(DISTINCT(u.id)) FROM users u LEFT JOIN (SELECT a.* FROM login_record a INNER JOIN ( SELECT uid, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON a.uid = b.uid AND a.created_at = b.created_at WHERE a.uid = b.uid AND a.created_at = b.created_at AND UNIX_TIMESTAMP(a.date) >= %d) r ON u.id = r.uid WHERE "
str := fmt.Sprintf(" u.birth >= %d AND u.birth < %d ", su, eu)
if req.Channel != nil {
str += fmt.Sprintf(" AND u.channel_id = %d AND r.channel_id = %d", *req.Channel, *req.Channel)
}
// 三天未登录的用户 UNIX_TIMESTAMP('20210816')
str += fmt.Sprintf(" AND (%d - UNIX_TIMESTAMP(r.date) > %d ) ", now, 3*oneDay)
var count int64
err := db.Mysql().QueryBySql(fmt.Sprintf(queryCount+str, eu, eu), &count)
if err != nil {
log.Error(err.Error())
}
str += " GROUP BY u.id "
str += fmt.Sprintf(" LIMIT %d, %d ", (req.Page-1)*req.Num, req.Num)
var users []common.PlayerDBInfo
err = db.Mysql().QueryBySql(fmt.Sprintf(queryUser+str, eu, eu), &users)
if err != nil {
log.Error(err.Error())
}
for i := 0; i < len(users); i++ {
var lostPlayerData values.LostPlayerData
lostPlayerData.Date = su
lostPlayerData.Nick = users[i].Nick
lostPlayerData.Uid = users[i].Id
lostPlayerData.Birth = users[i].Birth
lostPlayerData.Amount = call.GetUserCurrencyTotal(users[i].Id, 0)
var record common.LoginRecord
err = db.Mysql().C().Model(&common.LoginRecord{}).Where(" uid = ?", users[i].Id).Last(&record).Error
if err != nil {
log.Error(err.Error())
}
lostPlayerData.LastLogin = record.Time
// 玩家提现金额
lostPlayerData.WithDrawAmount = models.GetWithdrawTotalByUid(&users[i].Id)
// 玩家游戏局数
//gameCount := make(map[string]int64)
// 房间游戏数据
//for j := 0; j < len(common.RoomGameIDs); j++ {
// gameCount[strconv.Itoa(common.RoomGameIDs[j])] = models.GetUserGameCount(nil, nil, &users[i].Id, &common.RoomGameIDs[j], nil, req.Channel)
// lostPlayerData.GameCount += gameCount[strconv.Itoa(common.RoomGameIDs[j])]
//}
//
//// 百人游戏数据
//for j := 0; j < len(common.MillionGameIDs); j++ {
// millionGameID := common.MillionGameIDs[j].(int)
// gameCount[strconv.Itoa(millionGameID)] = models.GetUserGameCount(nil, nil, &users[i].Id, &millionGameID, nil, req.Channel)
// lostPlayerData.GameCount += gameCount[strconv.Itoa(millionGameID)]
//}
//lostPlayerData.MostGameCount = gameCount
// 最后三局游戏记录
event := int(common.CurrencyEventGameSettle)
var balance []common.CurrencyBalance
uid := strconv.Itoa(users[i].Id)
_, err = models.QueryUserBalance(&uid, 0, 3, nil, nil, nil, nil, nil, req.Channel, &event, &balance)
if err != nil {
log.Error(err.Error())
return
}
for j := 0; j < len(balance); j++ {
lostPlayerData.GameRecord = append(lostPlayerData.GameRecord, balance[j].Value)
}
resp.List = append(resp.List, lostPlayerData)
}
resp.Count = count
a.Data = resp
}

@ -0,0 +1,242 @@
package guser
import (
"fmt"
"server/call"
"server/common"
"server/db"
"server/modules/backend/models"
utils "server/modules/backend/util"
"server/modules/backend/values"
"server/modules/customer/app"
"time"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
// 流失玩家数据
func LostUserData(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.LostUserDataReq)
if !a.S(req) {
return
}
resp := values.LostUserDataResp{}
su, eu := utils.GetQueryUnix(req.Start, req.End)
switch req.Sort {
case 1:
resp.Count, resp.List = getAllLostUser(su, eu, req.Page, req.Num, req.Channel)
case 2:
resp.Count, resp.List = getPayLostUser(su, eu, req.Page, req.Num, req.Channel)
case 3:
resp.Count, resp.List = getActiveLostUser(su, eu, req.Page, req.Num, req.Channel)
case 4:
resp.Count, resp.List = getNewLostUser(su, eu, req.Page, req.Num, req.Channel)
default:
resp.Count, resp.List = getAllLostUser(su, eu, req.Page, req.Num, req.Channel)
}
a.Data = resp
}
// 获取所有流失用户
func getAllLostUser(su, eu int64, page, num int, channel *int) (int64, []values.LostUserData) {
var oneDay = 24 * 60 * 60
now := time.Now().Unix()
queryUser := " SELECT u.id, u.nick, u.bind_cash, u.cash, u.birth FROM users u LEFT JOIN (SELECT a.* FROM login_record a INNER JOIN ( SELECT uid, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON a.uid = b.uid AND a.created_at = b.created_at WHERE a.uid = b.uid AND a.created_at = b.created_at AND UNIX_TIMESTAMP(a.date) >= %d) r ON u.id = r.uid WHERE "
queryCount := " SELECT COUNT(DISTINCT(u.id)) FROM users u LEFT JOIN (SELECT a.* FROM login_record a INNER JOIN ( SELECT uid, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON a.uid = b.uid AND a.created_at = b.created_at WHERE a.uid = b.uid AND a.created_at = b.created_at AND UNIX_TIMESTAMP(a.date) >= %d) r ON u.id = r.uid WHERE "
str := fmt.Sprintf(" u.birth >= %d AND u.birth < %d ", su, eu)
if channel != nil {
str += fmt.Sprintf(" AND u.channel_id = %d AND r.channel_id = %d", *channel, *channel)
}
// 七天未登录的用户 UNIX_TIMESTAMP('20210816')
str += fmt.Sprintf(" AND (%d - UNIX_TIMESTAMP(r.date) > %d ) ", now, 7*oneDay)
var count int64
err := db.Mysql().QueryBySql(fmt.Sprintf(queryCount+str, su, su), &count)
if err != nil {
log.Error(err.Error())
return 0, nil
}
str += " GROUP BY u.id "
str += fmt.Sprintf(" LIMIT %d, %d ", (page-1)*num, num)
var users []common.PlayerDBInfo
err = db.Mysql().QueryBySql(fmt.Sprintf(queryUser+str, su, su), &users)
if err != nil {
log.Error(err.Error())
return 0, nil
}
return count, getLostUserInfo(users)
}
// 获取付费流失用户
func getPayLostUser(su, eu int64, page, num int, channel *int) (int64, []values.LostUserData) {
var oneDay = 24 * 60 * 60
now := time.Now().Unix()
queryUser := " SELECT u.id, u.nick, u.bind_cash, u.cash, u.birth FROM users u LEFT JOIN (SELECT a.* FROM login_record a INNER JOIN ( SELECT uid, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON a.uid = b.uid AND a.created_at = b.created_at WHERE a.uid = b.uid AND a.created_at = b.created_at AND UNIX_TIMESTAMP(a.date) >= %d) r ON u.id = r.uid LEFT JOIN (SELECT * FROM recharge_order WHERE `event` = %d AND `status` = %d AND callback_time > %d) re ON u.id = re.uid WHERE u.id = re.uid AND "
queryCount := " SELECT COUNT(DISTINCT(u.id)) FROM users u LEFT JOIN (SELECT a.* FROM login_record a INNER JOIN ( SELECT uid, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON a.uid = b.uid AND a.created_at = b.created_at WHERE a.uid = b.uid AND a.created_at = b.created_at AND UNIX_TIMESTAMP(a.date) >= %d) r ON u.id = r.uid LEFT JOIN (SELECT * FROM recharge_order WHERE `event` = %d AND `status` = %d AND callback_time > %d) re ON u.id = re.uid WHERE u.id = re.uid AND "
str := fmt.Sprintf(" u.birth >= %d AND u.birth < %d ", su, eu)
if channel != nil {
str += fmt.Sprintf(" AND u.channel_id = %d AND r.channel_id = %d", *channel, *channel)
}
// 三天未登录的用户 UNIX_TIMESTAMP('20210816')
str += fmt.Sprintf(" AND (%d - UNIX_TIMESTAMP(r.date) > %d ) ", now, 7*oneDay)
var count int64
err := db.Mysql().QueryBySql(fmt.Sprintf(queryCount+str, su, su, common.CurrencyEventReCharge, common.StatusROrderPay, su), &count)
if err != nil {
log.Error(err.Error())
return 0, nil
}
str += " GROUP BY u.id "
str += fmt.Sprintf(" LIMIT %d, %d ", (page-1)*num, num)
var users []common.PlayerDBInfo
err = db.Mysql().QueryBySql(fmt.Sprintf(queryUser+str, su, su, common.CurrencyEventReCharge, common.StatusROrderPay, su), &users)
if err != nil {
log.Error(err.Error())
return 0, nil
}
return count, getLostUserInfo(users)
}
// 获取活跃流失用户
func getActiveLostUser(su, eu int64, page, num int, channel *int) (int64, []values.LostUserData) {
var oneDay = 24 * 60 * 60
now := time.Now().Unix()
queryUser := fmt.Sprintf(" SELECT u.id, u.nick, u.bind_cash, u.cash, u.birth FROM users u LEFT JOIN ( SELECT uid, MAX(date) date, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON u.id = b.uid WHERE u.id = b.uid AND ", su) +
" FROM_UNIXTIME(u.birth,'%Y%m%d') != b.date AND "
queryCount := fmt.Sprintf(" SELECT COUNT(DISTINCT(u.id)) FROM users u LEFT JOIN ( SELECT uid, MAX(date) date, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON u.id = b.uid WHERE u.id = b.uid AND ", su) +
" FROM_UNIXTIME(u.birth,'%Y%m%d') != b.date AND "
str := fmt.Sprintf(" u.birth >= %d AND u.birth < %d ", su, eu)
if channel != nil {
str += fmt.Sprintf(" AND u.channel_id = %d AND b.channel_id = %d", *channel, *channel)
}
// 七天未登录的用户 UNIX_TIMESTAMP('20210816')
str += fmt.Sprintf(" AND (%d - UNIX_TIMESTAMP(b.date) > %d ) ", now, 7*oneDay)
var count int64
err := db.Mysql().QueryBySql(queryCount+str, &count)
if err != nil {
log.Error(err.Error())
return 0, nil
}
str += " GROUP BY u.id "
str += fmt.Sprintf(" LIMIT %d, %d ", (page-1)*num, num)
var users []common.PlayerDBInfo
err = db.Mysql().QueryBySql(queryUser+str, &users)
if err != nil {
log.Error(err.Error())
return 0, nil
}
return count, getLostUserInfo(users)
}
// 获取新用户流失
func getNewLostUser(su, eu int64, page, num int, channel *int) (int64, []values.LostUserData) {
queryUser := fmt.Sprintf(" SELECT u.id, u.nick, u.bind_cash, u.cash, u.birth FROM users u LEFT JOIN ( SELECT uid, MAX( created_at ) created_at, MAX(date) date FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON u.id = b.uid WHERE u.id = b.uid ", su) +
"AND FROM_UNIXTIME(u.birth,'%Y%m%d') = b.date AND"
queryCount := fmt.Sprintf(" SELECT COUNT(DISTINCT(u.id)) FROM users u LEFT JOIN ( SELECT uid, MAX( created_at )created_at, MAX(date) date FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON u.id = b.uid WHERE u.id = b.uid ", su) +
"AND FROM_UNIXTIME(u.birth,'%Y%m%d') = b.date AND"
str := fmt.Sprintf(" u.birth >= %d AND u.birth < %d ", su, eu)
if channel != nil {
str += fmt.Sprintf(" AND u.channel_id = %d ", *channel)
str += fmt.Sprintf(" AND u.channel_id = %d ", *channel)
}
// 7天未登录的用户 UNIX_TIMESTAMP('20210816')
str += fmt.Sprintf(" AND (%d - UNIX_TIMESTAMP(b.date) > %d ) ", time.Now().Unix(), 7*24*60*60)
var count int64
err := db.Mysql().QueryBySql(queryCount+str, &count)
if err != nil {
log.Error(err.Error())
return 0, nil
}
str += fmt.Sprintf(" LIMIT %d, %d ", (page-1)*num, num)
var users []common.PlayerDBInfo
err = db.Mysql().QueryBySql(queryUser+str, &users)
if err != nil {
log.Error(err.Error())
return 0, nil
}
return count, getLostUserInfo(users)
}
func getLostUserInfo(users []common.PlayerDBInfo) []values.LostUserData {
var res []values.LostUserData
for i := 0; i < len(users); i++ {
var data values.LostUserData
// 用户昵称
data.Nick = users[i].Nick
// 用户uid
data.Uid = users[i].Id
// 用户生日
data.Birth = users[i].Birth
var record common.LoginRecord
err := db.Mysql().C().Model(&common.LoginRecord{}).Where(" uid = ?", users[i].Id).Last(&record).Error
if err != nil {
log.Error(err.Error())
}
// 最后登录时间
data.LastLogin = record.Time
// 玩家游戏局数
data.GameCount = models.GetGameCountByBalance(nil, nil, &users[i].Id, nil, nil, nil)
// 玩家剩余账户金额
data.Amount = call.GetUserCurrencyTotal(users[i].Id, 0)
// 玩家总提现金额
data.WithDrawAmount = getPlayerAmountBySql(users[i].Id, int(common.CurrencyEventWithDraw), common.StatusROrderFinish)
// 玩家总充值金额
data.RechargeAmount = getPlayerAmountBySql(users[i].Id, int(common.CurrencyEventReCharge), common.StatusROrderPay)
res = append(res, data)
}
return res
}
// 获取玩家充值金额
func getPlayerAmountBySql(uid, event, status int) int64 {
var amount int64
amountTotal := "SELECT IFNULL(SUM(amount),0) as Amount FROM recharge_order WHERE uid = %d AND event = %v AND status = %v "
err := db.Mysql().QueryBySql(fmt.Sprintf(amountTotal, uid, event, status), &amount)
if err != nil {
log.Error(err.Error())
}
return amount
}

@ -0,0 +1,39 @@
package guser
//func LostUserDetail(c *gin.Context) {
// a := app.NewApp(c)
// defer func() {
// a.Response()
// }()
// req := new(values.LostUserDetailReq)
// if !a.S(req) {
// return
// }
// resp := values.LostUserDetailResp{}
//
// for i := 0; i < len(common.RoomGameIDs); i++ {
// resp.List = append(resp.List, getLostUserDetail(req.Uid, common.RoomGameIDs[i]))
// }
//
// for i := 0; i < len(common.MillionGameIDs); i++ {
// resp.List = append(resp.List, getLostUserDetail(req.Uid, common.MillionGameIDs[i].(int)))
// }
//
// a.Data = resp
//}
//
//func getLostUserDetail(uid int, gameId int) values.LostUserDetail {
// var lostUserDetail values.LostUserDetail
//
// lostUserDetail.GameId = gameId
//
// isWin := true
// winCount := models.GetWinGameCountByBalance(nil, nil, &uid, nil, &gameId, nil, &isWin)
// lostUserDetail.GameCount = models.GetGameCountByBalance(nil, nil, &uid, nil, &gameId, nil)
//
// lostUserDetail.WinPer = utils.GetPer(winCount, lostUserDetail.GameCount)
//
// lostUserDetail.BreakPer = utils.GetPer(models.GetPlayerBreakCount(nil, nil, &uid, &gameId, nil, nil), lostUserDetail.GameCount)
//
// return lostUserDetail
//}

@ -0,0 +1,96 @@
package guser
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
"server/call"
"server/common"
"server/db"
utils "server/modules/backend/util"
"server/modules/backend/values"
"server/modules/customer/app"
)
// 充值排行榜
func RechargeRank(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.RechargeRankReq)
if !a.S(req) {
return
}
su, eu := utils.GetQueryUnix(req.Start, req.End)
resp := values.RechargeRankResp{}
var num int64 = 100
if req.Num != nil {
num = *req.Num
}
var str string
if req.Status == 1 {
str = fmt.Sprintf("SELECT uid, SUM(amount) AS amount, COUNT(amount) as event FROM recharge_order WHERE event = %d AND status = %d AND callback_time >= %d AND callback_time < %d GROUP BY uid ORDER BY amount DESC LIMIT 0, %d",
common.CurrencyEventReCharge,
common.StatusROrderPay,
su,
eu,
num)
} else {
str = fmt.Sprintf("SELECT uid, SUM(amount) AS amount, COUNT(amount) as event FROM recharge_order WHERE event = %d AND status = %d AND callback_time >= %d AND callback_time < %d GROUP BY uid ORDER BY amount DESC LIMIT 0, %d",
common.CurrencyEventWithDraw,
common.StatusROrderFinish,
su,
eu,
num)
}
var users []common.RechargeOrder
err := db.Mysql().QueryBySql(str, &users)
if err != nil {
log.Error(err.Error())
a.Code = values.CodeRetry
return
}
for i := 0; i < len(users); i++ {
var temp values.RechargeRank
temp.Date = su
temp.Uid = users[i].UID
if req.Status == 1 {
temp.TodayRechargeAmount = users[i].Amount
temp.TodayRechargeOrderCount = int64(users[i].Event)
sql := fmt.Sprintf("event = %v and status = %v and callback_time >= '%v' and callback_time < '%v' and uid = %v", common.CurrencyEventWithDraw, common.StatusROrderFinish, su, eu, users[i].UID)
temp.TodayWithDrawAmount = db.Mysql().Sum(&common.RechargeOrder{}, sql, "amount")
temp.TodayWithDrawOrderCount = db.Mysql().Count(&common.RechargeOrder{}, sql)
} else {
temp.TodayWithDrawAmount = users[i].Amount
temp.TodayWithDrawOrderCount = int64(users[i].Event)
sql := fmt.Sprintf("event = %v and status = %v and callback_time >= '%v' and callback_time < '%v' and uid = %v", common.CurrencyEventReCharge, common.StatusROrderPay, su, eu, users[i].UID)
temp.TodayRechargeAmount = db.Mysql().Sum(&common.RechargeOrder{}, sql, "amount")
temp.TodayRechargeOrderCount = db.Mysql().Count(&common.RechargeOrder{}, sql)
}
// 玩家总提现金额
temp.WithDrawAmount = getPlayerAmountBySql(users[i].UID, int(common.CurrencyEventWithDraw), common.StatusROrderFinish)
// 玩家总充值金额
temp.RechargeAmount = getPlayerAmountBySql(users[i].UID, int(common.CurrencyEventReCharge), common.StatusROrderPay)
// 玩家生日
res, _ := call.GetUserInfo(users[i].UID)
temp.Birth = res.Birth
// 用户渠道
temp.Channel = users[i].ChannelID
resp.List = append(resp.List, &temp)
}
resp.Count = int64(len(users))
a.Data = resp
}

@ -0,0 +1,208 @@
package handler
import (
"fmt"
"server/modules/customer/app"
"server/modules/customer/bdb"
"server/modules/customer/values"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
func UserList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
resp := values.UserListResp{}
if err := bdb.BackDB.C().Find(&resp.List).Error; err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
a.Data = resp
}
func AddUser(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.AddUserReq)
if !a.S(req) {
return
}
log.Debug("adduser:%+v", req)
if req.Role == values.UserRoleAdmin {
a.Code = values.CodeParam
a.Msg = "不可添加超级管理员"
return
}
var roles []*values.Role
bdb.BackDB.C().Find(&roles)
var r *values.Role
for _, v := range roles {
if req.Role == v.Role {
r = v
}
}
if r == nil {
log.Error("invalid role:%v", req.Role)
a.Code = values.CodeParam
a.Msg = "请求角色不存在"
return
}
one := &values.User{Name: req.Name, Account: req.Account, Password: req.Password, Role: req.Role, Power: r.Power, Phone: req.Phone, Channels: req.Channels}
if err := bdb.BackDB.Create(one); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeParam
a.Msg = err.Error()
return
}
a.RecordEdit(values.PowerManageUser, fmt.Sprintf("新增用户:%v", req.Name))
}
func EditUserPower(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.EditPowerReq)
if !a.S(req) {
return
}
log.Debug("edit power:%+v", req)
user := new(values.User)
user.ID = uint(req.ID)
if err := bdb.BackDB.Get(user); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeParam
a.Msg = "账户不存在"
return
}
if user.Role == values.UserRoleAdmin {
a.Code = values.CodeParam
a.Msg = "不可修改超级管理员"
return
}
update := map[string]interface{}{}
if req.Power != nil {
if !a.CheckPower(*req.Power) {
return
}
update["power"] = *req.Power
}
if req.Name != nil {
update["name"] = *req.Name
}
if req.Account != nil {
update["account"] = *req.Account
}
if req.Password != nil {
update["password"] = *req.Password
}
if req.Role != nil {
if *req.Role == values.UserRoleAdmin {
a.Code = values.CodeParam
a.Msg = "不可修改为超级管理员"
return
}
update["role"] = *req.Role
}
if req.Phone != nil {
update["phone"] = *req.Phone
}
if req.Channels != nil {
update["channels"] = *req.Channels
}
if len(update) == 0 {
a.Code = values.CodeParam
a.Msg = "无内容修改"
return
}
if err := bdb.BackDB.Update(&values.User{ID: uint(req.ID)}, update); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
a.RecordEdit(values.PowerManageUser, fmt.Sprintf("修改用户权限:%v", req.ID))
}
func DelUser(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.DelUserReq)
if !a.S(req) {
return
}
user := new(values.User)
user.ID = uint(req.ID)
if err := bdb.BackDB.C().Delete(user).Where("id = ?", req.ID).Error; err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
}
func RoleList(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
resp := values.RoleListResp{}
if err := bdb.BackDB.C().Find(&resp.List).Error; err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
a.Data = resp
}
func AddRole(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.AddRoleReq)
if !a.S(req) {
return
}
if !a.CheckPower(req.Power) {
return
}
one := &values.Role{Role: req.Role, Name: req.Name, Power: req.Power}
if err := bdb.BackDB.Create(one); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
a.RecordEdit(values.PowerManageRole, fmt.Sprintf("新增角色:%v", req.Name))
}
func EditRole(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
req := new(values.EditRoleReq)
if !a.S(req) {
return
}
if !a.CheckPower(req.Power) {
return
}
one := &values.Role{Role: req.Role, Name: req.Name, Power: req.Power}
if err := bdb.BackDB.Update(&values.Role{ID: uint(req.ID)}, one); err != nil {
log.Error("err:%v", err)
a.Code = values.CodeRetry
return
}
err := bdb.BackDB.Update(&values.User{Role: req.Role}, map[string]interface{}{"power": req.Power})
if err != nil {
log.Error(err.Error())
}
a.RecordEdit(values.PowerManageRole, fmt.Sprintf("修改角色:%v", req.ID))
}

@ -0,0 +1,48 @@
package middleware
import (
"net/http"
"server/modules/customer/app"
"github.com/gin-gonic/gin"
)
//跨域访问:cross origin resource share
func CrosHandler() gin.HandlerFunc {
return func(context *gin.Context) {
method := context.Request.Method
origin := context.Request.Header.Get("Origin") //请求头部
if origin != "" {
//接收客户端发送的origin (重要!)
context.Writer.Header().Set("Access-Control-Allow-Origin", "*")
// 设置允许访问所有域
context.Header("Access-Control-Allow-Origin", "*")
//服务器支持的所有跨域请求的方法
context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
//允许跨域设置可以返回其他子段,可以自定义字段
context.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma,token,openid,opentoken,istoken")
// 允许浏览器(客户端)可以解析的头部 (重要)
context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar")
//设置缓存时间
context.Header("Access-Control-Max-Age", "172800")
//允许客户端传递校验信息比如 cookie (重要)
context.Header("Access-Control-Allow-Credentials", "true")
// 设置返回格式是json
context.Set("content-type", "application/json")
}
if method == "OPTIONS" {
context.JSON(http.StatusOK, app.R{Code: http.StatusOK, Data: "Options Request!"})
}
//处理请求
context.Next()
}
}

@ -0,0 +1,68 @@
package middleware
import (
"server/modules/customer/app"
"server/modules/customer/bdb"
"server/modules/customer/values"
"strings"
"github.com/gin-gonic/gin"
)
// 进行权限校验
func PowerMiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
path := c.Request.RequestURI
if PassURL(path) {
c.Next()
return
}
a := app.NewApp(c)
if !powerPass(a.User, path) {
a.Code = values.CodePower
a.Response()
c.Abort()
return
}
c.Next()
}
}
func powerPass(u *values.User, path string) bool {
if u == nil {
return false
}
if u.Role == values.UserRoleAdmin {
return true
}
// 第一步找到主页签
p := 0
for s, v := range values.PowerMap {
if strings.Contains(path, s) {
p = v
break
}
}
// 不在权限控制范围
if p == 0 {
return true
}
buttons, ok := bdb.GetPowerByRole(u.Role)[p]
if !ok {
return false
}
pbutton, ok2 := values.PowerButtonMap[p]
// 该页签没有子按钮
if !ok2 {
return true
}
for i, v := range pbutton {
if v == path {
if i > len(pbutton)-1 {
return true
}
return buttons[i] == 1
}
}
return true
}

@ -0,0 +1,90 @@
package middleware
import (
"server/common"
"server/db"
"server/modules/customer/app"
"server/modules/customer/values"
"strings"
"github.com/liangdas/mqant/log"
"github.com/gin-gonic/gin"
)
var (
passURLs = map[string]struct{}{
"/account/login": {},
"/image/download": {},
"/gm/customer/config/info": {},
}
)
// 进行token校验
func TokenMiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
// 检查是否排除当前url
// exclude := regexp.MustCompile("/static/*")
path := c.Request.RequestURI
if PassURL(path) {
c.Next()
return
}
// 对用户的token进行校验 并对token续期
token := c.GetHeader("token")
one := new(values.User)
if err := db.Redis().GetJsonData(common.GetBackendTokenKey(token), one); err != nil || one.Account == "" {
app := app.NewApp(c)
app.Code = values.CodeToken
app.Msg = "登录已过期,请重新登录"
app.Response()
c.Abort()
return
}
// if len(one.Power) > 0 {
// err := json.Unmarshal([]byte(one.Power), &one.PowerMap)
// if err != nil {
// log.Error("err:%v", err)
// app := app.NewApp(c)
// app.Code = values.CodePower
// app.Response()
// c.Abort()
// return
// }
// }
c.Set("user", one)
c.Next()
// 刷新token过期时间
defer func() {
err := db.Redis().Expire(common.GetBackendTokenKey(token), values.RedisTokenEx)
if err != nil {
log.Error(err.Error())
}
}()
}
}
// PassURL 过滤url
func PassURL(path string) bool {
index := strings.Index(path, "?")
if index > 0 {
path = path[:index]
}
_, ok := passURLs[path]
if !ok {
// index := strings.LastIndex(path, "/")
// url := path[:index+1] + "*"
// _, ok = passURLs[url]
for k := range passURLs {
if strings.Contains(path, k) {
return true
}
}
}
return ok
}

@ -0,0 +1,114 @@
package customer
import (
"context"
"net/http"
"server/call"
"server/config"
"server/db"
edb "server/db/es"
mdb "server/db/mysql"
rdb "server/db/redis"
"server/modules/customer/bdb"
"server/modules/customer/routers"
"time"
"github.com/liangdas/mqant/conf"
"github.com/liangdas/mqant/log"
"github.com/liangdas/mqant/module"
basemodule "github.com/liangdas/mqant/module/base"
)
var (
Module = func() module.Module {
this := new(Customer)
return this
}
BackDB = new(mdb.MysqlClient)
)
type Customer struct {
basemodule.BaseModule
httpSvr *http.Server
addr string
}
func (b *Customer) GetType() string {
//很关键,需要与配置文件中的Module配置对应
return "customer"
}
func (b *Customer) Version() string {
//可以在监控时了解代码版本
return "1.0.0"
}
func (b *Customer) OnInit(app module.App, settings *conf.ModuleSettings) {
b.BaseModule.OnInit(b, app, settings)
call.NewCaller(b)
db.InitDB(&mdb.MysqlClient{}, &rdb.RedisClient{}, &edb.EsClient{})
bdb.InitMysql()
// 自动初始化后台数据库
bdb.MigrateDB()
// 加载配置
call.Go(func() {
loadConfig()
})
b.addr = config.GetConfig().Customer.Addr
call.NewSnowflake(int64(config.GetConfig().WorkID))
call.InitReload(b.App.Transport())
StartTimer()
}
func (b *Customer) startHttpServer() {
router := routers.SetUpRouter()
srv := &http.Server{
Addr: b.addr,
Handler: router,
}
go func() {
if err := srv.ListenAndServe(); err != nil {
panic(err)
}
}()
// returning reference so caller can call Shutdown()
b.httpSvr = srv
}
func (b *Customer) Run(closeSig chan bool) {
log.Info("customer: starting HTTP server :%s", b.addr)
call.InitTimeWheel(closeSig)
call.InitWarn(b.App.Transport())
b.startHttpServer()
<-closeSig
log.Info("customer: stopping HTTP server")
}
func (b *Customer) OnDestroy() {
// The context is used to inform the server it has 5 seconds to finish
// the request it is currently handling
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// now close the server gracefully ("shutdown")
// timeout could be given instead of nil as a https://golang.org/pkg/context/
if err := b.httpSvr.Shutdown(ctx); err != nil {
log.Error("OnDestroy Customer Shutdown error:%v", err)
}
log.Info("Customer: done. exiting")
//一定别忘了继承
b.BaseModule.OnDestroy()
log.Info("Customer 模块已销毁")
}

@ -0,0 +1,41 @@
package routers
import (
"runtime"
"server/config"
"server/modules/customer/middleware"
"github.com/gin-gonic/gin"
"github.com/liangdas/mqant/log"
)
func SetUpRouter() *gin.Engine {
release := config.GetConfig().Release
if release {
gin.SetMode(gin.ReleaseMode)
// 禁用控制台颜色
gin.DisableConsoleColor()
} else {
gin.SetMode(gin.DebugMode)
}
r := gin.New()
// 跨域处理
r.Use(middleware.CrosHandler())
r.Use(middleware.TokenMiddleWare())
r.Use(middleware.PowerMiddleWare())
r.Use(gin.RecoveryWithWriter(log.LogBeego(), func(c *gin.Context, err interface{}) {
buf := make([]byte, 1024)
runtime.Stack(buf, false)
log.Error("panic(%+v), stack:\n%s", err, string(buf))
}))
gmHandle(r)
account(r)
power(r)
common(r)
chat(r)
mail(r)
guser(r)
return r
}

@ -0,0 +1,14 @@
// 账号相关的接口
package routers
import (
handler "server/modules/customer/handler/account"
"github.com/gin-gonic/gin"
)
func account(e *gin.Engine) {
e.POST("/account/login", handler.Login)
e.POST("/account/online", handler.Online)
e.POST("/account/onlineStatus", handler.OnlineStatus)
}

@ -0,0 +1,42 @@
package routers
import (
"github.com/gin-gonic/gin"
handler2 "server/modules/backend/handler/guser"
handler "server/modules/customer/handler/chat"
)
func chat(e *gin.Engine) {
// 工单分配
e.POST("/order/allocate", handler.CustomerOrderAllocate)
// 聊天历史
e.POST("/customer/history", handler.GetCustomerHistory)
// 消息已读
e.POST("/customer/read/message", handler.ReadMessage)
// 发送消息
e.POST("/customer/send/message", handler.SendMessage)
// 工单列表
e.POST("/customer/order/list", handler.GetCustomerOrder)
// 改变工单状态
e.POST("/customer/order/change", handler.ChangeCustomerOrderStatus)
// 编辑工单标签
e.POST("/customer/label/edit", handler.EditCustomerOrderLabel)
// 玩家信息
e.POST("/customer/player/info", handler.GetPlayerInfo)
// 玩家充值历史
e.POST("/customer/rechargeHistory", handler2.GetGameUserRechargeHistory)
// 玩家提现历史
e.POST("/customer/withdrawHistory", handler2.GetGameUserWithdrawHistory)
// 玩家客诉历史
e.POST("/customer/complaint/history", handler.ComplaintHistory)
}

@ -0,0 +1,23 @@
// 账号相关的接口
package routers
import (
"github.com/gin-gonic/gin"
handler "server/modules/customer/handler/common"
)
func common(e *gin.Engine) {
// 上传图片
e.POST("/image/upload", handler.UploadImage)
// 获取图片
e.GET("/image/download", handler.DownImage)
// 操作日志查看
e.POST("/option/log/list", handler.OptList)
e.GET("/common/goodsList", handler.GoodList)
e.GET("/common/productList", handler.ProductList)
e.GET("/common/channelList", handler.ChannelList)
e.GET("/common/userInfo", handler.UserInfo)
}

@ -0,0 +1,31 @@
package routers
import (
handler "server/modules/customer/handler/gm"
"github.com/gin-gonic/gin"
)
func gmHandle(e *gin.Engine) {
// 客服机器人配置
e.POST("/gm/customer/robot/info", handler.GetCustomerRobot)
e.POST("/gm/customer/robot/edit", handler.EditCustomerRobot)
e.POST("/gm/customer/robot/del", handler.DelCustomerRobot)
// 客服订单标签
e.GET("/gm/order/label/info", handler.GetCustomerLabel)
e.POST("/gm/order/label/edit", handler.EditCustomerLabel)
e.POST("/gm/order/label/del", handler.DelCustomerLabel)
// 客服系统配置
e.GET("/gm/customer/config/info", handler.GetConfigCustomer)
e.POST("/gm/customer/config/edit", handler.EditConfigCustomer)
e.POST("/gm/customer/config/del", handler.DelConfigCustomer)
// 客服系统黑名单
e.POST("/gm/customer/black/list", handler.GetCustomerBlackUser)
e.POST("/gm/customer/black/edit", handler.EditCustomerBlackUser)
e.GET("/gm/control/*action", handler.ConfigControlCommon)
e.POST("/gm/control/*action", handler.ConfigControlCommon)
}

@ -0,0 +1,26 @@
package routers
import (
handler "server/modules/customer/handler/guser"
"github.com/gin-gonic/gin"
)
func guser(e *gin.Engine) {
e.POST("/guser/list", handler.GetGameUserList)
e.POST("/guser/activeUserList", handler.ActiveUserList)
e.POST("/guser/info", handler.GetGameUserInfo)
e.POST("/guser/allBalance", handler.GetGameUserAllBalance)
e.POST("/guser/playData", handler.GetGameUserPlayData)
e.POST("/guser/playDetail", handler.GetGameUserPlayDetail)
e.POST("/guser/rechargeHistory", handler.GetGameUserRechargeHistory)
e.POST("/guser/withdrawHistory", handler.GetGameUserWithdrawHistory)
e.POST("/guser/controlBalance", handler.GetGameUserControlBalance)
e.POST("/guser/controlCardData", handler.ControlCardData)
e.POST("/guser/editGold", handler.EditGameUserGold)
e.POST("/guser/editStatus", handler.EditGameUserStatus)
e.POST("/guser/addUserTag", handler.AddUserTag)
e.POST("/guser/deleteUserTag", handler.AddUserTag)
e.POST("/guser/addUserBlackList", handler.AddUserBlackList)
}

@ -0,0 +1,12 @@
package routers
import (
"github.com/gin-gonic/gin"
)
func mail(e *gin.Engine) {
//e.POST("/mail/draftList", handler.DraftList)
//e.POST("/mail/draftCreate", handler.DraftCreate)
//e.POST("/mail/draftEdit", handler.DraftEdit)
//e.POST("/mail/draftOpt", handler.DraftOpt)
}

@ -0,0 +1,16 @@
package routers
import (
"github.com/gin-gonic/gin"
handler "server/modules/customer/handler/power"
)
func power(e *gin.Engine) {
e.GET("/power/user/list", handler.UserList)
e.POST("/power/user/add", handler.AddUser)
e.POST("/power/user/edit", handler.EditUserPower)
e.POST("/power/user/del", handler.DelUser)
e.GET("/power/role/list", handler.RoleList)
e.POST("/power/role/add", handler.AddRole)
e.POST("/power/role/edit", handler.EditRole)
}

@ -0,0 +1,113 @@
package customer
import (
"fmt"
"math/rand"
"server/common"
"server/config"
"server/db"
"server/modules/customer/bdb"
"server/modules/customer/values"
"server/util"
"time"
"github.com/liangdas/mqant/log"
)
func StartTimer() {
count := config.GetConfig().Customer.MaxOrderCount
if count > 0 {
MaxOrderCount = count
}
CustomerOrderAssignTimer()
}
const (
// MaxOrderCount = 10 // 暂定客诉最大同时分配支付订单数
)
var (
MaxOrderCount int64 = 10
)
func CustomerOrderAssignTimer() {
time.AfterFunc(2*time.Second, func() {
defer func() {
CustomerOrderAssignTimer()
}()
users := []*values.User{}
bdb.BackDB.QueryAll(fmt.Sprintf("role = %d and online = 1", values.UserRole2), "", &values.User{}, &users)
if len(users) == 0 {
return
}
orderCount := map[int]int64{}
uids := []int{}
for _, v := range users {
list := []common.CustomerOrder{}
count, _ := db.Mysql().QueryList(0, 100, fmt.Sprintf(`customer_uid = %d and status = %d and order_id <> ""`, v.ID, common.CustomerOrderCreate),
"", &common.CustomerOrder{}, &list)
orderCount[int(v.ID)] = count
uids = append(uids, int(v.ID))
}
rechargeList := []common.CustomerOrder{}
db.Mysql().QueryList(0, 100, fmt.Sprintf(`status = %d and order_id <> ""`, common.CustomerOrderCreate), "", &common.CustomerOrder{}, &rechargeList)
normalList := []common.CustomerOrder{}
db.Mysql().QueryList(0, 100, fmt.Sprintf(`status = %d`, common.CustomerOrderCreate), "", &common.CustomerOrder{}, &normalList)
if len(rechargeList) == 0 && len(normalList) == 0 {
return
}
begin := time.Now()
// log.Debug("start CustomerOrderAssignTimer......")
count := 0
now := time.Now().Unix()
// 先分配充值订单
for _, v := range rechargeList {
if util.SliceContain(uids, v.CustomerUid) {
continue
}
indexs := rand.Perm(len(users))
var u *values.User
for _, l := range indexs {
diff := MaxOrderCount - orderCount[int(users[l].ID)]
if diff <= 0 {
continue
}
u = users[l]
break
}
if u == nil {
break
}
orderCount[int(u.ID)]++
db.Mysql().Update(&common.CustomerOrder{ID: v.ID}, map[string]interface{}{"customer_uid": u.ID, "assign_time": now})
count++
}
for _, v := range normalList {
if util.SliceContain(uids, v.CustomerUid) {
continue
}
indexs := rand.Perm(len(users))
var u *values.User
for _, l := range indexs {
diff := MaxOrderCount - orderCount[int(users[l].ID)]
if diff <= 0 {
continue
}
u = users[l]
break
}
if u == nil {
break
}
orderCount[int(u.ID)]++
db.Mysql().Update(&common.CustomerOrder{ID: v.ID}, map[string]interface{}{"customer_uid": u.ID, "assign_time": now})
count++
}
if count > 0 {
log.Debug("finish CustomerOrderAssignTimer since:%v,rechargeList:%d,normalList:%d,count:%d", time.Since(begin), len(rechargeList), len(normalList), count)
}
})
}

@ -0,0 +1,34 @@
package values
import (
"time"
)
// 用户身份
const (
UserRoleAdmin = iota + 1 // 管理员
UserRole1 // 主管
UserRole2 // 普通客服
)
const (
RedisTokenEx = 60 * time.Minute
)
// LoginReq 登录请求
type LoginReq struct {
Account string `json:"Account" binding:"required"`
Pass string `json:"Pass" binding:"required"`
}
// LoginResp 登录返回
// Power:权限
// Role:账户等级,1管理员
// Token:身份码,登录成功后的所有请求需在header里加入token字段以进行后续请求
// 账户id
type LoginResp struct {
Power interface{}
Token string
Role int
Id int
}

@ -0,0 +1,122 @@
package values
import "server/common"
// GetCustomerHistoryReq 获取聊天信息
type GetCustomerHistoryReq struct {
Title int `json:"Title" binding:"required"` // 玩家uid
Page int `json:"Page" binding:"required"`
Num int `json:"Num" binding:"required"`
}
// GetCustomerHistoryResp 获取聊天信息
type GetCustomerHistoryResp struct {
List []*common.CustomerChatData
Count int64
}
// ReadMessageReq 消息已读接口
type ReadMessageReq struct {
OrderId int // 订单id
Title int `json:"Title" binding:"required"` // 玩家uid
List []int `json:"List" binding:"required"` // 传入需要标记已读消息的id
}
// 发送消息请求
type SendMessageReq struct {
common.CustomerChatData
}
// 查询订单请求
type GetCustomerOrderReq struct {
Page int `json:"Page" binding:"required"`
Num int `json:"Num" binding:"required"`
CustomerUid int `json:"CustomerUid"` // uid
Uid int `json:"Uid"` // 玩家uid
Status int `json:"Status"` // 工单状态码 等于 匹配
Vip int `json:"Vip"` // vip等级限制
Label int `json:"Label"` // 标签
Order int `json:"Order"` // 默认按创建时间逆序, 1表示按创建时间逆序, 2表示按创建时间正序 3表示按消息未读数排序
Status2 int `json:"Status2"` // 工单状态码 小于等于 匹配
Reply int // 是否已回复 0 不筛选 1已回复 2未回复
Recharge bool `json:"Recharge"` // 是否查询充值订单
}
type GetCustomerOrderResp struct {
List []*common.CustomerOrder
Count int64
}
// 改变工单状态
type ChangeCustomerOrderReq struct {
List []*CustomerOrderStatus
}
type CustomerOrderStatus struct {
Id int `json:"Id"` // 改订单id
Status int `json:"Status"` // 工单状态码
Label1 int `json:"Label1"` // 工单标签
Label2 int `json:"Label2"` // 工单标签
Label3 int `json:"Label3"` // 工单标签
Label4 int `json:"Label4"` // 工单标签
Label5 int `json:"Label5"` // 工单标签
Remark string
}
// 分配工单到客服人员
type CustomerOrderAllocateReq struct {
List []*OrderAllocate
}
type OrderAllocate struct {
Uid int // 客服人员uid
OrderId int // 分配工单Id
}
// 分配工单到客服人员
type CustomerOrderAllocateResp struct {
List []*OrderAllocate
}
// 编辑订单标签
type EditCustomerOrderLabelReq struct {
OrderId int `json:"OrderId" binding:"required"` // 编辑的订单id
LabelId1 int `json:"LabelId1" binding:"required"` // 编辑的标签id
LabelId2 int `json:"LabelId2" binding:"required"` // 编辑的标签id
LabelId3 int `json:"LabelId3" binding:"required"` // 编辑的标签id
LabelId4 int `json:"LabelId4" binding:"required"` // 编辑的标签id
LabelId5 int `json:"LabelId5" binding:"required"` // 编辑的标签id
}
// 玩家信息
type GetPlayerInfoReq struct {
Uid int `json:"Uid" binding:"required"` // 客诉玩家uid
}
// 玩家信息响应
type GetPlayerInfoResp struct {
Uid int // 客诉玩家uid
Nick string // 昵称
Avatar string // 头像
Birth int64 // 注册日期
Phone string // 玩家电话号码
Channel int // 渠道
Package string // 游戏包名
Vip int // 玩家vip等级
Recharge int64 // 玩家充值总金额
Withdraw int64 // 玩家提现总金额
CustomerBlack bool // 是否被拉黑
}
// 玩家客诉历史请求
type ComplaintHistoryReq struct {
Uid int `json:"Uid" binding:"required"` // 玩家uid
Page int `json:"Page" binding:"required"`
Num int `json:"Num" binding:"required"`
}
// 玩家客诉历史响应
type ComplaintHistoryResp struct {
List []*common.CustomerOrder
Count int64
}

@ -0,0 +1,63 @@
package values
import "server/common"
// 图片存放地址
var (
ImagePath = "images"
)
// DownLoadImageReq 图片请求
type DownLoadImageReq struct {
ImagePath string `json:"ImagePath" binding:"required"` // 图片地址
}
// EditHistoryListReq 操作日志请求
type EditHistoryListReq struct {
Page uint `json:"Page" binding:"required"`
Num uint `json:"Num" binding:"required"`
}
// EditHistoryListResp 操作日志
type EditHistoryListResp struct {
List []EditHistory
Count int64
}
// GoodListResp 请求物品列表返回
type GoodListResp struct {
List []*common.SheetGoods_config
}
// ProductListResp 请求充值列表返回
type ProductListResp struct {
List []*common.ConfigPayProduct
}
// GamesListResp 游戏列表
type GamesListResp struct {
List []string
}
// ChannelListResp 渠道列表
type ChannelListResp struct {
List []*common.Channel
}
// UserInfoResp 获取用户信息
type UserInfoResp struct {
Name string
Role int
Power string
}
// GameInfoResp 游戏信息,游戏名称跟游戏id
type GameInfoResp struct {
List []GameInfo
RoomId []int
}
type GameInfo struct {
GameId int
Name string
}

@ -0,0 +1,10 @@
package values
// 错误码
const (
CodeOK = iota
CodeRetry
CodeToken
CodeParam
CodePower // 权限不足
)

@ -0,0 +1,96 @@
package values
import "server/common"
// GetCustomerRobotReq 客服机器人请求
type GetCustomerRobotReq struct {
ParentId int // 该消息父类id
}
// GetCustomerRobotResp 客服机器人响应
type GetCustomerRobotResp struct {
List []*common.ConfigCustomerRobot
}
// EditCustomerRobotReq 编辑客服机器人消息
type EditCustomerRobotReq struct {
List []*common.ConfigCustomerRobot
}
// EditCustomerRobotResp 编辑客服机器人消息
type EditCustomerRobotResp struct {
List []*common.ConfigCustomerRobot
}
// DelCustomerRobotReq 删除客服机器人消息
type DelCustomerRobotReq struct {
List []*int // id
}
// GetCustomerLabelResp 订单标签响应
type GetCustomerLabelResp struct {
List []*common.CustomerOrderLabel
}
// EditCustomerLabelReq 编辑订单标签响应
type EditCustomerLabelReq struct {
List []*common.CustomerOrderLabel
}
// DelCustomerLabelReq 删除订单标签响应
type DelCustomerLabelReq struct {
List []*int // id
}
// GetConfigCustomerResp 客服系统配置
type GetConfigCustomerResp struct {
List []*common.ConfigCustomer
}
// EditConfigCustomerReq 客服系统配置
type EditConfigCustomerReq struct {
List []*common.ConfigCustomer
}
// DelConfigCustomerReq 客服系统配置
type DelConfigCustomerReq struct {
List []*int // id
}
// 客服黑名单请求
type CustomerBlackUserReq struct {
Page int `json:"Page" binding:"required"`
Num int `json:"Num" binding:"required"`
}
// 客服黑名单请求
type CustomerBlackUserResp struct {
List []*common.CustomerBlackUser
Count int64
}
// DelConfigCustomerReq 客服系统配置
type EditCustomerBlackUserReq struct {
Opt int // 1是添加黑名单 2是删除黑名单
List []*int // uid 传玩家uid
}
// GMConfigCommonListReq 后台获取调控配置通用接口
type GMConfigCommonListReq struct {
Condition map[string]interface{}
}
// GMConfigCommonListResp 后台获取调控配置通用接口
type GMConfigCommonListResp struct {
Config interface{}
}
// GMConfigCommonEditReq 后台修改调控配置通用接口
type GMConfigCommonEditReq struct {
Config []map[string]interface{}
}
// GMConfigCommonDelReq 后台删除调控配置通用接口
type GMConfigCommonDelReq struct {
ID int
}

@ -0,0 +1,111 @@
package values
// 权限对应页签
const (
PowerAll = iota
// 系统管理从1开始
PowerGM // 系统配置
PowerManageRole // 角色管理账户权限
PowerManageUser // 用户管理账户权限
PowerMail // 邮件权限
PowerOrderAllocate // 工单分配权限
PowerOrderProcessing // 工单处理权限
PowerOptionLog // 操作日志权限
PowerOptionBlack // 操作黑名单权限
PowerMax1
)
// 数据管理从100开始
const (
PowerRealData = iota + 100 // 实时数据 100
PowerGameData // 游戏概况 101
PowerNewPlayData // 新增用户分析 102
PowerActivePlayData // 用户活跃分析 103
PowerFinancialData // 系统货币 104
PowerRechargeData // 收入概要 105
PowerPlayData // 用户牌局 106
PowerRechargeOrder // 订单明细 107
PowerShareData // 分享数据 108
PowerWithdrawOrder // 提现明细 109
PowerGame // 游戏牌局 110
PowerRealProfit // 实时盈亏 111
PowerRedActivity // 红包雨活动 112
PowerPlayerProfit // 玩家收益 113
PowerEventTrack // 打点数据 114
PowerMax2
)
func IsValidPower(p int) bool {
if p > PowerAll && p < PowerMax1 || p >= PowerRealData && p < PowerMax2 {
return true
}
return false
}
var (
// 权限映射表
PowerMap = map[string]int{
"/gm": PowerGM,
"/power/role": PowerManageRole,
"/power/user": PowerManageUser,
"/mail": PowerMail,
"/order/allocate": PowerOrderAllocate,
"/customer": PowerOrderProcessing,
"/option/log": PowerOptionLog,
"/black": PowerOptionBlack,
}
// 页面按钮权限
PowerButtonMap = map[int][]string{}
)
type UserListResp struct {
List []User
}
// AddUserReq 新增角色
type AddUserReq struct {
Role int `json:"Role" binding:"required"`
Name string `json:"Name" binding:"required"`
Account string `json:"Account" binding:"required"`
Password string `json:"Password" binding:"required"`
Phone string `json:"Phone" binding:"required"`
Channels string `json:"Channels"`
}
// DelUserReq 删除角色
type DelUserReq struct {
ID int `json:"ID" binding:"required"`
}
type RoleListResp struct {
List []Role
}
// AddRoleReq 新增角色
type AddRoleReq struct {
Role int `json:"Role" binding:"required"`
Name string `json:"Name" binding:"required"`
Power string `json:"Power" binding:"required"`
}
// EditRoleReq 编辑角色
type EditRoleReq struct {
ID int `json:"ID" binding:"required"`
Role int `json:"Role" binding:"required"`
Name string `json:"Name" binding:"required"`
Power string `json:"Power" binding:"required"`
}
// EditPowerReq 编辑权限
// ID 账户id
// Power 用户编辑后的权限
type EditPowerReq struct {
ID int `json:"ID" binding:"required"`
Power *string `json:"Power"`
Role *int `json:"Role"`
Name *string `json:"Name"`
Account *string `json:"Account"`
Password *string `json:"Password"`
Phone *string `json:"Phone"`
Channels *string `json:"Channels"`
}

@ -0,0 +1,53 @@
package values
// User 后台用户
type User struct {
Name string `gorm:"column:name;type:varchar(32);uniqueIndex:name;not null;comment:名字" json:"Name"`
Account string `gorm:"column:account;type:varchar(32);uniqueIndex:account;not null;comment:账号" json:"Account"`
Password string `gorm:"column:password;type:varchar(32);not null;comment:密码" json:"Password"`
ID uint `gorm:"primarykey"`
Role int `gorm:"column:role;type:tinyint(4);not null;comment:角色" json:"Role"`
Power string `gorm:"column:power;type:varchar(512);not null;comment:权限" json:"Power"`
PowerMap map[int][]int `gorm:"-" json:"PowerMap"`
Phone string `gorm:"column:phone;type:varchar(32);uniqueIndex:phone;comment:手机号" json:"Phone"`
Channels string `gorm:"column:channels;type:varchar(512);not null;comment:拥有权限的包,为空时代表所有包都有权限" json:"Channels"`
SChannels []int `gorm:"-"`
Online int `gorm:"column:online;type:tinyint(4);default:0;comment:是否在线" json:"Online"`
}
func (u *User) TableName() string {
return "users"
}
// EditHistory 后台修改操作历史
// Operator 操作人
// Detail 修改内容
// Time 时间
// Model 操作模块,与权限列表对应
type EditHistory struct {
Operator string `gorm:"column:operator;type:varchar(32);not null;comment:操作人" json:"Operator"`
Detail string `gorm:"column:detail;type:varchar(256);not null;comment:修改明细" json:"Detail"`
ID uint `gorm:"primarykey" json:"-"`
Time int64 `gorm:"column:time;type:bigint(20);default:0;comment:操作时间" json:"Time"`
UID int `gorm:"column:uid;type:int(11);comment:操作人id" json:"UID"`
Model int `gorm:"column:model;type:int(11);comment:操作功能模块" json:"Model"`
}
func (e *EditHistory) TableName() string {
return "edit_history"
}
// Role 后台角色
// Role 角色等级 1是超管
// Power 权限
// Name 角色名
type Role struct {
ID uint `gorm:"primarykey"`
Role int `gorm:"column:role;type:tinyint(4);uniqueIndex:role;not null;comment:角色等级" json:"Role"`
Power string `gorm:"column:power;type:varchar(512);not null;comment:权限" json:"Power"`
Name string `gorm:"column:name;type:varchar(32);uniqueIndex:name;not null;comment:角色名" json:"Name"`
}
func (u *Role) TableName() string {
return "role"
}

@ -145,6 +145,9 @@ func NewSub(b *base.Base, index int) {
if index < 0 {
return
}
if b != nil {
b.Channel = values.PayWay(index)
}
if index >= int(values.PayAll) {
log.Error("get newSub err, %d %d", index, values.PayAll)
return

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/config"
"server/modules/pay/base"
"server/modules/pay/values"
@ -161,13 +160,13 @@ func (s *Sub) PackWithdrawReq() interface{} {
AccountName: r.Name,
NotifyURL: s.Base.GetWithdrawCallbackURL(),
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.BankNo = r.PayCode
send.AccountType = "BANK"
send.AccountNo = r.CardNo
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.BankNo = r.PayCode
send.AccountType = "BANK"
send.AccountNo = r.CardNo
//} else {
// return nil
//}
// signStr := GetSignStr(send, s.Base.SignPassStr...)
// signStr = signStr + "&key=" + key
// send.Sign = util.CalculateMD5(util.CalculateMD5(signStr))

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/modules/pay/base"
"server/modules/pay/values"
"server/pb"
@ -147,12 +146,12 @@ func (s *Sub) PackWithdrawReq() interface{} {
NotifyUrl: s.Base.GetWithdrawCallbackURL(),
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.IfscCode = r.PayCode
send.BankCardNumber = r.CardNo
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.IfscCode = r.PayCode
send.BankCardNumber = r.CardNo
//} else {
// return nil
//}
send.Sign = s.Base.SignMD5(send)
return send

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/modules/pay/base"
"server/modules/pay/values"
"server/pb"
@ -158,16 +157,16 @@ func (s *Sub) PackWithdrawReq() interface{} {
NotifyUrl: s.Base.GetWithdrawCallbackURL(),
CreateOrderTime: fmt.Sprintf("%d", time.Now().Unix()),
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.PayType = "IMPS"
send.UserBankAccount = r.CardNo
send.IfscCode = r.PayCode
} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
send.PayType = "UPI"
send.UserBankAccount = r.PayCode
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.PayType = "IMPS"
send.UserBankAccount = r.CardNo
send.IfscCode = r.PayCode
//} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
// send.PayType = "UPI"
// send.UserBankAccount = r.PayCode
//} else {
// return nil
//}
send.Sign = s.Base.SignMD5(send)
return send

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/modules/pay/base"
"server/modules/pay/values"
"server/pb"
@ -158,16 +157,16 @@ func (s *Sub) PackWithdrawReq() interface{} {
NotifyUrl: s.Base.GetWithdrawCallbackURL(),
ReqTime: time.Now().Unix(),
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.PayType = "IMPS"
send.UbAccount = r.CardNo
send.IfscCode = r.PayCode
} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
send.PayType = "UPI"
send.UbAccount = r.PayCode
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.PayType = "IMPS"
send.UbAccount = r.CardNo
send.IfscCode = r.PayCode
//} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
// send.PayType = "UPI"
// send.UbAccount = r.PayCode
//} else {
// return nil
//}
send.Sign = s.Base.SignMD5(send)
return send

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/modules/pay/base"
"server/modules/pay/values"
"server/pb"
@ -154,14 +153,14 @@ func (s *Sub) PackWithdrawReq() interface{} {
ClientIp: r.IP,
NotifyUrl: s.Base.GetWithdrawCallbackURL(),
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.PayType = 4
send.Account = r.CardNo
send.AccountOwner = r.Name
send.BankCode = r.PayCode
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.PayType = 4
send.Account = r.CardNo
send.AccountOwner = r.Name
send.BankCode = r.PayCode
//} else {
// return nil
//}
str := base.GetSignStr(send)
var err error
send.Sign, err = base.SignWithSHA512([]byte(str), string(privateKey))

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/config"
"server/modules/pay/base"
"server/modules/pay/values"
@ -155,15 +154,15 @@ func (s *Sub) PackWithdrawReq() interface{} {
Timestamp: fmt.Sprintf("%d", time.Now().Unix()),
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.PayMethod = "imps"
send.IFSC = r.PayCode
send.Account = r.CardNo
} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
send.PayMethod = "upi"
send.Account = r.PayCode
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.PayMethod = "imps"
send.IFSC = r.PayCode
send.Account = r.CardNo
//} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
// send.PayMethod = "upi"
// send.Account = r.PayCode
// return nil
//}
s.Base.Sign = s.Base.SignMD5(send)
return send

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/modules/pay/base"
"server/modules/pay/values"
"server/pb"
@ -154,13 +153,13 @@ func (s *Sub) PackWithdrawReq() interface{} {
Phone: r.Phone,
SignType: "RSA",
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.BankName = r.BankName
send.AccountNumber = r.CardNo
send.IfscCode = r.PayCode
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.BankName = r.BankName
send.AccountNumber = r.CardNo
send.IfscCode = r.PayCode
//} else {
// return nil
//}
str := base.GetSignStr(send)
var err error
send.Sign, err = base.SignWithSHA512([]byte(str), string(privateKey))

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/modules/pay/base"
"server/modules/pay/values"
"server/pb"
@ -156,14 +155,14 @@ func (s *Sub) PackWithdrawReq() interface{} {
Time: fmt.Sprintf("%d", time.Now().Unix()),
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.AccountType = "Bank"
send.AccountCode = r.PayCode
send.IFSC = r.PayCode
send.Account = r.CardNo
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.AccountType = "Bank"
send.AccountCode = r.PayCode
send.IFSC = r.PayCode
send.Account = r.CardNo
//} else {
// return nil
//}
send.Sign = s.Base.SignMD5(send)
return send

@ -140,6 +140,7 @@ func (s *Sub) PackWithdrawReq() interface{} {
KeyId: KeyID,
NotifyUrl: s.Base.GetWithdrawCallbackURL(),
}
// todo
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
} else {
return nil

@ -113,7 +113,7 @@ func (s *Sub) PackWithdrawReq() interface{} {
MchNo: mchId,
MchOrderNo: r.OrderID,
Currency: "INR",
PayAmount: fmt.Sprintf("%."+strconv.Itoa(2)+"f", float64(r.Amount)/common.DecimalDigits),
PayAmount: fmt.Sprintf("%."+strconv.Itoa(2)+"f", float64(r.Amount)),
AccountType: accountType,
AccountCode: r.PayCode,
AccountNo: r.CardNo,

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/modules/pay/base"
"server/modules/pay/values"
"server/pb"
@ -190,17 +189,17 @@ func (s *Sub) PackWithdrawReq() interface{} {
AccountEmail: r.Email,
Version: "1.0",
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.ReceiptMode = 1
send.AccountNumber = r.CardNo
send.AccountExtra1 = r.PayCode
send.AccountExtra2 = r.PayCode[:4]
} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
send.ReceiptMode = 0
send.AccountNumber = r.PayCode
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.ReceiptMode = 1
send.AccountNumber = r.CardNo
send.AccountExtra1 = r.PayCode
send.AccountExtra2 = r.PayCode[:4]
//} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
// send.ReceiptMode = 0
// send.AccountNumber = r.PayCode
//} else {
// return nil
//}
send.Sign = Sign(util.StructToMapJson(send), 1)
return send
}

@ -102,7 +102,7 @@ func (s *Sub) PackWithdrawReq() interface{} {
Type: "api",
MchId: mchId,
MchTransNo: r.OrderID,
Amount: util.Decimal(float64(r.Amount)/common.DecimalDigits, 2),
Amount: float64(r.Amount),
NotifyUrl: values.GetWithdrawCallback(values.PayPlus),
AccountName: r.Name,
AccountNo: r.CardNo,

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/modules/pay/base"
"server/modules/pay/values"
"server/pb"
@ -155,13 +154,13 @@ func (s *Sub) PackWithdrawReq() interface{} {
MchOrderNo: r.OrderID,
NotifyURL: s.Base.GetWithdrawCallbackURL(),
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.EntryType = "IMPS"
send.AccountNo = r.CardNo
send.AccountCode = r.PayCode
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.EntryType = "IMPS"
send.AccountNo = r.CardNo
send.AccountCode = r.PayCode
//} else {
// return nil
//}
send.Sign = s.Base.SignMD5(send)
return send

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"server/common"
"server/config"
"server/modules/pay/base"
"server/modules/pay/values"
@ -196,16 +195,16 @@ func (s *Sub) PackWithdrawReq() interface{} {
// Account: ,
// IFSC: ,
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.Type = "BANK"
send.Account = r.CardNo
send.IFSC = r.PayCode
} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
send.Type = "UPI"
send.VPA = r.PayCode
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.Type = "BANK"
send.Account = r.CardNo
send.IFSC = r.PayCode
//} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
// send.Type = "UPI"
// send.VPA = r.PayCode
//} else {
// return nil
//}
str := fmt.Sprintf("%s%s%d%s%s%s", mid, send.MerchantOrderNo, send.OrderAmount, send.NonceStr, send.Timestamp, send.Action)
sign, err := base.SignDsa(str, privateKey)
if err != nil {

@ -6,7 +6,6 @@ import (
"fmt"
"math/rand"
"net/http"
"server/common"
"server/config"
"server/modules/pay/base"
"server/modules/pay/values"
@ -185,17 +184,17 @@ func (s *Sub) PackWithdrawReq() interface{} {
return nil
}
send.IfCode = code[rand.Intn(len(code))]
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.EntryType = BankCard
send.AccountNo = r.CardNo
send.ChannelExtra.Ifsc = r.PayCode
} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
send.EntryType = IndiaUpiUtr
send.AccountNo = r.PayCode
send.ChannelExtra.Upi = r.PayCode
} else {
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.EntryType = BankCard
send.AccountNo = r.CardNo
send.ChannelExtra.Ifsc = r.PayCode
//} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
// send.EntryType = IndiaUpiUtr
// send.AccountNo = r.PayCode
// send.ChannelExtra.Upi = r.PayCode
//} else {
// return nil
//}
// send.Sign = s.Base.SignMD5(send)
return send

@ -276,6 +276,7 @@ func TryWithdraw(or *common.WithdrawOrder) {
if channel == nil || channel.WithdrawPer <= 0 {
con := call.GetConfigWithdrawChannelsBest(common.CurrencyINR)
if con == nil {
log.Debug("get withdraw channel is nil")
return
}
req.Channel = int64(con.ChannelID)
@ -292,7 +293,7 @@ func TryWithdraw(or *common.WithdrawOrder) {
}
log.Debug("order:%v,err:%v", req.OrderID, err)
if err != nil {
log.Debug("order:%+v,err:%v", or, err)
log.Error("order:%+v,err:%v", or, err)
call.ReturnBackWithdraw(or, common.StatusROrderPay, common.StatusROrderFail, int(req.Channel))
return
}

@ -157,15 +157,15 @@ func (s *Sub) PackWithdrawReq() interface{} {
// Account: ,
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.WithdrawType = "1"
send.BankCode = r.PayCode
send.Account = r.CardNo
} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
send.WithdrawType = "2"
send.Account = r.PayCode
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.WithdrawType = "1"
send.BankCode = r.PayCode
send.Account = r.CardNo
//} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
// send.WithdrawType = "2"
// send.Account = r.PayCode
// return nil
//}
str := base.GetSignStr(send, s.Base.SignPassStr...) + "&key=" + key
var err error

@ -283,43 +283,44 @@ func WithdrawSuccess(w PayWay) {
}
func PayFail(w PayWay) {
// failWeight := config.GetConfig().Pay.PayFailWeight
// if failWeight <= 0 {
// return
// }
// PayWeightLock.Lock()
// for _, v := range call.ConfigPayChannels {
// if v.ChannelID == int(w) {
// v.PayPer -= failWeight
// break
// }
// }
// sort.Slice(call.ConfigPayChannels, func(i, j int) bool {
// return call.ConfigPayChannels[i].PayPer > call.ConfigPayChannels[j].PayPer
// })
// PayWeightLock.Unlock()
// AddPayChannel(int(w), -failWeight)
// call.AddChannel(int(w), false)
if w == MoneydealerPay {
return
}
failWeight := config.GetConfig().Pay.PayFailWeight
if failWeight <= 0 {
return
}
PayWeightLock.Lock()
for _, v := range call.ConfigPayChannels {
if v.ChannelID == int(w) {
v.PayPer -= failWeight
break
}
}
sort.Slice(call.ConfigPayChannels, func(i, j int) bool {
return call.ConfigPayChannels[i].PayPer > call.ConfigPayChannels[j].PayPer
})
PayWeightLock.Unlock()
AddPayChannel(int(w), -failWeight)
}
func PaySuccess(w PayWay) {
// successWeight := config.GetConfig().Pay.PaySuccessWeight
// if successWeight <= 0 {
// return
// }
// PayWeightLock.Lock()
// for _, v := range call.ConfigPayChannels {
// if v.ChannelID == int(w) {
// v.PayPer += successWeight
// break
// }
// }
// sort.Slice(call.ConfigPayChannels, func(i, j int) bool {
// return call.ConfigPayChannels[i].PayPer > call.ConfigPayChannels[j].PayPer
// })
// PayWeightLock.Unlock()
// AddPayChannel(int(w), successWeight)
call.AddChannel(int(w), true)
successWeight := config.GetConfig().Pay.PaySuccessWeight
if successWeight <= 0 {
return
}
PayWeightLock.Lock()
for _, v := range call.ConfigPayChannels {
if v.ChannelID == int(w) {
v.PayPer += successWeight
break
}
}
sort.Slice(call.ConfigPayChannels, func(i, j int) bool {
return call.ConfigPayChannels[i].PayPer > call.ConfigPayChannels[j].PayPer
})
PayWeightLock.Unlock()
AddPayChannel(int(w), successWeight)
}
// 获取支付回调路径
@ -542,14 +543,10 @@ func AddWithdrawChannel(p int, amount int) {
}
func AddPayChannel(p int, amount int) {
channel := &common.ConfigPayChannels{
ChannelID: p,
}
db.Mysql().Get(&channel)
if channel.PayPer+amount > 100 {
if err := db.Mysql().C().Model(&common.ConfigPayChannels{}).Where("channel_id = ?", p).Updates(map[string]interface{}{"pay_per": gorm.Expr("pay_per + ?", amount)}).Error; err != nil {
log.Error("err:%v", err)
}
log.Debug("update pay per, %d:%d", p, amount)
if err := db.Mysql().C().Model(&common.ConfigPayChannels{}).Where("channel_id = ? and pay_per > 0 ", p).
Updates(map[string]interface{}{"pay_per": gorm.Expr("pay_per + ?", amount)}).Error; err != nil {
log.Error("err:%v", err)
}
}

@ -162,16 +162,16 @@ func (s *Sub) PackWithdrawReq() interface{} {
NotifyURL: s.Base.GetWithdrawCallbackURL(),
}
if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.PayType = 1
send.IFSC = r.PayCode
send.Account = r.CardNo
send.BankName = r.BankName
} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
send.PayType = 2
send.Account = r.PayCode
return nil
}
//if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank {
send.PayType = 1
send.IFSC = r.PayCode
send.Account = r.CardNo
send.BankName = r.BankName
//} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI {
// send.PayType = 2
// send.Account = r.PayCode
// return nil
//}
send.Sign = s.Base.SignMD5(send)
return send
}

@ -1,17 +1,20 @@
package app
import (
"fmt"
"github.com/go-redis/redis/v8"
"github.com/liangdas/mqant/log"
iptool "github.com/liangdas/mqant/utils/ip"
"github.com/olivere/elastic/v7"
"gorm.io/gorm"
"net"
"server/call"
"server/common"
"server/db"
"server/modules/web/values"
"server/util"
"strings"
"github.com/go-redis/redis/v8"
"github.com/liangdas/mqant/log"
iptool "github.com/liangdas/mqant/utils/ip"
"gorm.io/gorm"
"time"
)
// VerifyCode 验证短信验证码
@ -88,6 +91,20 @@ func (g *Gin) QueryUser(req values.CommonLogin) (user *common.PlayerDBInfo, isNe
return
}
isNew = true
if len(req.DeviceID) > 0 {
uuid := req.DeviceID
// 处理一下新增安装
util.Go(func() {
q := elastic.NewBoolQuery()
q.Filter(elastic.NewTermsQuery("UUID.keyword", uuid))
q.Filter(elastic.NewTermQuery("Channel", g.Channel))
if db.ES().Count(common.ESIndexBackOpenRecord, q) > 0 {
return
}
id := fmt.Sprintf("%v_%v", g.Channel, uuid)
db.ES().InsertToESByIDGO(common.ESIndexBackOpenRecord, id, &common.ESOpenRecord{Time: time.Now().Unix(), UUID: uuid, Channel: g.Channel})
})
}
} else {
user.ADID = req.Adid
user.GPSADID = req.Gpsadid

@ -100,6 +100,8 @@ func (g *Gin) Response() {
if g.R.Code == values.CodeRetry {
} else if g.R.Code == values.CodeToken {
g.R.Msg = "login expired"
} else if g.R.Code == values.CodeCodeError {
g.R.Msg = "Code is wrong"
}
jsonData, _ := json.Marshal(g.R)
g.Context.Data(http.StatusOK, "text", util.AesEncrypt(jsonData))

@ -573,8 +573,8 @@ func ShareCfg(c *gin.Context) {
resp.TotalAward = shareInfo.Reward
err := db.Mysql().C().Model(&common.ShareReward{}).
Select("COALESCE(SUM(reward_count), 0) as todayAmount").
Where("uid = ? and reward_at > ?", a.UID, util.GetZeroTime(time.Now()).Unix()).
Scan(&resp.TotalAward).Error
Where("uid = ? and reward_at > ? and reward_count > 0 ", a.UID, util.GetZeroTime(time.Now()).Unix()).
Scan(&resp.TodayAward).Error
if err != nil {
log.Error("get todayAmount err, %s", err.Error())
}
@ -850,6 +850,11 @@ func ShareWithdraw(c *gin.Context) {
db.Redis().UnLock(common.GetRedisKeyShare(uid))
}()
if req.Amount < 0 {
a.Code = values.CodeParam
a.Msg = "Insufficient Amount."
return
}
shareInfo := call.GetShareInfo(uid)
if shareInfo.Reward < req.Amount {
a.Code = values.CodeParam
@ -866,7 +871,12 @@ func ShareWithdraw(c *gin.Context) {
shareWithdrawInfo := call.GetShareWithdrawInfo(uid)
if shareWithdrawInfo.DayCount >= con.DayWithdrawCount {
a.Code = values.CodeParam
a.Msg = "Withdrawal limit."
a.Msg = fmt.Sprintf("Your current agent level is %d, with a maximum of %d withdrawals per day.", shareInfo.Level, con.DayWithdrawCount)
return
}
if shareWithdrawInfo.TodayWithdraw+req.Amount >= con.WithdrawAudit {
a.Code = values.CodeParam
a.Msg = fmt.Sprintf("Your current agent level is %d, with a max amount of %d withdrawals per day.", shareInfo.Level, con.WithdrawAudit/common.DecimalDigits)
return
}
err := call.UpdateShare(uid, 5, req.Amount, fmt.Sprintf("%d", req.Amount))
@ -894,10 +904,12 @@ func ShareWithdraw(c *gin.Context) {
updateValues := map[string]interface{}{
"day_count": 1,
"day_time": now.Unix(),
"today_withdraw": req.Amount,
"total_withdraw": gorm.Expr("total_withdraw + ?", req.Amount),
}
if shareWithdrawInfo.DayTime != 0 && util.IsSameDayTimeStamp(shareWithdrawInfo.DayTime, now.Unix()) {
updateValues["day_count"] = gorm.Expr("day_count + ?", 1)
updateValues["today_withdraw"] = gorm.Expr("today_withdraw + ?", req.Amount)
delete(updateValues, "day_time")
}
err = db.Mysql().C().Model(&common.ShareWithdrawInfo{}).Where("id = ?", shareWithdrawInfo.ID).Updates(updateValues).Error

@ -79,8 +79,11 @@ func getUserInfo(uid int, isNew bool) (resp values.UserInfoResp, err error) {
resp.Currencys[i] = ref.Field(int(i) + 1).Int()
}
if isNew {
if resp.Currencys[common.CurrencyINR] == 0 {
resp.Currencys[common.CurrencyINR] = call.GetConfigPlatform().NewPlayerGift
if resp.Currencys[common.CurrencyINR] == 0 && call.GetConfigPlatform().NewPlayerGift > 0 {
resp.Currencys[common.CurrencyINR] += call.GetConfigPlatform().NewPlayerGift
}
if resp.Currencys[common.CurrencyINR] == 0 && call.GetConfigPlatform().NewPlayerGift > 0 {
resp.Currencys[common.CurrencyINR] += call.GetConfigPlatform().NewPlayerGift
}
}
re := &common.RechargeInfo{UID: uid}

@ -88,6 +88,7 @@ func TokenMiddleWare() gin.HandlerFunc {
c.Set("uid", uid)
c.Set("token", token)
c.Set("referrer", c.GetHeader("referrer"))
c.Set("channel", c.GetHeader("channel"))
util.Go(func() {
db.Redis().AddUserExpire(uid, token)
})

@ -29,7 +29,7 @@ func (s *Sub) EnterGame() string {
token := s.Base.EnterGameReq.Token
providerID := s.Base.EnterGameReq.ProviderID
gameID := s.Base.EnterGameReq.GameID
game := call.GetConfigProviderGameListByID(providerID, gameID)
game := call.GetGameListByByID(providerID, gameID)
if game == nil {
return ""
}

@ -36,7 +36,7 @@ func Auth(c *gin.Context) {
req := &AuthReq{}
resp := &AuthResp{}
a.RetData = resp
if !a.S(req) {
if !a.SB(req) {
resp.Code = CodeRequestInvalidParams
return
}
@ -67,7 +67,7 @@ func GameBet(c *gin.Context) {
req := &GameBetReq{}
resp := &GameBetResp{}
a.RetData = resp
if !a.S(req) {
if !a.SB(req) {
resp.Code = CodeRequestInvalidParams
return
}
@ -125,7 +125,7 @@ func Jackpot(c *gin.Context) {
req := &JackpotReq{}
resp := &JackpotResp{}
a.RetData = resp
if !a.S(req) {
if !a.SB(req) {
resp.Code = CodeRequestInvalidParams
return
}

Loading…
Cancel
Save