挪到子仓库中
This commit is contained in:
parent
617332daed
commit
5bb0240a7c
@ -1,54 +0,0 @@
|
||||
package jackpot
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func JackpotSet(rdb *redis.Client, gameId int, chips int64) {
|
||||
key := fmt.Sprintf("Jackpot:%d", gameId)
|
||||
_, _ = rdb.Set(context.Background(), key, chips, 0).Result()
|
||||
}
|
||||
|
||||
func JackpotAdd(rdb *redis.Client, gameId int, chips int64) int64 {
|
||||
key := fmt.Sprintf("Jackpot:%d", gameId)
|
||||
v, _ := rdb.IncrBy(context.Background(), key, chips).Result()
|
||||
return v
|
||||
}
|
||||
|
||||
func JackpotGet(rdb *redis.Client, gameId int) int64 {
|
||||
key := fmt.Sprintf("Jackpot:%d", gameId)
|
||||
jp := rdb.Get(context.Background(), key).Val()
|
||||
result, _ := strconv.ParseInt(jp, 10, 64)
|
||||
return result
|
||||
}
|
||||
|
||||
// jp系统池,玩家部分利润进入该池,重置jackpot池时,从这里扣除。系统池反映系统盈亏
|
||||
func JackpotSystemAdd(rdb *redis.Client, gameId int, chips int64) int64 {
|
||||
key := fmt.Sprintf("JackpotSystem:%d", gameId)
|
||||
value, _ := rdb.IncrBy(context.Background(), key, chips).Result()
|
||||
return value
|
||||
}
|
||||
|
||||
func JackpotSystemGet(rdb *redis.Client, gameId int) int64 {
|
||||
key := fmt.Sprintf("JackpotSystem:%d", gameId)
|
||||
jp := rdb.Get(context.Background(), key).Val()
|
||||
result, _ := strconv.ParseInt(jp, 10, 64)
|
||||
return result
|
||||
}
|
||||
|
||||
// 玩家总赎回
|
||||
func JackpotUserRepaidAdd(rdb *redis.Client, gameId int, chips int64) int64 {
|
||||
key := fmt.Sprintf("JackpotUserRepaid:%d", gameId)
|
||||
value, _ := rdb.IncrBy(context.Background(), key, chips).Result()
|
||||
return value
|
||||
}
|
||||
|
||||
// jp池重置次数
|
||||
func JackpotInitCountAdd(rdb *redis.Client, gameId int) int64 {
|
||||
key := fmt.Sprintf("JackpotInitCount:%d", gameId)
|
||||
count, _ := rdb.IncrBy(context.Background(), key, 1).Result()
|
||||
return count
|
||||
}
|
@ -1,264 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"game/common/proto/pb"
|
||||
"game/common/serialization"
|
||||
"game/common/utils"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"gorm.io/gorm"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
TableExpire = 7 * 24 * time.Hour // 七天后过期
|
||||
)
|
||||
|
||||
type iTable interface {
|
||||
GetId() int64
|
||||
TableName() string
|
||||
}
|
||||
|
||||
/*
|
||||
T:Table,如果不想操作redis则将rds设置为nil
|
||||
*/
|
||||
type TableOp[T iTable] struct {
|
||||
db *gorm.DB
|
||||
rds *redis.Client
|
||||
}
|
||||
|
||||
func NewTableOp[T iTable](db *gorm.DB, rds *redis.Client) *TableOp[T] {
|
||||
return &TableOp[T]{db: db, rds: rds}
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) tableName() string {
|
||||
var result utils.TValue[T]
|
||||
return result.V.TableName()
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) redisKey(id int64) string {
|
||||
return fmt.Sprintf("%s:%d", s.tableName(), id)
|
||||
}
|
||||
|
||||
// 查找并返回结构体
|
||||
func (s *TableOp[T]) findByRedis(id int64) *T {
|
||||
maps := s.findByRedisMaps(id)
|
||||
if len(maps) == 0 {
|
||||
return nil
|
||||
}
|
||||
us, err := serialization.MapToStruct[T](maps)
|
||||
if err != nil {
|
||||
log.ErrorF("serialization map to struct err: %v", err)
|
||||
return nil
|
||||
}
|
||||
//log.DebugF("findByRedis redis-key:%v result:%v", s.redisKey(id), us)
|
||||
return us
|
||||
}
|
||||
|
||||
// 查找并返回map
|
||||
func (s *TableOp[T]) findByRedisMaps(id int64) map[string]string {
|
||||
if s.rds == nil {
|
||||
return nil
|
||||
}
|
||||
maps, err := s.rds.HGetAll(context.Background(), s.redisKey(id)).Result()
|
||||
if err != nil {
|
||||
log.ErrorF("redis-key:%v HGetAll err: %v", s.redisKey(id), err)
|
||||
return nil
|
||||
}
|
||||
if len(maps) == 0 {
|
||||
return nil
|
||||
}
|
||||
return maps
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) writeRedis(id int64, t *T) {
|
||||
if s.rds == nil {
|
||||
return
|
||||
}
|
||||
maps := serialization.StructToMap(t)
|
||||
if len(maps) == 0 {
|
||||
log.ErrorF("table struct is empty:%v", s.tableName())
|
||||
}
|
||||
s.updateRedis(id, maps)
|
||||
}
|
||||
|
||||
// 查看在redis中是否存在
|
||||
func (s *TableOp[T]) existRedis(t *T) bool {
|
||||
if s.rds == nil {
|
||||
return false
|
||||
}
|
||||
// 查看redis中是否存在该键
|
||||
exist, _ := s.rds.Exists(context.Background(), s.redisKey((*t).GetId())).Result()
|
||||
return exist == 1
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) updateRedis(id int64, maps map[string]any) {
|
||||
if s.rds == nil {
|
||||
return
|
||||
}
|
||||
if err := s.rds.HMSet(context.Background(), s.redisKey(id), maps).Err(); err != nil {
|
||||
log.ErrorF("redis-key:%v HMSet err: %v", s.redisKey(id), err)
|
||||
}
|
||||
_ = s.rds.Expire(context.Background(), s.redisKey(id), TableExpire).Err()
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) deleteRedis(id int64) {
|
||||
if s.rds == nil {
|
||||
return
|
||||
}
|
||||
_ = s.rds.Del(context.Background(), s.redisKey(id)).Err()
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) Create(t *T) (*T, pb.ErrCode) {
|
||||
if err := s.db.Create(t).Error; err != nil {
|
||||
log.ErrorF("create table:%v err:%v", s.tableName(), err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
s.writeRedis((*t).GetId(), t)
|
||||
return t, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) Find(id int64) (*T, pb.ErrCode) {
|
||||
// 先从redis中查询,redis中没有则从mysql中查询
|
||||
if table := s.findByRedis(id); table != nil {
|
||||
return table, pb.ErrCode_OK
|
||||
}
|
||||
var result utils.TValue[T]
|
||||
err := s.db.Where("id = ?", id).First(&result.V).Error
|
||||
if err != nil {
|
||||
log.DebugF("find table:%v id:%v err:%v", s.tableName(), id, err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
return &result.V, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
// 根据条件查询,只在mysql中查询,无法在redis中查询
|
||||
func (s *TableOp[T]) FindCondition(condition map[string]any) (*T, pb.ErrCode) {
|
||||
us := new(T)
|
||||
err := s.db.Where(condition).First(us).Error
|
||||
if err != nil {
|
||||
log.ErrorF("find table:%v condition:%v err:%v", s.tableName(), utils.JsonMarshal(condition), err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
// 查看redis中是否存在该键,不存在则写入数据
|
||||
if !s.existRedis(us) {
|
||||
s.writeRedis((*us).GetId(), us)
|
||||
}
|
||||
return us, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) Update(id int64, updates map[string]any) (*T, pb.ErrCode) {
|
||||
var result utils.TValue[T]
|
||||
err := s.db.Model(&result.V).Where("id = ?", id).Updates(updates).Error
|
||||
if err != nil {
|
||||
log.ErrorF("update table:%v id:%v err:%v", s.tableName(), id, err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
s.updateRedis(id, updates)
|
||||
return &result.V, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
// 辅助函数:将map的keys转为字符串slice
|
||||
func keysToStringSlice(m map[string]int64) []string {
|
||||
keys := make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// 获取资源
|
||||
func (s *TableOp[T]) GetInt(id int64, resName []string) (map[string]int64, pb.ErrCode) {
|
||||
mapFields := s.findByRedisMaps(id)
|
||||
// 查询更新后的值到map
|
||||
updatedValues := make(map[string]int64)
|
||||
if len(mapFields) != 0 {
|
||||
for _, name := range resName {
|
||||
v, _ := strconv.ParseInt(mapFields[name], 10, 64)
|
||||
updatedValues[name] = v
|
||||
}
|
||||
return updatedValues, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
// redis中没有值,从表中加载并写入redis
|
||||
mapAny := make(map[string]any)
|
||||
err := s.db.Model(new(T)).
|
||||
Where("id = ?", id).
|
||||
Take(&mapAny). // 扫描到map
|
||||
Error
|
||||
|
||||
if err != nil {
|
||||
log.ErrorF("query updated values table:%v id:%v err:%v", s.tableName(), id, err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
s.updateRedis(id, mapAny)
|
||||
|
||||
// 查询更新后的值到map
|
||||
updatedValues = make(map[string]int64)
|
||||
for _, name := range resName {
|
||||
if val, ok := mapAny[name]; ok {
|
||||
var v64 int64
|
||||
switch v := val.(type) {
|
||||
case int64:
|
||||
v64 = v
|
||||
case int, int32, uint, uint32, uint64:
|
||||
v64 = reflect.ValueOf(v).Int()
|
||||
case float32, float64:
|
||||
v64 = int64(reflect.ValueOf(v).Float())
|
||||
default:
|
||||
// 处理无法转换的情况
|
||||
}
|
||||
updatedValues[name] = v64
|
||||
}
|
||||
}
|
||||
return updatedValues, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
// 增加或减少资源
|
||||
func (s *TableOp[T]) AddInt(id int64, res map[string]int64) (map[string]int64, pb.ErrCode) {
|
||||
addRes := map[string]any{}
|
||||
for k, v := range res {
|
||||
addRes[k] = gorm.Expr(fmt.Sprintf("%v + ?", k), v)
|
||||
}
|
||||
var result utils.TValue[T]
|
||||
err := s.db.Model(&result.V).Where("id = ?", id).Updates(addRes).Error
|
||||
if err != nil {
|
||||
log.ErrorF("add table:%v id:%v err:%v", s.tableName(), id, err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
|
||||
// 查询更新后的值到map
|
||||
updatedValues := make(map[string]int64)
|
||||
err = s.db.Model(new(T)).
|
||||
Select(keysToStringSlice(res)). // 只选择需要返回的字段
|
||||
Where("id = ?", id).
|
||||
Take(&updatedValues). // 扫描到map
|
||||
Error
|
||||
|
||||
if err != nil {
|
||||
log.ErrorF("query updated values table:%v id:%v err:%v", s.tableName(), id, err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
|
||||
mapAny := make(map[string]any)
|
||||
for k, v := range updatedValues {
|
||||
mapAny[k] = v
|
||||
}
|
||||
s.updateRedis(id, mapAny)
|
||||
return updatedValues, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) Delete(id int64) (*T, pb.ErrCode) {
|
||||
var result utils.TValue[T]
|
||||
err := s.db.Delete(&result.V, id).Error
|
||||
if err != nil {
|
||||
log.ErrorF("delete table:%v err:%v", s.tableName(), err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
s.deleteRedis(id)
|
||||
return &result.V, pb.ErrCode_OK
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"gorm.io/datatypes"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserLog struct {
|
||||
ID int64 `json:"id"`
|
||||
Nickname string `json:"nickname"` // 昵称
|
||||
AvatarUrl string `json:"avatar_url"` // 头像
|
||||
AvatarFrame string `json:"avatar_frame"` // 头像框
|
||||
Gold int32 `json:"gold"` // 金币
|
||||
}
|
||||
|
||||
type GameRecordLog struct {
|
||||
GameNo string `gorm:"primaryKey;type:String" json:"game_no"`
|
||||
GameId int32 `gorm:"type:Int32;default:0" json:"game_id"`
|
||||
RoomId int32 `gorm:"type:Int32;default:0" json:"room_id"`
|
||||
RoomType int32 `gorm:"type:Int32;default:0" json:"room_type"`
|
||||
StartTime time.Time `gorm:"type:DateTime;default:now()" json:"start_time"` // 开始时间
|
||||
EndTime time.Time `gorm:"type:DateTime;default:now()" json:"end_time"` // 结束时间
|
||||
Users datatypes.JSONType[[]UserLog] `json:"users"`
|
||||
UserTotalBet int64 `gorm:"type:Int64;default:0" json:"user_total_bet"` // 所有玩家总投注额
|
||||
UserTotalNetWin int64 `gorm:"type:Int64;default:0" json:"user_total_net_win"` // 所有玩家总净胜分
|
||||
TotalTax int64 `gorm:"type:Int64;default:0" json:"total_tax"` // 税
|
||||
GameData string `gorm:"type:String" json:"game_data"` // 游戏数据(JSON格式)
|
||||
}
|
||||
|
||||
func (u GameRecordLog) GetId() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (u GameRecordLog) TableName() string {
|
||||
return "game_record_log"
|
||||
}
|
||||
|
||||
func (u GameRecordLog) TableOptions() string {
|
||||
return `ENGINE=MergeTree()
|
||||
ORDER BY (game_no, game_id, room_type)
|
||||
PARTITION BY toYYYYMM(start_time)
|
||||
`
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"gorm.io/datatypes"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserRecordLog struct {
|
||||
GameNo string `gorm:"primaryKey;type:String" json:"game_no"`
|
||||
GameId int32 `gorm:"type:Int32;default:0" json:"game_id"`
|
||||
RoomId int32 `gorm:"type:Int32;default:0" json:"room_id"`
|
||||
RoomType int32 `gorm:"type:Int32;default:0" json:"room_type"`
|
||||
StartTime time.Time `gorm:"type:DateTime;default:now()" json:"start_time"` // 开始时间
|
||||
EndTime time.Time `gorm:"type:DateTime;default:now()" json:"end_time"` // 结束时间
|
||||
Users datatypes.JSONType[UserLog] `json:"user"`
|
||||
TotalBet int64 `gorm:"type:Int64;default:0" json:"total_bet"` // 玩家总投注额
|
||||
TotalNetWin int64 `gorm:"type:Int64;default:0" json:"total_net_win"` // 玩家总净胜分
|
||||
Tax int64 `gorm:"type:Int64;default:0" json:"tax"` // 税
|
||||
GameData string `gorm:"type:String" json:"game_data"` // 游戏数据(JSON格式)
|
||||
}
|
||||
|
||||
func (u UserRecordLog) GetId() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (u UserRecordLog) TableName() string {
|
||||
return "user_record_log"
|
||||
}
|
||||
|
||||
func (u UserRecordLog) TableOptions() string {
|
||||
return `ENGINE=MergeTree()
|
||||
ORDER BY (game_no, game_id, room_type)
|
||||
PARTITION BY toYYYYMM(start_time)
|
||||
`
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package user
|
||||
|
||||
// 玩家账户表
|
||||
type User struct {
|
||||
ID int64 `gorm:"primarykey;autoIncrement" json:"id"`
|
||||
AccountId int64 `gorm:"uniqueIndex;not null" json:"account_id"` // 帐号id
|
||||
Nickname string `gorm:"type:varchar(32);uniqueIndex;not null" json:"nickname"` // 昵称
|
||||
AvatarUrl string `gorm:"type:varchar(255)" json:"avatar_url"` // 头像
|
||||
AvatarFrame string `gorm:"type:varchar(255)" json:"avatar_frame"` // 头像框
|
||||
VipExp int32 `gorm:"type:int" json:"vip_exp"` // vip经验值
|
||||
}
|
||||
|
||||
func (u User) GetId() int64 {
|
||||
return u.ID
|
||||
}
|
||||
|
||||
func (u User) TableName() string {
|
||||
return "user"
|
||||
}
|
||||
|
||||
type GameUser struct {
|
||||
User
|
||||
UserResources
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// AccountNormal = 1 // 正常
|
||||
AccountFrozen = 2 // 冻结
|
||||
AccountBanned = 3 // 封禁
|
||||
)
|
||||
|
||||
// 玩家账户表
|
||||
type UserAccount struct {
|
||||
ID int64 `gorm:"primarykey;autoIncrement" json:"id"`
|
||||
Username string `gorm:"type:varchar(32);uniqueIndex;not null" json:"username"` // 用户名
|
||||
Password string `gorm:"type:varchar(255);not null" json:"password"` // 密码哈希
|
||||
Email string `gorm:"type:varchar(100)" json:"email"` // 邮箱(可选)
|
||||
Phone string `gorm:"type:varchar(20)" json:"phone"` // 手机号(可选)
|
||||
DeviceID string `gorm:"type:varchar(64);index" json:"device_id"` // 设备ID
|
||||
LastLoginIP string `gorm:"type:varchar(45)" json:"last_login_ip"` // 最后登录IP(支持IPv6)
|
||||
LastLoginTime time.Time `json:"last_login_time"` // 最后登录时间
|
||||
Status int `gorm:"type:tinyint;default:1" json:"status"` // 账号状态 1-正常 2-冻结 3-封禁
|
||||
RegisterIP string `gorm:"type:varchar(45)" json:"register_ip"` // 注册IP
|
||||
RegisterTime time.Time `gorm:"type:TIMESTAMP;default:CURRENT_TIMESTAMP" json:"register_time"` // 注册时间
|
||||
}
|
||||
|
||||
func (u UserAccount) GetId() int64 {
|
||||
return u.ID
|
||||
}
|
||||
|
||||
func (u UserAccount) TableName() string {
|
||||
return "user_account"
|
||||
}
|
||||
|
||||
// 玩家登录记录表
|
||||
type UserLoginLog struct {
|
||||
AccountID int64 `gorm:"type:Int64;index" json:"account_id"` // 关联帐号ID
|
||||
LoginIP string `gorm:"type:String;not null" json:"login_ip"` // 登录IP
|
||||
LoginTime time.Time `gorm:"type:DateTime;default:now()" json:"login_time"` // 登录或登出时间
|
||||
IsLogin bool `gorm:"type:Int8" json:"is_login"` // 登录或登出 true-登录 false-登出
|
||||
DeviceInfo string `gorm:"type:String" json:"device_info"` // 设备信息(JSON格式)
|
||||
LoginResult bool `gorm:"type:Int8" json:"login_result"` // 登录结果 true-成功 false-失败
|
||||
FailReason string `gorm:"type:String" json:"fail_reason"` // 失败原因
|
||||
}
|
||||
|
||||
func (u UserLoginLog) GetId() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (u UserLoginLog) TableName() string {
|
||||
return "user_login_log"
|
||||
}
|
||||
|
||||
func (u UserLoginLog) TableOptions() string {
|
||||
// "ENGINE=MergeTree() ORDER BY tuple()"
|
||||
return `ENGINE=MergeTree()
|
||||
ORDER BY (account_id, login_time)
|
||||
PARTITION BY toYYYYMM(login_time)
|
||||
TTL login_time + INTERVAL 6 MONTH
|
||||
`
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package user
|
||||
|
||||
// 玩家账户表
|
||||
type UserResources struct {
|
||||
UID int64 `gorm:"uniqueIndex" json:"uid"`
|
||||
Gold int64 `gorm:"default:0" json:"gold"` // 金币
|
||||
Diamond int64 `gorm:"default:0" json:"diamond"` // 钻石
|
||||
}
|
||||
|
||||
func (u UserResources) GetId() int64 {
|
||||
return u.UID
|
||||
}
|
||||
|
||||
func (u UserResources) TableName() string {
|
||||
return "user_resources"
|
||||
}
|
||||
|
||||
type UserResourcesLog struct {
|
||||
UID int64 `gorm:"uniqueIndex" json:"uid"`
|
||||
ResName string `gorm:"default:0" json:"res_name"` // 资源名
|
||||
ResAddValue int64 `gorm:"default:0" json:"res_value"` // 资源增加值
|
||||
ResAfterValue int64 `gorm:"default:0" json:"res_after_value"` // 资源增加后的值
|
||||
GameId int `gorm:"default:0" json:"game_id"` // 添加资源的玩法id,充值等非玩法操作资源,则为0
|
||||
GameNo string `json:"game_no"` // 游戏局id,同上
|
||||
Reason string `json:"reason"` // 原因
|
||||
}
|
||||
|
||||
func (u UserResourcesLog) GetId() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (u UserResourcesLog) TableName() string {
|
||||
return "user_resources_log"
|
||||
}
|
||||
|
||||
type AddUserRes struct {
|
||||
GameId int `json:"game_id"` // 添加资源的玩法id,充值等非玩法操作资源,则为0
|
||||
GameNo string `json:"game_no"` // 游戏局id,同上
|
||||
Reason string `json:"reason"` // 原因
|
||||
AddRes map[string]int64 `json:"add_res"` // map[资源名]增加值
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user