package service import ( "context" "encoding/json" "errors" "fmt" "gadmin/config" "gadmin/internal/admin/consts" "gadmin/internal/admin/forms" "gadmin/internal/admin/gm_rpc/rpc_share" "gadmin/internal/gorm/model" "gadmin/internal/gorm/query" "gadmin/package/gmdata" "gadmin/utility" "gadmin/utility/character" "gadmin/utility/player" "gadmin/utility/serializer" "gorm.io/gorm/clause" "time" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" ) // UserAccount 玩家账号服务 var UserAccount = new(sUserAccount) type sUserAccount struct{} func (s *sUserAccount) MigrateComplete(ctx *gin.Context, req forms.MigrateCompleteReq) serializer.Response { DB, err := player.GetDBByUserId(req.PlayerId) if err != nil { return serializer.Err(consts.CodeParamErr, "GetDBByUserId err", err) } var ( models = new(forms.MigrateCompleteData) pm = query.Use(config.GDBGroup[DB]).PlayerMaterial pmm = pm.WithContext(ctx).Where(pm.Playerid.Eq(req.PlayerId)) ) if err = pmm.Scan(&models.PlayerMaterial); err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 PlayerMaterial", err) } logrus.Warnf("MigrateComplete models:%+v", models) return serializer.Suc(models) } func (s *sUserAccount) Get(ctx *gin.Context, req forms.UserAccountGetReq) serializer.Response { DB, err := player.GetDBByUserId(req.ID) if err != nil { return serializer.Err(consts.CodeParamErr, "GetDBByUserId err", err) } var ( q = query.Use(config.GDBGroup[DB]).PlayerAttr m = q.WithContext(ctx).Where(q.Playerid.Eq(req.ID)) models *model.PlayerAttr ) if err = m.Scan(&models); err != nil { return serializer.Err(consts.CodeParamErr, "查询出错", err) } type Data struct { *model.UserAccount BanReason string `json:"banReason"` PayOffReason string `json:"payOffReason"` SingleBan int32 `json:"singleBan"` SingleBanReason string `json:"singleBanReason"` ChatBan int32 `json:"chatBan"` ChatBanReason string `json:"chatBanReason"` ChatBanDeadlineTime int64 `json:"chatBanDeadlineTime"` } if models != nil { acc, _ := s.GetAcc(models.AccID) var data = new(Data) data.UserAccount = acc data.SingleBan = models.Ban var ( //chatQ = query.Use(config.GDBGroup[DB]).Chat //chatM = chatQ.WithContext(ctx).Where(chatQ.Playerid.Eq(req.ID)) //chatModel *model.Chat //banQ = query.Use(config.DB).AdminBanUserLog //banM = banQ.WithContext(ctx).Where(banQ.PlayerID.Eq(req.ID)) //banModels []*model.AdminBanUserLog ) /*if err = chatM.Scan(&chatModel); err != nil { return serializer.Err(consts.CodeParamErr, "查询出错", err) } if err = banM.Scan(&banModels); err != nil { fmt.Println("123") return serializer.Err(consts.CodeParamErr, "查询出错", err) } if chatModel != nil { if chatModel.ForbidTime > time.Now().Unix() { data.ChatBan = 1 data.ChatBanDeadlineTime = chatModel.ForbidTime } } for _, banModel := range banModels { switch banModel.Type { case consts.BanType: data.BanReason = banModel.Reason case consts.SingleBanType: data.SingleBanReason = banModel.Reason case consts.PaySwitchType: data.PayOffReason = banModel.Reason case consts.ChatBanType: data.ChatBanReason = banModel.Reason } }*/ return serializer.Suc(data) } return serializer.Err(consts.CodeParamErr, "查询出错 models != nil", err) } func (s *sUserAccount) List(ctx *gin.Context, req forms.UserAccountListReq) serializer.Response { type Result struct { ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` Playerid int64 `gorm:"column:playerid" json:"playerid"` Level int32 `gorm:"column:level" json:"level"` Exp int64 `gorm:"column:exp" json:"exp"` Stamina int32 `gorm:"column:stamina" json:"stamina"` Lastlogintick int64 `gorm:"column:lastlogintick" json:"lastlogintick"` Lastlogouttick int64 `gorm:"column:lastlogouttick" json:"lastlogouttick"` LastChapter string `gorm:"column:lastChapter" json:"lastChapter"` LastStamTick int64 `gorm:"column:lastStamTick" json:"lastStamTick"` Location string `gorm:"column:location" json:"location"` OpenID string `gorm:"column:openId" json:"openId"` NickName string `gorm:"column:nickName" json:"nickName"` ImgURL string `gorm:"column:imgUrl" json:"imgUrl"` ServerID int32 `gorm:"column:serverId" json:"serverId"` AccID int64 `gorm:"column:accId" json:"accId"` CreateTime time.Time `gorm:"column:create_time" json:"create_time"` CreateTime2 int64 `gorm:"column:createtime" json:"createtime"` Ban int32 `json:"ban"` SingleBan int32 `json:"singleBan"` Account string `json:"account"` } if req.ServerId <= 0 { return serializer.Err(consts.CodeParamErr, "必须选择一个有效的区服", nil) } DB, err := player.GetDBByServerID(req.ServerId) if err != nil { return serializer.Err(consts.CodeParamErr, "GetDB err", err) } var ( c = query.Use(config.DB).PlayerChannel q = query.Use(config.GDBGroup[DB]) u = q.PlayerAttr material = q.PlayerMaterial m = u.WithContext(ctx) offset int64 = 0 models forms.UserAccountListRes lists []Result joinMaterial bool ) if len(req.DiamondBetween) == 2 { if !joinMaterial { m = m.LeftJoin(material, material.Playerid.EqCol(u.Playerid)) joinMaterial = true } m = m.Where(material.Diamond.Between(int32(req.DiamondBetween[0]), int32(req.DiamondBetween[1]))) } if len(req.CoinBetween) == 2 { if !joinMaterial { m = m.LeftJoin(material, material.Playerid.EqCol(u.Playerid)) joinMaterial = true } m = m.Where(material.Coin.Between(int64(req.CoinBetween[0]), int64(req.CoinBetween[1]))) } if len(req.LevelBetween) == 2 { m = m.Where(u.Level.Between(req.LevelBetween[0], req.LevelBetween[1])) } if len(req.StaminaBetween) == 2 { m = m.Where(u.Stamina.Between(req.StaminaBetween[0], req.StaminaBetween[1])) } if len(req.Createtime) == 2 { m = m.Where(u.CreateTime.Between(time.Unix(req.Createtime[0], 0), time.Unix(req.Createtime[1], 0))) } if req.ID > 0 { m = m.Where(u.Playerid.Eq(req.ID)) } if req.Nickname != "" { m = m.Where(u.NickName.Like("%" + req.Nickname + "%")) } // openid if req.OpenId != "" { m = m.Where(u.OpenID.Like(req.OpenId)) } if len(req.Sorter) > 0 { for i := 0; i < len(req.Sorter); i++ { if req.Sorter[i].Field == "id" { if req.Sorter[i].By == "DESC" { m = m.Order(u.ID.Desc()) } else { m = m.Order(u.ID) } } if req.Sorter[i].Field == "createtime" { if req.Sorter[i].By == "DESC" { m = m.Order(u.CreateTime.Desc()) } else { m = m.Order(u.CreateTime) } } } } else { m = m.Order(u.ID.Desc()) } req.Page, req.PerPage, offset = forms.CalculatePage(req.Page, req.PerPage) count, err := m.Count() if err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 count", err) } if count > 0 { switch req.ChannelId { case consts.ChannelIdNone: // 不选择渠道 if err = m.Limit(int(req.PerPage)).Offset(int(offset)).Scan(&lists); err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 lists", err) } case consts.ChannelIdAllAdv, consts.ChannelIdAllWx, consts.ChannelIdAllTT: var playerids []int64 err = c.WithContext(ctx).Select(c.Playerid).Where(c.ChannelID.In(Channel.GetIdsByType(req.ChannelId)...)).Order(c.Playerid.Desc()).Limit(int(req.PerPage)).Offset(int(offset)).Pluck(c.Playerid, &playerids) if err != nil { return serializer.Err(consts.CodeParamErr, "Pluck count", err) } if err = m.Where(u.Playerid.In(playerids...)).Scan(&lists); err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 lists", err) } default: // 指定渠道 var playerids []int64 err = c.WithContext(ctx).Select(c.Playerid).Where(c.ChannelID.Eq(req.ChannelId)).Order(c.Playerid.Desc()).Limit(int(req.PerPage)).Offset(int(offset)).Pluck(c.Playerid, &playerids) if err != nil { return serializer.Err(consts.CodeParamErr, "Pluck count", err) } if err = m.Where(u.Playerid.In(playerids...)).Scan(&lists); err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 lists", err) } } } for k, v := range lists { lists[k].CreateTime2 = v.CreateTime.Unix() lists[k].SingleBan = lists[k].Ban acc, _ := s.GetAcc(lists[k].AccID) if acc != nil { lists[k].Ban = acc.Ban //lists[k].Account = acc.Account //lists[k].OpenID = acc.Openid } } models.List = lists models.Page = req.Page models.PerPage = req.PerPage models.PageCount = (count + req.PerPage - 1) / req.PerPage return serializer.Suc(models) } /*func (s *sUserAccount) UpdateNickname(ctx *gin.Context, req forms.UpdateNicknameReq) serializer.Response { //发送到nats type sendResult struct { ErrCode int `json:"errCode"` MsgId string `json:"msgId"` } data := struct { MsgId string `json:"msgId"` PlayerID int64 `json:"userId"` NickName string `json:"name"` }{ MsgId: character.GenerateMsgId(), PlayerID: req.UserId, NickName: req.Nickname, } resp := &sendResult{} serverId := model2.ExtractLineId(req.UserId) res, err := config.GmNats.GmRequest(serverId, "GmUpdateName", data) if err != nil { return serializer.Err(consts.CodeParamErr, err.Error(), err) } if err = json.Unmarshal(res, &resp); err != nil { return serializer.Err(consts.CodeParamErr, err.Error(), err) } rpc_share.LogChan <- rpc_share.LogMsg{ MsgID: data.MsgId, Data: resp, } return serializer.Suc(req) } func (s *sUserAccount) SingleBanUser(ctx *gin.Context, req forms.UserAccountBanReq) serializer.Response { DB, err := player.GetDBByUserId(req.ID) if err != nil { return serializer.Err(consts.CodeParamErr, "GetDBByUserId 出错", err) } logrus.Warnf("SingleBanUser.GetAccIdByPlayerId DB:%v", DB) var ( q = query.Use(config.GDBGroup[DB]).PlayerAttr m = q.Where(q.Playerid.Eq(req.ID)) ) if _, err = m.Update(q.Ban, req.Ban); err != nil { return serializer.Err(consts.CodeParamErr, "更新出错", err) } if req.ID == 0 { return serializer.Err(consts.CodeParamErr, "玩家ID不能为空", nil) } serverID, err := player.GetServerIDByUserId(req.ID) if err != nil { return serializer.Err(consts.CodeParamErr, "更新出错", err) } msgs := msg.GmSetBan{ MsgId: character.GenerateMsgId(), PlayerID: req.ID, Ban: int(req.Ban), OperatorId: token.GetUID(ctx), } if req.Ban == 0 { rpc_share.MsgMap[msgs.MsgId] = fmt.Sprintf("%s,GM为服务器[%v]玩家[%d]设为解封状态", utility.FormatSecond(time.Now()), gmdata.GetServerName(int(serverID)), req.ID) } else { rpc_share.MsgMap[msgs.MsgId] = fmt.Sprintf("%s,GM为服务器[%v]玩家[%v]设为封禁状态", utility.FormatSecond(time.Now()), gmdata.GetServerName(int(serverID)), req.ID) } var resp *msg.ResponseGmSetBan res, err := config.GmNats.GmRequest(int(serverID), "GmSetBan", msgs) if err != nil { return serializer.Err(consts.CodeParamErr, "GmRequest 出错", err) } if err = json.Unmarshal(res, &resp); err != nil { return serializer.Err(consts.CodeParamErr, "Unmarshal 出错", err) } rpc_share.LogChan <- rpc_share.LogMsg{ MsgID: msgs.MsgId, Data: resp, } createOrUpdateAdminBanUserLog(ctx, req.ID, consts.SingleBanType, req.Reason) strInfo := "Ban success" if req.Ban == 0 { strInfo = "Unban success" } return serializer.Suc(nil, strInfo) }*/ func (s *sUserAccount) BanUser(ctx *gin.Context, req forms.UserAccountBanReq) serializer.Response { accId, err := s.GetAccIdByPlayerId(req.ID) if err != nil { logrus.Warnf("GetAcc err:%+v", err) return serializer.Err(consts.CodeParamErr, "更新出错1", err) } if accId == 0 { logrus.Warnf("GetAcc accId == 0 ") return serializer.Err(consts.CodeParamErr, "更新出错 accId == 0", nil) } for _, table := range s.GetAccTables() { tx := config.LDB.Table(table).Where("accId = ? ", accId).Update("ban", req.Ban) if tx.Error != nil { return serializer.Err(consts.CodeParamErr, "更新出错", tx.Error) } } createOrUpdateAdminBanUserLog(ctx, req.ID, consts.BanType, req.Reason) strInfo := "Ban success" if req.Ban == 0 { strInfo = "Unban success" } return serializer.Suc(nil, strInfo) } func (s *sUserAccount) BanUserChat(ctx *gin.Context, req forms.BanChatReq) serializer.Response { if req.PlayerID == 0 { return serializer.Err(consts.CodeParamErr, "参数错误", errors.New("playerid不能为空")) } playerAttr, err := player.GetAttrByUserId(req.PlayerID) if err != nil { return serializer.Err(consts.CodeDBError, "系统错误", err) } DB, err := player.GetDBByPlayerAttr(playerAttr) if err != nil { return serializer.Err(consts.CodeDBError, "系统错误", err) } message := forms.GmChatForbid{ MsgId: character.GenerateMsgId(), PlayerID: req.PlayerID, ForbidTime: req.DeadlineTime, } if req.Ban == 0 { message.ForbidTime = 0 rpc_share.MsgMap[message.MsgId] = fmt.Sprintf("%s,服务器[%v]的玩家[%d]解除禁止聊天", utility.FormatSecond(time.Now()), gmdata.GetServerName(DB), req.PlayerID) } else { rpc_share.MsgMap[message.MsgId] = fmt.Sprintf("%s,服务器[%v]的玩家[%d]被禁止聊天", utility.FormatSecond(time.Now()), gmdata.GetServerName(DB), req.PlayerID) } var resp forms.ResponseGmChatForbid res, err := config.GmNats.GmRequest(DB, "GmChatForbid", message) if err != nil { return serializer.Err(consts.CodeParamErr, "nats request err", err) } if err = json.Unmarshal(res, &resp); err != nil { return serializer.Err(consts.CodeParamErr, "nats response err", err) } createOrUpdateAdminBanUserLog(ctx, req.PlayerID, consts.ChatBanType, req.Reason) rpc_share.LogChan <- rpc_share.LogMsg{ MsgID: message.MsgId, Data: resp, } strInfo := "Ban success" if req.Ban == 0 { strInfo = "Unban success" } return serializer.Suc(nil, strInfo) } /*func (s *sUserAccount) UpdatePaySwitch(ctx *gin.Context, req forms.GmSetPaySwitch) serializer.Response { DB, err := player.GetDBByUserId(req.PlayerID) if err != nil { return serializer.Err(consts.CodeParamErr, "GetDBByUserId 出错", err) } logrus.Warnf("UpdatePaySwitch.GetAccIdByPlayerId DB:%v", DB) var ( q = query.Use(config.GDBGroup[DB]).PlayerMaterial m = q.Where(q.Playerid.Eq(req.PlayerID)) ) if _, err = m.Update(q.PaySwitch, req.Switch); err != nil { return serializer.Err(consts.CodeParamErr, "更新出错", err) } if req.PlayerID == 0 { return serializer.Err(consts.CodeParamErr, "玩家ID不能为空", nil) } serverID, err := player.GetServerIDByUserId(req.PlayerID) if err != nil { return serializer.Err(consts.CodeParamErr, "更新出错", err) } msgs := msg.GmSetPaySwitch{ MsgId: character.GenerateMsgId(), PlayerID: req.PlayerID, Switch: req.Switch, } if req.Switch == 0 { rpc_share.MsgMap[msgs.MsgId] = fmt.Sprintf("%s,GM为服务器[%v]玩家[%d]开启支付", utility.FormatSecond(time.Now()), gmdata.GetServerName(int(serverID)), req.PlayerID) } else { rpc_share.MsgMap[msgs.MsgId] = fmt.Sprintf("%s,GM为服务器[%v]玩家[%v]关闭支付", utility.FormatSecond(time.Now()), gmdata.GetServerName(int(serverID)), req.PlayerID) } var resp *msg.ResponseGmSetPaySwitch res, err := config.GmNats.GmRequest(int(serverID), "GmSetPaySwitch", msgs) if err != nil { return serializer.Err(consts.CodeParamErr, "GmRequest 出错", err) } if err = json.Unmarshal(res, &resp); err != nil { return serializer.Err(consts.CodeParamErr, "Unmarshal 出错", err) } rpc_share.LogChan <- rpc_share.LogMsg{ MsgID: msgs.MsgId, Data: resp, } createOrUpdateAdminBanUserLog(ctx, req.PlayerID, consts.PaySwitchType, req.Reason) strInfo := "switch success" if req.Switch == 0 { strInfo = "UnSwitch success" } return serializer.Suc(nil, strInfo) }*/ func createOrUpdateAdminBanUserLog(ctx *gin.Context, playerID int64, typ int32, reason string) { var adminID int64 if id, ok := ctx.Get("admin_id"); ok { if i, ok2 := id.(int64); ok2 { adminID = i } } // 记录禁用原因 now := time.Now().Unix() q := query.Use(config.DB).AdminBanUserLog m := q.WithContext(context.Background()).Where(q.PlayerID.Eq(playerID), q.Type.Eq(typ)) adminBanUserData := &model.AdminBanUserLog{ AdminID: int32(adminID), IP: ctx.ClientIP(), PlayerID: playerID, Type: typ, Reason: reason, CreateAt: int32(now), UpdateAt: int32(now), } if err := m.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "player_id"}, {Name: "type"}}, DoUpdates: clause.AssignmentColumns([]string{"admin_id", "ip", "reason", "update_at"}), }).Create(adminBanUserData); err != nil { logrus.Errorf("Create Or Update admin_ban_user_log err:%v", err.Error()) } } func (s *sUserAccount) GetAccIdByPlayerId(playerId int64) (accId int64, err error) { DB, err := player.GetDBByUserId(playerId) if err != nil { return } logrus.Warnf("GetAccIdByPlayerId DB:%v", DB) var ( q = query.Use(config.GDBGroup[DB]).PlayerAttr m = q.Select(q.AccID).Where(q.Playerid.Eq(playerId)) models *model.PlayerAttr ) if err = m.Scan(&models); err != nil { return } if models != nil { accId = models.AccID return } return 0, nil } // GetAcc 获取档案信息 func (s *sUserAccount) GetAcc(accId int64) (models *model.UserAccount, tab string) { for _, table := range s.GetAccTables() { config.LDB.Table(table).Where("accId = ? ", accId).Scan(&models) if models != nil { return models, table } } return nil, "" } func (s *sUserAccount) GetAccTables() (tables []string) { type Table struct { Value string } var sql = "SELECT TABLE_NAME as `value` FROM information_schema.`TABLES` WHERE TABLE_SCHEMA ='graveaccount1' AND TABLE_NAME LIKE 'user_account_%'" tx := config.LDB.Raw(sql) if err := tx.Scan(&tables).Error; err != nil { logrus.Warnf("service.GetAcc err:%+v", err) return } logrus.Warnf("service.GetAccTables tables:%+v", tables) return tables } func (s *sUserAccount) Search(ctx *gin.Context, req forms.UserAccountSearchReq) serializer.Response { if req.ID == 0 && req.OpenId == "" && req.AccId == 0 { return serializer.Suc(nil) } if req.ID > 0 { accId, err := player.GetAccIDByUserId(req.ID) if err != nil { return serializer.Err(consts.CodeParamErr, err.Error(), nil) } if accId > 0 { req.AccId = accId } } if req.OpenId != "" { accId, err := player.GetAccIDByOpenId(req.OpenId) if err != nil { return serializer.Err(consts.CodeParamErr, err.Error(), nil) } if accId > 0 { req.AccId = accId } } if req.AccId <= 0 { return serializer.Suc(nil) } type Result struct { ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` Playerid int64 `gorm:"column:playerid" json:"playerid"` Level int32 `gorm:"column:level" json:"level"` Exp int64 `gorm:"column:exp" json:"exp"` Stamina int32 `gorm:"column:stamina" json:"stamina"` Lastlogintick int64 `gorm:"column:lastlogintick" json:"lastlogintick"` Lastlogouttick int64 `gorm:"column:lastlogouttick" json:"lastlogouttick"` LastChapter string `gorm:"column:lastChapter" json:"lastChapter"` LastStamTick int64 `gorm:"column:lastStamTick" json:"lastStamTick"` Location string `gorm:"column:location" json:"location"` OpenID string `gorm:"column:openId" json:"openId"` NickName string `gorm:"column:nickName" json:"nickName"` ImgURL string `gorm:"column:imgUrl" json:"imgUrl"` ServerID int32 `gorm:"column:serverId" json:"serverId"` AccID int64 `gorm:"column:accId" json:"accId"` CreateTime time.Time `gorm:"column:create_time" json:"create_time"` CreateTime2 int64 `gorm:"column:createtime" json:"createtime"` Ban int32 `json:"ban"` SingleBan int32 `json:"singleBan"` Account string `json:"account"` ServerName string `json:"serverName"` } var ( models forms.UserAccountListRes lists []*Result ) for _, DB := range config.GDBGroup { var ( q = query.Use(DB).PlayerAttr m = q.WithContext(ctx) ) var first *Result if err := m.Where(q.AccID.Eq(req.AccId)).Scan(&first); err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 First", err) } if first != nil { first.ServerName, _ = ServerOption.GetName(ctx, int32(config.GetDBId(DB))) lists = append(lists, first) } } req.Page, req.PerPage, _ = forms.CalculatePage(req.Page, req.PerPage) for k, v := range lists { lists[k].CreateTime2 = v.CreateTime.Unix() lists[k].SingleBan = lists[k].Ban acc, _ := s.GetAcc(lists[k].AccID) if acc != nil { lists[k].Ban = acc.Ban //lists[k].Account = acc.Account //lists[k].OpenID = acc.Openid } } count := int64(len(lists)) models.List = lists models.Page = req.Page models.PerPage = req.PerPage models.PageCount = (count + req.PerPage - 1) / req.PerPage return serializer.Suc(models) }