Commit 74e1d4d3c0ac419d02d97362c0ea6442898d7f39

Authored by 王家文
1 parent bce08317
Exists in master

feat✨:配置管理

Showing 65 changed files with 2067 additions and 1311 deletions   Show diff stats
conf/bytes/abtestcfg.bytes 0 → 100644
No preview for this file type
configs-db/confapi/config.go 0 → 100644
... ... @@ -0,0 +1,48 @@
  1 +package confapi
  2 +
  3 +import (
  4 + "apigame/configs-db/confbase"
  5 + "apigame/service-common/svconst"
  6 + "fmt"
  7 +)
  8 +
  9 +// ApiGameConfig api游戏配置
  10 +type ApiGameConfig struct {
  11 + Raw *Raw
  12 +}
  13 +
  14 +func (c *ApiGameConfig) GetUid() string {
  15 + return c.Raw.GameId
  16 +}
  17 +
  18 +func (c *ApiGameConfig) CheckCurrent() bool {
  19 + return true
  20 +}
  21 +
  22 +func (c *ApiGameConfig) ConfInfo(suffix string) *confbase.ConfInfo {
  23 + tableName := "s_game_config"
  24 + cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix)
  25 + return &confbase.ConfInfo{
  26 + DbMysql: svconst.DbApi,
  27 + TableName: tableName,
  28 + KeyName: "gameid",
  29 + CacheKey: cacheKey,
  30 + CacheCurrent: cacheKey + ":current",
  31 + CacheTime: 300,
  32 + }
  33 +}
  34 +
  35 +// Raw 配置原始数据
  36 +type Raw struct {
  37 + AppId string `gorm:"column:appid"`
  38 + GameId string `gorm:"column:gameid"`
  39 + Secret string `gorm:"column:secret"`
  40 + AppKey string `gorm:"column:appkey"`
  41 + Name string `gorm:"column:name"`
  42 +}
  43 +
  44 +// Decode 解析配置原始数据
  45 +func (c *ApiGameConfig) Decode(gameId string, rawData any) {
  46 + raw := rawData.(*Raw)
  47 + c.Raw = raw
  48 +}
... ...
configs-db/confapi/get.go 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +package confapi
  2 +
  3 +import (
  4 + "apigame/configs-db/confbase"
  5 + "errors"
  6 +)
  7 +
  8 +// GetConfig 获取 api游戏配置
  9 +func GetConfig(gameId string) (conf *ApiGameConfig, err error) {
  10 +
  11 + conf = new(ApiGameConfig)
  12 + has := confbase.GetConfig[*ApiGameConfig, Raw](gameId, gameId, conf)
  13 + if !has {
  14 + err = errors.New("confapi.GetConfig error")
  15 + return
  16 + }
  17 +
  18 + return
  19 +}
... ...
configs-db/confbase/external.go 0 → 100644
... ... @@ -0,0 +1,113 @@
  1 +package confbase
  2 +
  3 +import (
  4 + "apigame/util/util-lx/lxalilog"
  5 + "apigame/util/zjson"
  6 + "apigame/util/zredis"
  7 + "fmt"
  8 + "runtime/debug"
  9 +)
  10 +
  11 +var CacheState = 1 // 0=关闭 1=打开
  12 +
  13 +func SaveCache[T IConfData](gameId string, obj T) {
  14 + info := obj.ConfInfo(gameId)
  15 + _ = zredis.SetEx(info.CacheKey, zjson.Str(obj), info.CacheTime)
  16 +}
  17 +
  18 +func LoadCache[T IConfData](gameId string, obj T) (has bool) {
  19 + if CacheState == 0 {
  20 + return false
  21 + }
  22 + has = true
  23 + info := obj.ConfInfo(gameId)
  24 + text, err := zredis.Get(info.CacheKey)
  25 + if err != nil {
  26 + has = false
  27 + return
  28 + }
  29 + err = zjson.Obj(text, &obj)
  30 + if err != nil {
  31 + fmt.Println(err)
  32 + has = false
  33 + return
  34 + }
  35 + return
  36 +}
  37 +
  38 +func LoadData[T1 IConfData, T2 IConfRawData](gameId string, confId any, obj T1) (has bool) {
  39 + confRaw := new(T2)
  40 + info := obj.ConfInfo(gameId)
  41 + db := info.DbMysql
  42 + result := db.Table(info.TableName).Where(fmt.Sprintf("%s = ?", info.KeyName), confId).First(confRaw)
  43 +
  44 + has = result.RowsAffected != 0
  45 + err := result.Error
  46 + if err != nil {
  47 + lxalilog.Errors(err, "confbase.LoadData error", gameId, confId)
  48 + fmt.Printf("%s", debug.Stack())
  49 + return
  50 + }
  51 + if !has {
  52 + return
  53 + }
  54 +
  55 + obj.Decode(gameId, confRaw)
  56 + return
  57 +}
  58 +
  59 +func FindDuringTime[T1 IConfData, T2 IConfRawData](obj T1, raw *T2, gameId string) (has bool) {
  60 + info := obj.ConfInfo(gameId)
  61 + db := info.DbMysql
  62 + result := db.Table(info.TableName).Where(info.CurrentQuery, info.CurrentArgs...).First(raw)
  63 + has = result.RowsAffected != 0
  64 + return
  65 +}
  66 +
  67 +func GetConfig[T1 IConfData, T2 IConfRawData](gameId string, confId any, obj T1) (has bool) {
  68 + has = LoadCache(gameId, obj)
  69 + if has {
  70 + return
  71 + }
  72 + has = LoadData[T1, T2](gameId, confId, obj)
  73 + if !has {
  74 + return
  75 + }
  76 + SaveCache(gameId, obj)
  77 + return
  78 +}
  79 +
  80 +// GetCurrent 获取 当前配置
  81 +func GetCurrent[T1 IConfData, T2 IConfRawData](gameId string, obj T1) bool {
  82 + has := false
  83 + info := obj.ConfInfo(gameId)
  84 + currentKey := info.CacheCurrent
  85 + currentId := zredis.GetString(currentKey)
  86 + if currentId != "" {
  87 + has = GetConfig[T1, T2](gameId, currentId, obj)
  88 + if has {
  89 + if !obj.CheckCurrent() {
  90 + has = false
  91 + }
  92 + }
  93 + }
  94 + return has
  95 +}
  96 +
  97 +// FindCurrent 查找 当前配置
  98 +func FindCurrent[T1 IConfData, T2 IConfRawData](gameId string, obj T1) bool {
  99 + has := false
  100 + info := obj.ConfInfo(gameId)
  101 + currentKey := info.CacheCurrent
  102 + currentId := zredis.GetString(currentKey)
  103 + confRaw := new(T2)
  104 + has = FindDuringTime[T1, T2](obj, confRaw, gameId)
  105 + if has {
  106 + obj.Decode(gameId, confRaw)
  107 + SaveCache(gameId, obj)
  108 + has = true
  109 + currentId = obj.GetUid()
  110 + _ = zredis.Set(currentKey, currentId)
  111 + }
  112 + return has
  113 +}
... ...
configs-db/confbase/interface.go 0 → 100644
... ... @@ -0,0 +1,31 @@
  1 +package confbase
  2 +
  3 +import "gorm.io/gorm"
  4 +
  5 +// ConfInfo 配置对象信息
  6 +type ConfInfo struct {
  7 + DbMysql *gorm.DB
  8 + TableName string
  9 + KeyName string
  10 + CurrentQuery any
  11 + CurrentArgs []any
  12 + CacheKey string
  13 + CacheCurrent string
  14 + CacheTime int
  15 +}
  16 +
  17 +// IConfData 配置对象
  18 +type IConfData interface {
  19 + // ConfInfo redis存储信息
  20 + ConfInfo(suffix string) *ConfInfo
  21 + // Decode 解码
  22 + Decode(gameId string, rawData any)
  23 + // GetUid 获取keyID
  24 + GetUid() string
  25 + // CheckCurrent 判断当前开放
  26 + CheckCurrent() bool
  27 +}
  28 +
  29 +// IConfRawData mysql存储对象
  30 +type IConfRawData interface {
  31 +}
... ...
configs-db/confcardholder/config.go 0 → 100644
... ... @@ -0,0 +1,152 @@
  1 +package confcardholder
  2 +
  3 +import (
  4 + "apigame/configs-db/confbase"
  5 + "apigame/service-common/svconst"
  6 + "apigame/util/util-lx/lxtime"
  7 + "apigame/util/zconvert"
  8 + "fmt"
  9 +)
  10 +
  11 +// ActivityConfig 卡牌活动配置 分析后数据
  12 +type ActivityConfig struct {
  13 + Raw *ActivityConfigRaw `json:"-"`
  14 +
  15 + Id int64 // ID
  16 + OpenLevel int // 开启等级
  17 + PreviewTime int64 // 预告时间
  18 + StartTime int64 // 开始时间
  19 + EndTime int64 // 结束时间
  20 + Round int // 轮数
  21 + IconPath string // icon资源路径
  22 +
  23 + Awards map[string]string // 奖励配置
  24 + AlbumConfig map[int]AlbumConfig // 卡组配置
  25 + CardConfig map[int]CardConfig // 卡牌配置
  26 + CardholderConfig map[int]OpenCardholderConfig // 卡包开卡规则
  27 + NormalCardStarConfig map[string]NormalCardStarConfig // k=ID_用户序列_用户分组 卡片星级配置
  28 + CardSequenceConfig map[string]CardSequenceConfig // k=ID_用户序列_用户分组 卡片星级对应卡牌配置
  29 + StarShopConfig map[int]StarShopConfig // 星星商店配置
  30 +
  31 + Client *ActivityConfigClient
  32 + GameId string // 所属游戏ID
  33 +}
  34 +
  35 +func (c *ActivityConfig) GetUid() string {
  36 + return zconvert.Int64ToStr(c.Id)
  37 +}
  38 +
  39 +func (c *ActivityConfig) CheckCurrent() bool {
  40 + timeNow := lxtime.NowUninx()
  41 + return timeNow >= c.StartTime && timeNow <= c.EndTime && c.Raw.Status == 1
  42 +}
  43 +
  44 +func (c *ActivityConfig) ConfInfo(suffix string) *confbase.ConfInfo {
  45 + tableName := svconst.MYSQL_TABLE_S_CARDHOLDER_CONFIG
  46 + cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix)
  47 + timeNow := lxtime.NowUninx()
  48 + return &confbase.ConfInfo{
  49 + DbMysql: svconst.DbConfig,
  50 + TableName: fmt.Sprintf("%s_%s", tableName, suffix),
  51 + KeyName: "id",
  52 + CurrentQuery: "status = ? AND start_time <= ? AND end_time >= ?",
  53 + CurrentArgs: []any{1, timeNow, timeNow},
  54 + CacheKey: fmt.Sprintf("%s:%d", cacheKey, c.Id),
  55 + CacheCurrent: cacheKey + ":current",
  56 + CacheTime: 300,
  57 + }
  58 +}
  59 +
  60 +// ActivityConfigRaw 卡牌活动配置 原始数据
  61 +type ActivityConfigRaw struct {
  62 + Id int64 `gorm:"column:id;primaryKey"` // ID
  63 + OpenLevel int // 开启等级
  64 + PreviewTime int64 // 预告时间
  65 + StartTime int64 // 开始时间
  66 + EndTime int64 // 结束时间
  67 + Round int // 轮数
  68 + IconPath string // icon资源路径
  69 +
  70 + Awards string // 奖励配置
  71 + AlbumConfig string // 卡组配置
  72 + CardConfig string // 卡牌配置
  73 + CardHolderConfig string // 卡包开卡规则
  74 + NormalCardStarSequence string // 卡片星级配置
  75 + CardSequenceConfig string // 卡片星级对应卡牌配置
  76 + StarShopConfig string // 星星商店配置
  77 +
  78 + Ver string // 版本号
  79 + Status int // 状态 0=关闭 1=开启
  80 + UpdateTime int64 // 修改时间戳
  81 +}
  82 +
  83 +// ActivityConfigClient 卡牌活动配置 给客户端数据
  84 +type ActivityConfigClient struct {
  85 + Id int64 `form:"id" json:"id"` // ID
  86 + Round int `form:"round" json:"round"` // 轮数
  87 + IconPath string `form:"icon_path" json:"icon_path"` // icon资源路径
  88 + RoundAwards map[string]string `form:"round_awards" json:"round_awards"` // 轮次奖励配置
  89 + Albums []AlbumConfig `form:"albums" json:"albums"` // 卡组配置
  90 + Cards []CardConfig `form:"cards" json:"cards"` // 卡牌配置
  91 + Holders []OpenCardholderConfig `form:"holders" json:"holders"` // 卡包开卡规则
  92 + StarShop []StarShopConfig `form:"star_shop" json:"star_shop"` // 星星商店配置
  93 +}
  94 +
  95 +// AlbumConfig 卡组表
  96 +type AlbumConfig struct {
  97 + SetId int `json:"set_id"` // 卡组名
  98 + Name int `json:"name"` // 卡组图片
  99 + Icon string `json:"icon"` // 卡组id
  100 + Rewards map[string]string `json:"rewards"` // 集齐奖励 k=轮次
  101 + StartTime int64 `json:"start_time"` // 开始时间
  102 + EndTime int64 `json:"end_time"` // 结束时间
  103 +}
  104 +
  105 +// CardConfig 卡牌表
  106 +type CardConfig struct {
  107 + Id int `json:"id"` // ID
  108 + Name int `json:"name"` // 卡牌名字
  109 + Icon string `json:"icon"` // 卡牌图标
  110 + Desc int `json:"desc"` // 卡牌描述
  111 + SetId int `json:"album_setid"` // 卡组id
  112 + Star int `json:"star"` // 星级
  113 + IsGold int `json:"is_gold"` // 是否是金卡
  114 + IsSend int `json:"is_send"` // 卡片是否可赠送
  115 +}
  116 +
  117 +// OpenCardholderConfig 卡包开卡规则表
  118 +type OpenCardholderConfig struct {
  119 + Id int `json:"id"` // ID
  120 + CardPackIcon string `json:"img"` // 卡包资源名
  121 + IsGoldCardholder int `json:"is_gold_card_holder"` // 是否是金卡包
  122 + IsNew int `json:"is_new"` // 是否是新卡包
  123 + GuaranteedStarCardId int `json:"guaranteed_star_card_id"` // 保底卡星级序列ID
  124 + NormalCardNumber int `json:"normal_card_number"` // 非保底卡数量
  125 + MinimumGuaranteeCardId int `json:"minimum_guarantee_card_id"` // 非保底卡牌序列ID
  126 + ActivityId int `json:"activity_id"` // 对应活动ID
  127 + Star int `json:"star"` // star
  128 + Name int `json:"name"` // name
  129 +}
  130 +
  131 +// NormalCardStarConfig 非保底卡星级ID
  132 +type NormalCardStarConfig struct {
  133 + Id int `json:"id"` // ID
  134 + SequenceId int `json:"user_sequence_id"` // 用户序列组ID
  135 + Cohort int `json:"cohort"` // 用户分组
  136 + NormalCardSequenceId []int `json:"normal_card_sequence_id"` // 非保底星级序列
  137 +}
  138 +
  139 +// CardSequenceConfig 星级ID对应的卡片
  140 +type CardSequenceConfig struct {
  141 + Id int `json:"id"` // ID
  142 + SequenceId int `json:"user_sequence_id"` // 用户序列组ID
  143 + Cohort int `json:"cohort"` // 用户分组
  144 + CardIdList []int `json:"card_id_list"` // 卡牌抽取序列
  145 +}
  146 +
  147 +// StarShopConfig 星星商店配置
  148 +type StarShopConfig struct {
  149 + Id int `json:"id"` // ID
  150 + NeedStarNumber int `json:"need_star_number"` // 需求星星数
  151 + CardBagIds string `json:"card_bag_ids"` // 可换取的卡包ID {卡包类型,卡包ID,卡包数量}
  152 +}
... ...
configs-db/confcardholder/decode.go 0 → 100644
... ... @@ -0,0 +1,170 @@
  1 +package confcardholder
  2 +
  3 +import (
  4 + "apigame/util/util-lx/lxalilog"
  5 + "encoding/json"
  6 + "errors"
  7 + "fmt"
  8 +)
  9 +
  10 +// Decode 解析配置原始数据
  11 +func (c *ActivityConfig) Decode(gameId string, rawData any) {
  12 + raw := rawData.(*ActivityConfigRaw)
  13 + c.GameId = gameId
  14 + c.Raw = raw
  15 +
  16 + c.Id = raw.Id
  17 + c.OpenLevel = raw.OpenLevel
  18 + c.PreviewTime = raw.PreviewTime
  19 + c.StartTime = raw.StartTime
  20 + c.EndTime = raw.EndTime
  21 + c.Round = raw.Round
  22 + c.IconPath = raw.IconPath
  23 +
  24 + c.Awards = make(map[string]string)
  25 + c.AlbumConfig = make(map[int]AlbumConfig)
  26 + c.CardConfig = make(map[int]CardConfig)
  27 + c.CardholderConfig = make(map[int]OpenCardholderConfig)
  28 + c.NormalCardStarConfig = make(map[string]NormalCardStarConfig)
  29 + c.CardSequenceConfig = make(map[string]CardSequenceConfig)
  30 + c.StarShopConfig = make(map[int]StarShopConfig)
  31 + // 解析奖励
  32 + {
  33 + err := json.Unmarshal([]byte(raw.Awards), &c.Awards)
  34 + if err != nil {
  35 + lxalilog.Errors(err, raw.Awards, gameId, raw.Id)
  36 + return
  37 + }
  38 + }
  39 + // 卡组配置
  40 + {
  41 + configs := make([]AlbumConfig, 0)
  42 + err := json.Unmarshal([]byte(raw.AlbumConfig), &configs)
  43 + if err != nil {
  44 + lxalilog.Errors(err, raw.AlbumConfig, gameId, raw.Id)
  45 + return
  46 + }
  47 + for _, i2 := range configs {
  48 + c.AlbumConfig[i2.SetId] = i2
  49 + }
  50 + }
  51 + // 卡牌配置
  52 + {
  53 + configs := make([]CardConfig, 0)
  54 + err := json.Unmarshal([]byte(raw.CardConfig), &configs)
  55 + if err != nil {
  56 + lxalilog.Errors(err, raw.CardConfig, gameId, raw.Id)
  57 + return
  58 + }
  59 + for _, i2 := range configs {
  60 + c.CardConfig[i2.Id] = i2
  61 + }
  62 + }
  63 + // 卡包开卡规则
  64 + {
  65 + configs := make([]OpenCardholderConfig, 0)
  66 + err := json.Unmarshal([]byte(raw.CardHolderConfig), &configs)
  67 + if err != nil {
  68 + lxalilog.Errors(err, raw.CardHolderConfig, gameId, raw.Id)
  69 + return
  70 + }
  71 + for _, i2 := range configs {
  72 + c.CardholderConfig[i2.Id] = i2
  73 + }
  74 + }
  75 + // 卡片星级配置
  76 + {
  77 + configs := make([]NormalCardStarConfig, 0)
  78 + err := json.Unmarshal([]byte(raw.NormalCardStarSequence), &configs)
  79 + if err != nil {
  80 + lxalilog.Errors(err, raw.NormalCardStarSequence, gameId, raw.Id)
  81 + return
  82 + }
  83 + for _, i2 := range configs {
  84 + combineId := CombineIdSequenceIdCohort(i2.Id, i2.SequenceId, i2.Cohort)
  85 + c.NormalCardStarConfig[combineId] = i2
  86 + }
  87 + }
  88 + // 卡片星级对应卡牌配置
  89 + {
  90 + configs := make([]CardSequenceConfig, 0)
  91 + err := json.Unmarshal([]byte(raw.CardSequenceConfig), &configs)
  92 + if err != nil {
  93 + lxalilog.Errors(err, raw.CardSequenceConfig, gameId, raw.Id)
  94 + return
  95 + }
  96 + for _, i2 := range configs {
  97 + combineId := CombineIdSequenceIdCohort(i2.Id, i2.SequenceId, i2.Cohort)
  98 + c.CardSequenceConfig[combineId] = i2
  99 + }
  100 + }
  101 + // 星星商店配置
  102 + {
  103 + configs := make([]StarShopConfig, 0)
  104 + err := json.Unmarshal([]byte(raw.StarShopConfig), &configs)
  105 + if err != nil {
  106 + lxalilog.Errors(err, raw.StarShopConfig, gameId, raw.Id)
  107 + return
  108 + }
  109 + for _, i2 := range configs {
  110 + c.StarShopConfig[i2.Id] = i2
  111 + }
  112 + }
  113 +
  114 + c.GenerateConfigClient()
  115 +}
  116 +
  117 +// GenerateConfigClient 生成给客户端的配置
  118 +func (c *ActivityConfig) GenerateConfigClient() {
  119 + configClient := &ActivityConfigClient{
  120 + Id: c.Id,
  121 + Round: c.Round,
  122 + IconPath: c.IconPath,
  123 + RoundAwards: c.Awards,
  124 + Albums: make([]AlbumConfig, 0),
  125 + Cards: make([]CardConfig, 0),
  126 + Holders: make([]OpenCardholderConfig, 0),
  127 + StarShop: make([]StarShopConfig, 0),
  128 + }
  129 + for _, i2 := range c.AlbumConfig {
  130 + configClient.Albums = append(configClient.Albums, i2)
  131 + }
  132 + for _, i2 := range c.CardConfig {
  133 + configClient.Cards = append(configClient.Cards, i2)
  134 + }
  135 + for _, i2 := range c.CardholderConfig {
  136 + configClient.Holders = append(configClient.Holders, i2)
  137 + }
  138 + for _, i2 := range c.StarShopConfig {
  139 + configClient.StarShop = append(configClient.StarShop, i2)
  140 + }
  141 + c.Client = configClient
  142 +}
  143 +
  144 +// CombineIdSequenceIdCohort 组合ID k=ID_用户序列_用户分组
  145 +func CombineIdSequenceIdCohort(id, sequenceId, cohort int) string {
  146 + return fmt.Sprintf("%d_%d_%d", id, sequenceId, cohort)
  147 +}
  148 +
  149 +// FindNormalCardStarConfig 查找配置 非保底卡星级ID
  150 +func (c *ActivityConfig) FindNormalCardStarConfig(id, sequenceId, cohort int) (conf NormalCardStarConfig, has bool) {
  151 + combineId := CombineIdSequenceIdCohort(id, sequenceId, cohort)
  152 + conf, has = c.NormalCardStarConfig[combineId]
  153 + if !has {
  154 + lxalilog.Errors(errors.New("ht_cardholder NormalCardStarConfig error"), id, sequenceId, cohort)
  155 + }
  156 + return
  157 +}
  158 +
  159 +// FindCardSequenceConfig 查找配置 星级ID对应的卡片
  160 +func (c *ActivityConfig) FindCardSequenceConfig(id, sequenceId, cohort int) (conf CardSequenceConfig, has bool) {
  161 + combineId := CombineIdSequenceIdCohort(id, sequenceId, cohort)
  162 + conf, has = c.CardSequenceConfig[combineId]
  163 + if !has {
  164 + lxalilog.Errors(errors.New("ht_cardholder CardSequenceConfig error"), id, sequenceId, cohort)
  165 + fmt.Println(id)
  166 + fmt.Println(sequenceId)
  167 + fmt.Println(cohort)
  168 + }
  169 + return
  170 +}
... ...
configs-db/confcardholder/get.go 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +package confcardholder
  2 +
  3 +import (
  4 + "apigame/configs-db/confbase"
  5 +)
  6 +
  7 +// GetCurrent 获取 当前配置
  8 +func GetCurrent(gameId string) (conf *ActivityConfig, has bool) {
  9 + conf = new(ActivityConfig)
  10 + has = confbase.GetCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf)
  11 + if !has {
  12 + conf = new(ActivityConfig)
  13 + has = confbase.FindCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf)
  14 + }
  15 + return
  16 +}
  17 +
  18 +// GetConfig 获取 配置根据Id
  19 +func GetConfig(gameId string, confId int64) (conf *ActivityConfig, has bool) {
  20 + conf = new(ActivityConfig)
  21 + has = confbase.GetConfig[*ActivityConfig, ActivityConfigRaw](gameId, confId, conf)
  22 +
  23 + return
  24 +}
... ...
configs-db/confglobal/config.go 0 → 100644
... ... @@ -0,0 +1,67 @@
  1 +package confglobal
  2 +
  3 +import (
  4 + "apigame/configs-db/confbase"
  5 + "apigame/service-common/svconst"
  6 + "apigame/util/util-lx/lxalilog"
  7 + "encoding/json"
  8 + "fmt"
  9 +)
  10 +
  11 +// GlobalConfig 全局配置
  12 +type GlobalConfig struct {
  13 + Raw *Raw `json:"-"`
  14 + Names []string
  15 + Avatars []string
  16 + AvatarPath string
  17 +}
  18 +
  19 +func (c *GlobalConfig) GetUid() string {
  20 + return c.Raw.GameId
  21 +}
  22 +
  23 +func (c *GlobalConfig) CheckCurrent() bool {
  24 + return true
  25 +}
  26 +
  27 +func (c *GlobalConfig) ConfInfo(suffix string) *confbase.ConfInfo {
  28 + tableName := "s_game_global_config"
  29 + cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix)
  30 + return &confbase.ConfInfo{
  31 + DbMysql: svconst.DbConfig,
  32 + TableName: tableName,
  33 + KeyName: "gameid",
  34 + CacheKey: cacheKey,
  35 + CacheCurrent: cacheKey + ":current",
  36 + CacheTime: 300,
  37 + }
  38 +}
  39 +
  40 +// Raw 配置原始数据
  41 +type Raw struct {
  42 + GameId string `gorm:"column:gameid"`
  43 + NameConfig string
  44 + AvatarConfig string
  45 + AvatarPath string
  46 +}
  47 +
  48 +// Decode 解析配置原始数据
  49 +func (c *GlobalConfig) Decode(gameId string, rawData any) {
  50 + raw := rawData.(*Raw)
  51 + c.Raw = raw
  52 + {
  53 + err := json.Unmarshal([]byte(raw.NameConfig), &c.Names)
  54 + if err != nil {
  55 + lxalilog.Errors(err, raw.NameConfig, gameId, raw.GameId)
  56 + return
  57 + }
  58 + }
  59 + {
  60 + err := json.Unmarshal([]byte(raw.AvatarConfig), &c.Avatars)
  61 + if err != nil {
  62 + lxalilog.Errors(err, raw.AvatarConfig, gameId, raw.GameId)
  63 + return
  64 + }
  65 + }
  66 + c.AvatarPath = raw.AvatarPath
  67 +}
... ...
configs-db/confglobal/get.go 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +package confglobal
  2 +
  3 +import (
  4 + "apigame/configs-db/confbase"
  5 + "errors"
  6 +)
  7 +
  8 +// GetConfig 获取 api游戏配置
  9 +func GetConfig(gameId string) (conf *GlobalConfig, err error) {
  10 +
  11 + conf = new(GlobalConfig)
  12 + has := confbase.GetConfig[*GlobalConfig, Raw](gameId, gameId, conf)
  13 + if !has {
  14 + err = errors.New("confglobal.GetConfig error")
  15 + return
  16 + }
  17 +
  18 + return
  19 +}
... ...
configs-db/confroomrank/config.go 0 → 100644
... ... @@ -0,0 +1,129 @@
  1 +package confroomrank
  2 +
  3 +import (
  4 + "apigame/configs-db/confbase"
  5 + "apigame/service-common/svconst"
  6 + "apigame/util/util-lx/lxtime"
  7 + "apigame/util/zconvert"
  8 + "fmt"
  9 +)
  10 +
  11 +// ActivityConfig 房间排行活动配置 分析后数据
  12 +type ActivityConfig struct {
  13 + Raw *ActivityConfigRaw `json:"-"`
  14 +
  15 + Id int64 // ID
  16 + Typ int // 排行榜类型
  17 + OpenLevel int // 开启等级
  18 + OpenScore int64 // 开启积分
  19 + PreviewTime int64 // 预告时间
  20 + StartTime int64 // 开始时间
  21 + EndTime int64 // 结束时间
  22 + ReleaseTime string // 结算发奖时间
  23 +
  24 + Robot map[int]RobotConfig // 机器人配置
  25 + Room map[int]RoomConfig // 房间配置
  26 +
  27 + GameId string // 所属游戏ID
  28 +}
  29 +
  30 +func (c *ActivityConfig) GetUid() string {
  31 + return zconvert.Int64ToStr(c.Id)
  32 +}
  33 +
  34 +func (c *ActivityConfig) CheckCurrent() bool {
  35 + timeNow := lxtime.NowUninx()
  36 + return timeNow >= c.StartTime && timeNow <= c.EndTime && c.Raw.Status == 1
  37 +}
  38 +
  39 +func (c *ActivityConfig) ConfInfo(suffix string) *confbase.ConfInfo {
  40 + tableName := svconst.MYSQL_TABLE_S_ROOMRANK_CONFIG
  41 + cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix)
  42 + timeNow := lxtime.NowUninx()
  43 + return &confbase.ConfInfo{
  44 + DbMysql: svconst.DbConfig,
  45 + TableName: fmt.Sprintf("%s_%s", tableName, suffix),
  46 + KeyName: "id",
  47 + CurrentQuery: "typ = ? AND status = ? AND start_time <= ? AND end_time >= ?",
  48 + CurrentArgs: []any{c.Typ, 1, timeNow, timeNow},
  49 + CacheKey: fmt.Sprintf("%s:%d", cacheKey, c.Id),
  50 + CacheCurrent: fmt.Sprintf("%s:%d:current", cacheKey, c.Typ),
  51 + CacheTime: 300,
  52 + }
  53 +}
  54 +
  55 +// ActivityConfigRaw 房间排行活动配置 原始数据
  56 +type ActivityConfigRaw struct {
  57 + Id int64 `gorm:"column:id;primaryKey"` // ID
  58 + Serial int64 // 轮次ID
  59 + Typ int // 排行榜类型
  60 + OpenLevel int // 开启等级
  61 + OpenScore int64 // 开启积分
  62 + PreviewTime int64 // 预告时间
  63 + StartTime int64 // 开始时间
  64 + EndTime int64 // 结束时间
  65 + ReleaseTime string // 结算发奖时间
  66 +
  67 + BootConfig string // 机器人配置
  68 + RoomConfig string // 房间配置
  69 +
  70 + Ver string // 版本号
  71 + Status int // 状态 0=关闭 1=开启
  72 + UpdateTime int64 // 修改时间戳
  73 +}
  74 +
  75 +// GenerateConfigClient 生成给客户端的配置
  76 +func (c *ActivityConfigRaw) GenerateConfigClient() *ActivityConfigClient {
  77 + configClient := &ActivityConfigClient{
  78 + Id: c.Id,
  79 + Typ: c.Typ,
  80 + Serial: c.Serial,
  81 + OpenLevel: c.OpenLevel,
  82 + OpenScore: c.OpenScore,
  83 + PreviewTime: c.PreviewTime,
  84 + StartTime: c.StartTime,
  85 + EndTime: c.EndTime,
  86 + ReleaseTime: c.ReleaseTime,
  87 + Ver: c.Ver,
  88 + Status: c.Status,
  89 + }
  90 + return configClient
  91 +}
  92 +
  93 +// ActivityConfigClient 房间排行活动配置 给客户端数据
  94 +type ActivityConfigClient struct {
  95 + Id int64 `form:"id" json:"id"` // ID
  96 + Typ int `form:"typ" json:"typ"` // 排行榜类型
  97 + Serial int64 `form:"serial" json:"serial"` // 轮次ID
  98 + OpenLevel int `form:"open_level" json:"open_level"` // 开启等级
  99 + OpenScore int64 `form:"open_score" json:"open_score"` // 开启积分
  100 + PreviewTime int64 `form:"preview_time" json:"preview_time"` // 预告时间
  101 + StartTime int64 `form:"start_time" json:"start_time"` // 开始时间
  102 + EndTime int64 `form:"end_time" json:"end_time"` // 结束时间
  103 + ReleaseTime string `form:"release_time" json:"release_time"` // 结算发奖时间
  104 + Ver string `form:"ver" json:"ver"` // 版本号
  105 + Status int `form:"status" json:"status"` // 状态 0=关闭 1=开启
  106 +}
  107 +
  108 +// RobotConfig 机器人配置
  109 +type RobotConfig struct {
  110 + Id int `json:"id"` // id
  111 + MinScore int `json:"min_score"` // 最低分数
  112 + TotalScore int `json:"total_score"` // 总分数
  113 + Range int `json:"range"` // 总分浮动范围(%)
  114 +}
  115 +
  116 +// RoomConfig 房间配置
  117 +type RoomConfig struct {
  118 + Id int `json:"id"` // id
  119 + Levels []int `json:"level_range"` // 等级范围
  120 + UserClass int `json:"rating"` // 评级
  121 + UserScore []int `json:"score_range"` // 分数范围
  122 + TotalPlayer int `json:"room_user_number"` // 房间总人数
  123 + PlayerTypeCount [][]int `json:"user_type_number"` // 玩家类型数量
  124 + AutoRobot []int `json:"auto_room"` // 自动填充机器人
  125 + InitRobot [][]int `json:"disposition_robots"` // 配置机器人
  126 + Awards map[string]string `json:"rewards"` // 奖励
  127 + SettleScores []int `json:"score_adjest"` // 结算分数调整
  128 + SettleUserType []int `json:"user_type"` // 结算用户类型
  129 +}
... ...
configs-db/confroomrank/decode.go 0 → 100644
... ... @@ -0,0 +1,50 @@
  1 +package confroomrank
  2 +
  3 +import (
  4 + "apigame/util/util-lx/lxalilog"
  5 + "encoding/json"
  6 +)
  7 +
  8 +// Decode 解析配置原始数据
  9 +func (c *ActivityConfig) Decode(gameId string, rawData any) {
  10 + raw := rawData.(*ActivityConfigRaw)
  11 + c.GameId = gameId
  12 + c.Raw = raw
  13 +
  14 + c.Id = raw.Id
  15 + c.Typ = raw.Typ
  16 + c.OpenLevel = raw.OpenLevel
  17 + c.OpenScore = raw.OpenScore
  18 + c.PreviewTime = raw.PreviewTime
  19 + c.StartTime = raw.StartTime
  20 + c.EndTime = raw.EndTime
  21 + c.ReleaseTime = raw.ReleaseTime
  22 +
  23 + c.Robot = make(map[int]RobotConfig)
  24 + c.Room = make(map[int]RoomConfig)
  25 +
  26 + // 解析 机器人
  27 + {
  28 + configs := make([]RobotConfig, 0)
  29 + err := json.Unmarshal([]byte(raw.BootConfig), &configs)
  30 + if err != nil {
  31 + lxalilog.Errors(err, raw.BootConfig, gameId, raw.Id)
  32 + return
  33 + }
  34 + for _, i2 := range configs {
  35 + c.Robot[i2.Id] = i2
  36 + }
  37 + }
  38 + // 解析 房间
  39 + {
  40 + configs := make([]RoomConfig, 0)
  41 + err := json.Unmarshal([]byte(raw.RoomConfig), &configs)
  42 + if err != nil {
  43 + lxalilog.Errors(err, raw.RoomConfig, gameId, raw.Id)
  44 + return
  45 + }
  46 + for _, i2 := range configs {
  47 + c.Room[i2.Id] = i2
  48 + }
  49 + }
  50 +}
... ...
configs-db/confroomrank/get.go 0 → 100644
... ... @@ -0,0 +1,44 @@
  1 +package confroomrank
  2 +
  3 +import (
  4 + "apigame/configs-db/confbase"
  5 + "apigame/util/util-lx/lxalilog"
  6 + "apigame/util/util-lx/lxtime"
  7 +)
  8 +
  9 +// GetCurrent 获取 当前配置
  10 +func GetCurrent(gameId string, topType int) (conf *ActivityConfig, has bool) {
  11 + conf = new(ActivityConfig)
  12 + conf.Typ = topType
  13 + has = confbase.GetCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf)
  14 + if !has {
  15 + conf = new(ActivityConfig)
  16 + conf.Typ = topType
  17 + has = confbase.FindCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf)
  18 + }
  19 + return
  20 +}
  21 +
  22 +// GetConfig 获取 配置根据Id
  23 +func GetConfig(gameId string, confId int64) (conf *ActivityConfig, has bool) {
  24 + conf = new(ActivityConfig)
  25 + has = confbase.GetConfig[*ActivityConfig, ActivityConfigRaw](gameId, confId, conf)
  26 +
  27 + return
  28 +}
  29 +
  30 +// GetCurrentConfigs 获取当前配置列表
  31 +func GetCurrentConfigs(gameId string) []*ActivityConfigRaw {
  32 + obj := new(ActivityConfig)
  33 + info := obj.ConfInfo(gameId)
  34 + db := info.DbMysql
  35 + timeNow := lxtime.NowUninx()
  36 + objs := make([]*ActivityConfigRaw, 0)
  37 + result := db.Table(info.TableName).Where(
  38 + "status = ? AND start_time <= ? AND end_time >= ?",
  39 + 1, timeNow, timeNow).Find(&objs)
  40 + if result.Error != nil {
  41 + lxalilog.Errors(result.Error, "confroomrank.GetCurrentConfigs error", gameId)
  42 + }
  43 + return objs
  44 +}
... ...
configs-db/init.go 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +package configs_db
  2 +
  3 +import (
  4 + "apigame/configs-db/confapi"
  5 + "apigame/configs-db/confcardholder"
  6 + "apigame/configs-db/confglobal"
  7 + "apigame/service-common/svconst"
  8 +)
  9 +
  10 +func Init() bool {
  11 +
  12 + for _, gameId := range svconst.GameList {
  13 + _, _ = confapi.GetConfig(gameId)
  14 + }
  15 +
  16 + for _, gameId := range svconst.GameList {
  17 + _, _ = confglobal.GetConfig(gameId)
  18 + }
  19 +
  20 + for _, gameId := range svconst.GameListCardHolder {
  21 + _, _ = confcardholder.GetCurrent(gameId)
  22 + }
  23 +
  24 + //for _, gameId := range svconst.GameListRoomRank {
  25 + // _, _ = confroomrank.GetCurrent(gameId)
  26 + //}
  27 +
  28 + return true
  29 +}
... ...
configs/confapi/config.go
... ... @@ -1,48 +0,0 @@
1   -package confapi
2   -
3   -import (
4   - "apigame/configs/confbase"
5   - "apigame/service-common/svconst"
6   - "fmt"
7   -)
8   -
9   -// ApiGameConfig api游戏配置
10   -type ApiGameConfig struct {
11   - Raw *Raw
12   -}
13   -
14   -func (c *ApiGameConfig) GetUid() string {
15   - return c.Raw.GameId
16   -}
17   -
18   -func (c *ApiGameConfig) CheckCurrent() bool {
19   - return true
20   -}
21   -
22   -func (c *ApiGameConfig) ConfInfo(suffix string) *confbase.ConfInfo {
23   - tableName := "s_game_config"
24   - cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix)
25   - return &confbase.ConfInfo{
26   - DbMysql: svconst.DbApi,
27   - TableName: tableName,
28   - KeyName: "gameid",
29   - CacheKey: cacheKey,
30   - CacheCurrent: cacheKey + ":current",
31   - CacheTime: 300,
32   - }
33   -}
34   -
35   -// Raw 配置原始数据
36   -type Raw struct {
37   - AppId string `gorm:"column:appid"`
38   - GameId string `gorm:"column:gameid"`
39   - Secret string `gorm:"column:secret"`
40   - AppKey string `gorm:"column:appkey"`
41   - Name string `gorm:"column:name"`
42   -}
43   -
44   -// Decode 解析配置原始数据
45   -func (c *ApiGameConfig) Decode(gameId string, rawData any) {
46   - raw := rawData.(*Raw)
47   - c.Raw = raw
48   -}
configs/confapi/get.go
... ... @@ -1,19 +0,0 @@
1   -package confapi
2   -
3   -import (
4   - "apigame/configs/confbase"
5   - "errors"
6   -)
7   -
8   -// GetConfig 获取 api游戏配置
9   -func GetConfig(gameId string) (conf *ApiGameConfig, err error) {
10   -
11   - conf = new(ApiGameConfig)
12   - has := confbase.GetConfig[*ApiGameConfig, Raw](gameId, gameId, conf)
13   - if !has {
14   - err = errors.New("confapi.GetConfig error")
15   - return
16   - }
17   -
18   - return
19   -}
configs/confbase/external.go
... ... @@ -1,113 +0,0 @@
1   -package confbase
2   -
3   -import (
4   - "apigame/util/util-lx/lxalilog"
5   - "apigame/util/zjson"
6   - "apigame/util/zredis"
7   - "fmt"
8   - "runtime/debug"
9   -)
10   -
11   -var CacheState = 1 // 0=关闭 1=打开
12   -
13   -func SaveCache[T IConfData](gameId string, obj T) {
14   - info := obj.ConfInfo(gameId)
15   - _ = zredis.SetEx(info.CacheKey, zjson.Str(obj), info.CacheTime)
16   -}
17   -
18   -func LoadCache[T IConfData](gameId string, obj T) (has bool) {
19   - if CacheState == 0 {
20   - return false
21   - }
22   - has = true
23   - info := obj.ConfInfo(gameId)
24   - text, err := zredis.Get(info.CacheKey)
25   - if err != nil {
26   - has = false
27   - return
28   - }
29   - err = zjson.Obj(text, &obj)
30   - if err != nil {
31   - fmt.Println(err)
32   - has = false
33   - return
34   - }
35   - return
36   -}
37   -
38   -func LoadData[T1 IConfData, T2 IConfRawData](gameId string, confId any, obj T1) (has bool) {
39   - confRaw := new(T2)
40   - info := obj.ConfInfo(gameId)
41   - db := info.DbMysql
42   - result := db.Table(info.TableName).Where(fmt.Sprintf("%s = ?", info.KeyName), confId).First(confRaw)
43   -
44   - has = result.RowsAffected != 0
45   - err := result.Error
46   - if err != nil {
47   - lxalilog.Errors(err, "confbase.LoadData error", gameId, confId)
48   - fmt.Printf("%s", debug.Stack())
49   - return
50   - }
51   - if !has {
52   - return
53   - }
54   -
55   - obj.Decode(gameId, confRaw)
56   - return
57   -}
58   -
59   -func FindDuringTime[T1 IConfData, T2 IConfRawData](obj T1, raw *T2, gameId string) (has bool) {
60   - info := obj.ConfInfo(gameId)
61   - db := info.DbMysql
62   - result := db.Table(info.TableName).Where(info.CurrentQuery, info.CurrentArgs...).First(raw)
63   - has = result.RowsAffected != 0
64   - return
65   -}
66   -
67   -func GetConfig[T1 IConfData, T2 IConfRawData](gameId string, confId any, obj T1) (has bool) {
68   - has = LoadCache(gameId, obj)
69   - if has {
70   - return
71   - }
72   - has = LoadData[T1, T2](gameId, confId, obj)
73   - if !has {
74   - return
75   - }
76   - SaveCache(gameId, obj)
77   - return
78   -}
79   -
80   -// GetCurrent 获取 当前配置
81   -func GetCurrent[T1 IConfData, T2 IConfRawData](gameId string, obj T1) bool {
82   - has := false
83   - info := obj.ConfInfo(gameId)
84   - currentKey := info.CacheCurrent
85   - currentId := zredis.GetString(currentKey)
86   - if currentId != "" {
87   - has = GetConfig[T1, T2](gameId, currentId, obj)
88   - if has {
89   - if !obj.CheckCurrent() {
90   - has = false
91   - }
92   - }
93   - }
94   - return has
95   -}
96   -
97   -// FindCurrent 查找 当前配置
98   -func FindCurrent[T1 IConfData, T2 IConfRawData](gameId string, obj T1) bool {
99   - has := false
100   - info := obj.ConfInfo(gameId)
101   - currentKey := info.CacheCurrent
102   - currentId := zredis.GetString(currentKey)
103   - confRaw := new(T2)
104   - has = FindDuringTime[T1, T2](obj, confRaw, gameId)
105   - if has {
106   - obj.Decode(gameId, confRaw)
107   - SaveCache(gameId, obj)
108   - has = true
109   - currentId = obj.GetUid()
110   - _ = zredis.Set(currentKey, currentId)
111   - }
112   - return has
113   -}
configs/confbase/interface.go
... ... @@ -1,31 +0,0 @@
1   -package confbase
2   -
3   -import "gorm.io/gorm"
4   -
5   -// ConfInfo 配置对象信息
6   -type ConfInfo struct {
7   - DbMysql *gorm.DB
8   - TableName string
9   - KeyName string
10   - CurrentQuery any
11   - CurrentArgs []any
12   - CacheKey string
13   - CacheCurrent string
14   - CacheTime int
15   -}
16   -
17   -// IConfData 配置对象
18   -type IConfData interface {
19   - // ConfInfo redis存储信息
20   - ConfInfo(suffix string) *ConfInfo
21   - // Decode 解码
22   - Decode(gameId string, rawData any)
23   - // GetUid 获取keyID
24   - GetUid() string
25   - // CheckCurrent 判断当前开放
26   - CheckCurrent() bool
27   -}
28   -
29   -// IConfRawData mysql存储对象
30   -type IConfRawData interface {
31   -}
configs/confcardholder/config.go
... ... @@ -1,152 +0,0 @@
1   -package confcardholder
2   -
3   -import (
4   - "apigame/configs/confbase"
5   - "apigame/service-common/svconst"
6   - "apigame/util/util-lx/lxtime"
7   - "apigame/util/utstring"
8   - "fmt"
9   -)
10   -
11   -// ActivityConfig 卡牌活动配置 分析后数据
12   -type ActivityConfig struct {
13   - Raw *ActivityConfigRaw `json:"-"`
14   -
15   - Id int64 // ID
16   - OpenLevel int // 开启等级
17   - PreviewTime int64 // 预告时间
18   - StartTime int64 // 开始时间
19   - EndTime int64 // 结束时间
20   - Round int // 轮数
21   - IconPath string // icon资源路径
22   -
23   - Awards map[string]string // 奖励配置
24   - AlbumConfig map[int]AlbumConfig // 卡组配置
25   - CardConfig map[int]CardConfig // 卡牌配置
26   - CardholderConfig map[int]OpenCardholderConfig // 卡包开卡规则
27   - NormalCardStarConfig map[string]NormalCardStarConfig // k=ID_用户序列_用户分组 卡片星级配置
28   - CardSequenceConfig map[string]CardSequenceConfig // k=ID_用户序列_用户分组 卡片星级对应卡牌配置
29   - StarShopConfig map[int]StarShopConfig // 星星商店配置
30   -
31   - Client *ActivityConfigClient
32   - GameId string // 所属游戏ID
33   -}
34   -
35   -func (c *ActivityConfig) GetUid() string {
36   - return utstring.Int64ToString(c.Id)
37   -}
38   -
39   -func (c *ActivityConfig) CheckCurrent() bool {
40   - timeNow := lxtime.NowUninx()
41   - return timeNow >= c.StartTime && timeNow <= c.EndTime && c.Raw.Status == 1
42   -}
43   -
44   -func (c *ActivityConfig) ConfInfo(suffix string) *confbase.ConfInfo {
45   - tableName := svconst.MYSQL_TABLE_S_CARDHOLDER_CONFIG
46   - cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix)
47   - timeNow := lxtime.NowUninx()
48   - return &confbase.ConfInfo{
49   - DbMysql: svconst.DbConfig,
50   - TableName: fmt.Sprintf("%s_%s", tableName, suffix),
51   - KeyName: "id",
52   - CurrentQuery: "status = ? AND start_time <= ? AND end_time >= ?",
53   - CurrentArgs: []any{1, timeNow, timeNow},
54   - CacheKey: fmt.Sprintf("%s:%d", cacheKey, c.Id),
55   - CacheCurrent: cacheKey + ":current",
56   - CacheTime: 300,
57   - }
58   -}
59   -
60   -// ActivityConfigRaw 卡牌活动配置 原始数据
61   -type ActivityConfigRaw struct {
62   - Id int64 `gorm:"column:id;primaryKey"` // ID
63   - OpenLevel int // 开启等级
64   - PreviewTime int64 // 预告时间
65   - StartTime int64 // 开始时间
66   - EndTime int64 // 结束时间
67   - Round int // 轮数
68   - IconPath string // icon资源路径
69   -
70   - Awards string // 奖励配置
71   - AlbumConfig string // 卡组配置
72   - CardConfig string // 卡牌配置
73   - CardHolderConfig string // 卡包开卡规则
74   - NormalCardStarSequence string // 卡片星级配置
75   - CardSequenceConfig string // 卡片星级对应卡牌配置
76   - StarShopConfig string // 星星商店配置
77   -
78   - Ver string // 版本号
79   - Status int // 状态 0=关闭 1=开启
80   - UpdateTime int64 // 修改时间戳
81   -}
82   -
83   -// ActivityConfigClient 卡牌活动配置 给客户端数据
84   -type ActivityConfigClient struct {
85   - Id int64 `form:"id" json:"id"` // ID
86   - Round int `form:"round" json:"round"` // 轮数
87   - IconPath string `form:"icon_path" json:"icon_path"` // icon资源路径
88   - RoundAwards map[string]string `form:"round_awards" json:"round_awards"` // 轮次奖励配置
89   - Albums []AlbumConfig `form:"albums" json:"albums"` // 卡组配置
90   - Cards []CardConfig `form:"cards" json:"cards"` // 卡牌配置
91   - Holders []OpenCardholderConfig `form:"holders" json:"holders"` // 卡包开卡规则
92   - StarShop []StarShopConfig `form:"star_shop" json:"star_shop"` // 星星商店配置
93   -}
94   -
95   -// AlbumConfig 卡组表
96   -type AlbumConfig struct {
97   - SetId int `json:"set_id"` // 卡组名
98   - Name int `json:"name"` // 卡组图片
99   - Icon string `json:"icon"` // 卡组id
100   - Rewards map[string]string `json:"rewards"` // 集齐奖励 k=轮次
101   - StartTime int64 `json:"start_time"` // 开始时间
102   - EndTime int64 `json:"end_time"` // 结束时间
103   -}
104   -
105   -// CardConfig 卡牌表
106   -type CardConfig struct {
107   - Id int `json:"id"` // ID
108   - Name int `json:"name"` // 卡牌名字
109   - Icon string `json:"icon"` // 卡牌图标
110   - Desc int `json:"desc"` // 卡牌描述
111   - SetId int `json:"album_setid"` // 卡组id
112   - Star int `json:"star"` // 星级
113   - IsGold int `json:"is_gold"` // 是否是金卡
114   - IsSend int `json:"is_send"` // 卡片是否可赠送
115   -}
116   -
117   -// OpenCardholderConfig 卡包开卡规则表
118   -type OpenCardholderConfig struct {
119   - Id int `json:"id"` // ID
120   - CardPackIcon string `json:"img"` // 卡包资源名
121   - IsGoldCardholder int `json:"is_gold_card_holder"` // 是否是金卡包
122   - IsNew int `json:"is_new"` // 是否是新卡包
123   - GuaranteedStarCardId int `json:"guaranteed_star_card_id"` // 保底卡星级序列ID
124   - NormalCardNumber int `json:"normal_card_number"` // 非保底卡数量
125   - MinimumGuaranteeCardId int `json:"minimum_guarantee_card_id"` // 非保底卡牌序列ID
126   - ActivityId int `json:"activity_id"` // 对应活动ID
127   - Star int `json:"star"` // star
128   - Name int `json:"name"` // name
129   -}
130   -
131   -// NormalCardStarConfig 非保底卡星级ID
132   -type NormalCardStarConfig struct {
133   - Id int `json:"id"` // ID
134   - SequenceId int `json:"user_sequence_id"` // 用户序列组ID
135   - Cohort int `json:"cohort"` // 用户分组
136   - NormalCardSequenceId []int `json:"normal_card_sequence_id"` // 非保底星级序列
137   -}
138   -
139   -// CardSequenceConfig 星级ID对应的卡片
140   -type CardSequenceConfig struct {
141   - Id int `json:"id"` // ID
142   - SequenceId int `json:"user_sequence_id"` // 用户序列组ID
143   - Cohort int `json:"cohort"` // 用户分组
144   - CardIdList []int `json:"card_id_list"` // 卡牌抽取序列
145   -}
146   -
147   -// StarShopConfig 星星商店配置
148   -type StarShopConfig struct {
149   - Id int `json:"id"` // ID
150   - NeedStarNumber int `json:"need_star_number"` // 需求星星数
151   - CardBagIds string `json:"card_bag_ids"` // 可换取的卡包ID {卡包类型,卡包ID,卡包数量}
152   -}
configs/confcardholder/decode.go
... ... @@ -1,170 +0,0 @@
1   -package confcardholder
2   -
3   -import (
4   - "apigame/util/util-lx/lxalilog"
5   - "encoding/json"
6   - "errors"
7   - "fmt"
8   -)
9   -
10   -// Decode 解析配置原始数据
11   -func (c *ActivityConfig) Decode(gameId string, rawData any) {
12   - raw := rawData.(*ActivityConfigRaw)
13   - c.GameId = gameId
14   - c.Raw = raw
15   -
16   - c.Id = raw.Id
17   - c.OpenLevel = raw.OpenLevel
18   - c.PreviewTime = raw.PreviewTime
19   - c.StartTime = raw.StartTime
20   - c.EndTime = raw.EndTime
21   - c.Round = raw.Round
22   - c.IconPath = raw.IconPath
23   -
24   - c.Awards = make(map[string]string)
25   - c.AlbumConfig = make(map[int]AlbumConfig)
26   - c.CardConfig = make(map[int]CardConfig)
27   - c.CardholderConfig = make(map[int]OpenCardholderConfig)
28   - c.NormalCardStarConfig = make(map[string]NormalCardStarConfig)
29   - c.CardSequenceConfig = make(map[string]CardSequenceConfig)
30   - c.StarShopConfig = make(map[int]StarShopConfig)
31   - // 解析奖励
32   - {
33   - err := json.Unmarshal([]byte(raw.Awards), &c.Awards)
34   - if err != nil {
35   - lxalilog.Errors(err, raw.Awards, gameId, raw.Id)
36   - return
37   - }
38   - }
39   - // 卡组配置
40   - {
41   - configs := make([]AlbumConfig, 0)
42   - err := json.Unmarshal([]byte(raw.AlbumConfig), &configs)
43   - if err != nil {
44   - lxalilog.Errors(err, raw.AlbumConfig, gameId, raw.Id)
45   - return
46   - }
47   - for _, i2 := range configs {
48   - c.AlbumConfig[i2.SetId] = i2
49   - }
50   - }
51   - // 卡牌配置
52   - {
53   - configs := make([]CardConfig, 0)
54   - err := json.Unmarshal([]byte(raw.CardConfig), &configs)
55   - if err != nil {
56   - lxalilog.Errors(err, raw.CardConfig, gameId, raw.Id)
57   - return
58   - }
59   - for _, i2 := range configs {
60   - c.CardConfig[i2.Id] = i2
61   - }
62   - }
63   - // 卡包开卡规则
64   - {
65   - configs := make([]OpenCardholderConfig, 0)
66   - err := json.Unmarshal([]byte(raw.CardHolderConfig), &configs)
67   - if err != nil {
68   - lxalilog.Errors(err, raw.CardHolderConfig, gameId, raw.Id)
69   - return
70   - }
71   - for _, i2 := range configs {
72   - c.CardholderConfig[i2.Id] = i2
73   - }
74   - }
75   - // 卡片星级配置
76   - {
77   - configs := make([]NormalCardStarConfig, 0)
78   - err := json.Unmarshal([]byte(raw.NormalCardStarSequence), &configs)
79   - if err != nil {
80   - lxalilog.Errors(err, raw.NormalCardStarSequence, gameId, raw.Id)
81   - return
82   - }
83   - for _, i2 := range configs {
84   - combineId := CombineIdSequenceIdCohort(i2.Id, i2.SequenceId, i2.Cohort)
85   - c.NormalCardStarConfig[combineId] = i2
86   - }
87   - }
88   - // 卡片星级对应卡牌配置
89   - {
90   - configs := make([]CardSequenceConfig, 0)
91   - err := json.Unmarshal([]byte(raw.CardSequenceConfig), &configs)
92   - if err != nil {
93   - lxalilog.Errors(err, raw.CardSequenceConfig, gameId, raw.Id)
94   - return
95   - }
96   - for _, i2 := range configs {
97   - combineId := CombineIdSequenceIdCohort(i2.Id, i2.SequenceId, i2.Cohort)
98   - c.CardSequenceConfig[combineId] = i2
99   - }
100   - }
101   - // 星星商店配置
102   - {
103   - configs := make([]StarShopConfig, 0)
104   - err := json.Unmarshal([]byte(raw.StarShopConfig), &configs)
105   - if err != nil {
106   - lxalilog.Errors(err, raw.StarShopConfig, gameId, raw.Id)
107   - return
108   - }
109   - for _, i2 := range configs {
110   - c.StarShopConfig[i2.Id] = i2
111   - }
112   - }
113   -
114   - c.GenerateConfigClient()
115   -}
116   -
117   -// GenerateConfigClient 生成给客户端的配置
118   -func (c *ActivityConfig) GenerateConfigClient() {
119   - configClient := &ActivityConfigClient{
120   - Id: c.Id,
121   - Round: c.Round,
122   - IconPath: c.IconPath,
123   - RoundAwards: c.Awards,
124   - Albums: make([]AlbumConfig, 0),
125   - Cards: make([]CardConfig, 0),
126   - Holders: make([]OpenCardholderConfig, 0),
127   - StarShop: make([]StarShopConfig, 0),
128   - }
129   - for _, i2 := range c.AlbumConfig {
130   - configClient.Albums = append(configClient.Albums, i2)
131   - }
132   - for _, i2 := range c.CardConfig {
133   - configClient.Cards = append(configClient.Cards, i2)
134   - }
135   - for _, i2 := range c.CardholderConfig {
136   - configClient.Holders = append(configClient.Holders, i2)
137   - }
138   - for _, i2 := range c.StarShopConfig {
139   - configClient.StarShop = append(configClient.StarShop, i2)
140   - }
141   - c.Client = configClient
142   -}
143   -
144   -// CombineIdSequenceIdCohort 组合ID k=ID_用户序列_用户分组
145   -func CombineIdSequenceIdCohort(id, sequenceId, cohort int) string {
146   - return fmt.Sprintf("%d_%d_%d", id, sequenceId, cohort)
147   -}
148   -
149   -// FindNormalCardStarConfig 查找配置 非保底卡星级ID
150   -func (c *ActivityConfig) FindNormalCardStarConfig(id, sequenceId, cohort int) (conf NormalCardStarConfig, has bool) {
151   - combineId := CombineIdSequenceIdCohort(id, sequenceId, cohort)
152   - conf, has = c.NormalCardStarConfig[combineId]
153   - if !has {
154   - lxalilog.Errors(errors.New("ht_cardholder NormalCardStarConfig error"), id, sequenceId, cohort)
155   - }
156   - return
157   -}
158   -
159   -// FindCardSequenceConfig 查找配置 星级ID对应的卡片
160   -func (c *ActivityConfig) FindCardSequenceConfig(id, sequenceId, cohort int) (conf CardSequenceConfig, has bool) {
161   - combineId := CombineIdSequenceIdCohort(id, sequenceId, cohort)
162   - conf, has = c.CardSequenceConfig[combineId]
163   - if !has {
164   - lxalilog.Errors(errors.New("ht_cardholder CardSequenceConfig error"), id, sequenceId, cohort)
165   - fmt.Println(id)
166   - fmt.Println(sequenceId)
167   - fmt.Println(cohort)
168   - }
169   - return
170   -}
configs/confcardholder/get.go
... ... @@ -1,24 +0,0 @@
1   -package confcardholder
2   -
3   -import (
4   - "apigame/configs/confbase"
5   -)
6   -
7   -// GetCurrent 获取 当前配置
8   -func GetCurrent(gameId string) (conf *ActivityConfig, has bool) {
9   - conf = new(ActivityConfig)
10   - has = confbase.GetCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf)
11   - if !has {
12   - conf = new(ActivityConfig)
13   - has = confbase.FindCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf)
14   - }
15   - return
16   -}
17   -
18   -// GetConfig 获取 配置根据Id
19   -func GetConfig(gameId string, confId int64) (conf *ActivityConfig, has bool) {
20   - conf = new(ActivityConfig)
21   - has = confbase.GetConfig[*ActivityConfig, ActivityConfigRaw](gameId, confId, conf)
22   -
23   - return
24   -}
configs/confglobal/config.go
... ... @@ -1,67 +0,0 @@
1   -package confglobal
2   -
3   -import (
4   - "apigame/configs/confbase"
5   - "apigame/service-common/svconst"
6   - "apigame/util/util-lx/lxalilog"
7   - "encoding/json"
8   - "fmt"
9   -)
10   -
11   -// GlobalConfig 全局配置
12   -type GlobalConfig struct {
13   - Raw *Raw `json:"-"`
14   - Names []string
15   - Avatars []string
16   - AvatarPath string
17   -}
18   -
19   -func (c *GlobalConfig) GetUid() string {
20   - return c.Raw.GameId
21   -}
22   -
23   -func (c *GlobalConfig) CheckCurrent() bool {
24   - return true
25   -}
26   -
27   -func (c *GlobalConfig) ConfInfo(suffix string) *confbase.ConfInfo {
28   - tableName := "s_game_global_config"
29   - cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix)
30   - return &confbase.ConfInfo{
31   - DbMysql: svconst.DbConfig,
32   - TableName: tableName,
33   - KeyName: "gameid",
34   - CacheKey: cacheKey,
35   - CacheCurrent: cacheKey + ":current",
36   - CacheTime: 300,
37   - }
38   -}
39   -
40   -// Raw 配置原始数据
41   -type Raw struct {
42   - GameId string `gorm:"column:gameid"`
43   - NameConfig string
44   - AvatarConfig string
45   - AvatarPath string
46   -}
47   -
48   -// Decode 解析配置原始数据
49   -func (c *GlobalConfig) Decode(gameId string, rawData any) {
50   - raw := rawData.(*Raw)
51   - c.Raw = raw
52   - {
53   - err := json.Unmarshal([]byte(raw.NameConfig), &c.Names)
54   - if err != nil {
55   - lxalilog.Errors(err, raw.NameConfig, gameId, raw.GameId)
56   - return
57   - }
58   - }
59   - {
60   - err := json.Unmarshal([]byte(raw.AvatarConfig), &c.Avatars)
61   - if err != nil {
62   - lxalilog.Errors(err, raw.AvatarConfig, gameId, raw.GameId)
63   - return
64   - }
65   - }
66   - c.AvatarPath = raw.AvatarPath
67   -}
configs/confglobal/get.go
... ... @@ -1,19 +0,0 @@
1   -package confglobal
2   -
3   -import (
4   - "apigame/configs/confbase"
5   - "errors"
6   -)
7   -
8   -// GetConfig 获取 api游戏配置
9   -func GetConfig(gameId string) (conf *GlobalConfig, err error) {
10   -
11   - conf = new(GlobalConfig)
12   - has := confbase.GetConfig[*GlobalConfig, Raw](gameId, gameId, conf)
13   - if !has {
14   - err = errors.New("confglobal.GetConfig error")
15   - return
16   - }
17   -
18   - return
19   -}
configs/config.go 0 → 100644
... ... @@ -0,0 +1,282 @@
  1 +// DO NOT EDIT!
  2 +// This code is auto generated by go-xlsx-exporter
  3 +// VERSION 1.3
  4 +// go-protobuf v1.27.1
  5 +
  6 +package configs
  7 +
  8 +import (
  9 + reflect "reflect"
  10 + sync "sync"
  11 +
  12 + protoreflect "google.golang.org/protobuf/reflect/protoreflect"
  13 + protoimpl "google.golang.org/protobuf/runtime/protoimpl"
  14 +)
  15 +
  16 +const (
  17 + // Verify that this generated code is sufficiently up-to-date.
  18 + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  19 + // Verify that runtime/protoimpl is sufficiently up-to-date.
  20 + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  21 +)
  22 +
  23 +/* type ConvertHandler func (field string, value interface{}) interface{}
  24 +
  25 +type MessageBase struct {
  26 +
  27 +}
  28 +
  29 +func (item *MessageBase) GetConvertData(field string, value interface{}) {
  30 +
  31 +} */
  32 +// Defined in table: data/abtest.xlsx:abtest;
  33 +type AbTestCfg struct {
  34 + state protoimpl.MessageState
  35 + sizeCache protoimpl.SizeCache
  36 + unknownFields protoimpl.UnknownFields
  37 +
  38 + ID uint32 `protobuf:"varint,1,opt,name=ID,proto3uint32" json:"ID,omitempty"` /** 编号 */
  39 +
  40 + Name string `protobuf:"bytes,2,opt,name=Name,proto3string" json:"Name,omitempty"` /** 分组名 */
  41 +
  42 + Min uint32 `protobuf:"varint,3,opt,name=Min,proto3uint32" json:"Min,omitempty"` /** ID下限 */
  43 +
  44 + Max uint32 `protobuf:"varint,4,opt,name=Max,proto3uint32" json:"Max,omitempty"` /** ID上限 */
  45 +
  46 + Condition string `protobuf:"bytes,5,opt,name=Condition,proto3string" json:"Condition,omitempty"` /** 条件 */
  47 +
  48 + Config string `protobuf:"bytes,6,opt,name=Config,proto3string" json:"Config,omitempty"` /** 配置 */
  49 +
  50 +}
  51 +
  52 +func (x *AbTestCfg) Reset() {
  53 + *x = AbTestCfg{}
  54 + if protoimpl.UnsafeEnabled {
  55 + mi := &file_config_proto_msgTypes[0]
  56 + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  57 + ms.StoreMessageInfo(mi)
  58 + }
  59 +}
  60 +
  61 +func (x *AbTestCfg) String() string {
  62 + return protoimpl.X.MessageStringOf(x)
  63 +}
  64 +
  65 +func (*AbTestCfg) ProtoMessage() {}
  66 +
  67 +func (x *AbTestCfg) ProtoReflect() protoreflect.Message {
  68 + mi := &file_config_proto_msgTypes[0]
  69 + if protoimpl.UnsafeEnabled && x != nil {
  70 + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  71 + if ms.LoadMessageInfo() == nil {
  72 + ms.StoreMessageInfo(mi)
  73 + }
  74 + return ms
  75 + }
  76 + return mi.MessageOf(x)
  77 +}
  78 +
  79 +// Deprecated: Use AbTestCfg.ProtoReflect.Descriptor instead.
  80 +func (*AbTestCfg) Descriptor() ([]byte, []int) {
  81 + return file_config_proto_rawDescGZIP(), []int{0}
  82 +}
  83 +
  84 +func (x *AbTestCfg) GetID() uint32 {
  85 + if x != nil {
  86 + return x.ID
  87 + }
  88 + return 0
  89 +}
  90 +
  91 +func (x *AbTestCfg) GetName() string {
  92 + if x != nil {
  93 + return x.Name
  94 + }
  95 + return ""
  96 +}
  97 +
  98 +func (x *AbTestCfg) GetMin() uint32 {
  99 + if x != nil {
  100 + return x.Min
  101 + }
  102 + return 0
  103 +}
  104 +
  105 +func (x *AbTestCfg) GetMax() uint32 {
  106 + if x != nil {
  107 + return x.Max
  108 + }
  109 + return 0
  110 +}
  111 +
  112 +func (x *AbTestCfg) GetCondition() string {
  113 + if x != nil {
  114 + return x.Condition
  115 + }
  116 + return ""
  117 +}
  118 +
  119 +func (x *AbTestCfg) GetConfig() string {
  120 + if x != nil {
  121 + return x.Config
  122 + }
  123 + return ""
  124 +}
  125 +
  126 +
  127 +// Defined in table: data/abtest.xlsx:abtest;
  128 +type AbTestCfg_ARRAY struct {
  129 + state protoimpl.MessageState
  130 + sizeCache protoimpl.SizeCache
  131 + unknownFields protoimpl.UnknownFields
  132 +
  133 +
  134 + Items []*AbTestCfg `protobuf:"bytes,1,rep,name=Items,proto3*AbTestCfg" json:"Items,omitempty"`
  135 +
  136 +}
  137 +
  138 +func (x *AbTestCfg_ARRAY) Reset() {
  139 + *x = AbTestCfg_ARRAY{}
  140 + if protoimpl.UnsafeEnabled {
  141 + mi := &file_config_proto_msgTypes[1]
  142 + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  143 + ms.StoreMessageInfo(mi)
  144 + }
  145 +}
  146 +
  147 +func (x *AbTestCfg_ARRAY) String() string {
  148 + return protoimpl.X.MessageStringOf(x)
  149 +}
  150 +
  151 +func (*AbTestCfg_ARRAY) ProtoMessage() {}
  152 +
  153 +func (x *AbTestCfg_ARRAY) ProtoReflect() protoreflect.Message {
  154 + mi := &file_config_proto_msgTypes[1]
  155 + if protoimpl.UnsafeEnabled && x != nil {
  156 + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  157 + if ms.LoadMessageInfo() == nil {
  158 + ms.StoreMessageInfo(mi)
  159 + }
  160 + return ms
  161 + }
  162 + return mi.MessageOf(x)
  163 +}
  164 +
  165 +// Deprecated: Use AbTestCfg_ARRAY.ProtoReflect.Descriptor instead.
  166 +func (*AbTestCfg_ARRAY) Descriptor() ([]byte, []int) {
  167 + return file_config_proto_rawDescGZIP(), []int{1}
  168 +}
  169 +
  170 +func (x *AbTestCfg_ARRAY) GetItems() []*AbTestCfg {
  171 + if x != nil {
  172 + return x.Items
  173 + }
  174 + return nil
  175 +}
  176 +
  177 +
  178 +var File_config_proto protoreflect.FileDescriptor
  179 +
  180 +var file_config_proto_rawDesc = []byte{
  181 +0x0a,0x0c,0x63,0x6f,0x6e,0x66,0x69,0x67,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x12,0x07,
  182 +0x63,0x6f,0x6e,0x66,0x69,0x67,0x73,0x22,0x89,0x01,0x0a,0x09,0x41,0x62,0x54,0x65,
  183 +0x73,0x74,0x43,0x66,0x67,0x12,0x0e,0x0a,0x02,0x49,0x44,0x18,0x01,0x20,0x01,0x28,
  184 +0x0d,0x52,0x02,0x49,0x44,0x12,0x12,0x0a,0x04,0x4e,0x61,0x6d,0x65,0x18,0x02,0x20,
  185 +0x01,0x28,0x09,0x52,0x04,0x4e,0x61,0x6d,0x65,0x12,0x10,0x0a,0x03,0x4d,0x69,0x6e,
  186 +0x18,0x03,0x20,0x01,0x28,0x0d,0x52,0x03,0x4d,0x69,0x6e,0x12,0x10,0x0a,0x03,0x4d,
  187 +0x61,0x78,0x18,0x04,0x20,0x01,0x28,0x0d,0x52,0x03,0x4d,0x61,0x78,0x12,0x1c,0x0a,
  188 +0x09,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x18,0x05,0x20,0x01,0x28,0x09,
  189 +0x52,0x09,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x12,0x16,0x0a,0x06,0x43,
  190 +0x6f,0x6e,0x66,0x69,0x67,0x18,0x06,0x20,0x01,0x28,0x09,0x52,0x06,0x43,0x6f,0x6e,
  191 +0x66,0x69,0x67,0x22,0x3b,0x0a,0x0f,0x41,0x62,0x54,0x65,0x73,0x74,0x43,0x66,0x67,
  192 +0x5f,0x41,0x52,0x52,0x41,0x59,0x12,0x28,0x0a,0x05,0x49,0x74,0x65,0x6d,0x73,0x18,
  193 +0x01,0x20,0x03,0x28,0x0b,0x32,0x12,0x2e,0x63,0x6f,0x6e,0x66,0x69,0x67,0x73,0x2e,
  194 +0x41,0x62,0x54,0x65,0x73,0x74,0x43,0x66,0x67,0x52,0x05,0x49,0x74,0x65,0x6d,0x73,
  195 +0x62,0x06,0x70,0x72,0x6f,0x74,0x6f,0x33,
  196 +}
  197 +
  198 +var (
  199 + file_config_proto_rawDescOnce sync.Once
  200 + file_config_proto_rawDescData = file_config_proto_rawDesc
  201 +)
  202 +
  203 +func file_config_proto_rawDescGZIP() []byte {
  204 + file_config_proto_rawDescOnce.Do(func() {
  205 + file_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_config_proto_rawDescData)
  206 + })
  207 + return file_config_proto_rawDescData
  208 +}
  209 +
  210 +var file_config_proto_enumTypes = make([]protoimpl.EnumInfo, 0)
  211 +var file_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
  212 +var file_config_proto_goTypes = []interface{}{
  213 + (*AbTestCfg)(nil), // 0: configs.AbTestCfg
  214 + (*AbTestCfg_ARRAY)(nil), // 1: configs.AbTestCfg_ARRAY
  215 +
  216 +}
  217 +
  218 +var file_config_proto_depIdxs = []int32{
  219 + 0, // 0: configs.AbTestCfg_ARRAY:type_name -> configs.AbTestCfg
  220 +1, // [1:1] is the sub-list for method output_type
  221 +1, // [1:1] is the sub-list for method input_type
  222 +1, // [1:1] is the sub-list for extension type_name
  223 +1, // [1:1] is the sub-list for extension extendee
  224 +0, // [0:1] is the sub-list for field type_name
  225 +}
  226 +
  227 +func file_config_proto_init() {
  228 + if File_config_proto != nil {
  229 + return
  230 + }
  231 + if !protoimpl.UnsafeEnabled {
  232 + file_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
  233 + switch v := v.(*AbTestCfg); i {
  234 + case 0:
  235 + return &v.state
  236 + case 1:
  237 + return &v.sizeCache
  238 + case 2:
  239 + return &v.unknownFields
  240 + default:
  241 + return nil
  242 + }
  243 + }
  244 +
  245 + file_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
  246 + switch v := v.(*AbTestCfg_ARRAY); i {
  247 + case 0:
  248 + return &v.state
  249 + case 1:
  250 + return &v.sizeCache
  251 + case 2:
  252 + return &v.unknownFields
  253 + default:
  254 + return nil
  255 + }
  256 + }
  257 +
  258 + }
  259 + type x struct{}
  260 + out := protoimpl.TypeBuilder{
  261 + File: protoimpl.DescBuilder{
  262 + GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
  263 + RawDescriptor: file_config_proto_rawDesc,
  264 + NumEnums: 0,
  265 + NumMessages: 2,
  266 + NumExtensions: 0,
  267 + NumServices: 0,
  268 + },
  269 + GoTypes: file_config_proto_goTypes,
  270 + DependencyIndexes: file_config_proto_depIdxs,
  271 + EnumInfos: file_config_proto_enumTypes,
  272 + MessageInfos: file_config_proto_msgTypes,
  273 + }.Build()
  274 + File_config_proto = out.File
  275 + file_config_proto_rawDesc = nil
  276 + file_config_proto_goTypes = nil
  277 + file_config_proto_depIdxs = nil
  278 +}
  279 +
  280 +func init() {
  281 + file_config_proto_init()
  282 +}
0 283 \ No newline at end of file
... ...
configs/confroomrank/config.go
... ... @@ -1,129 +0,0 @@
1   -package confroomrank
2   -
3   -import (
4   - "apigame/configs/confbase"
5   - "apigame/service-common/svconst"
6   - "apigame/util/util-lx/lxtime"
7   - "apigame/util/utstring"
8   - "fmt"
9   -)
10   -
11   -// ActivityConfig 房间排行活动配置 分析后数据
12   -type ActivityConfig struct {
13   - Raw *ActivityConfigRaw `json:"-"`
14   -
15   - Id int64 // ID
16   - Typ int // 排行榜类型
17   - OpenLevel int // 开启等级
18   - OpenScore int64 // 开启积分
19   - PreviewTime int64 // 预告时间
20   - StartTime int64 // 开始时间
21   - EndTime int64 // 结束时间
22   - ReleaseTime string // 结算发奖时间
23   -
24   - Robot map[int]RobotConfig // 机器人配置
25   - Room map[int]RoomConfig // 房间配置
26   -
27   - GameId string // 所属游戏ID
28   -}
29   -
30   -func (c *ActivityConfig) GetUid() string {
31   - return utstring.Int64ToString(c.Id)
32   -}
33   -
34   -func (c *ActivityConfig) CheckCurrent() bool {
35   - timeNow := lxtime.NowUninx()
36   - return timeNow >= c.StartTime && timeNow <= c.EndTime && c.Raw.Status == 1
37   -}
38   -
39   -func (c *ActivityConfig) ConfInfo(suffix string) *confbase.ConfInfo {
40   - tableName := svconst.MYSQL_TABLE_S_ROOMRANK_CONFIG
41   - cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix)
42   - timeNow := lxtime.NowUninx()
43   - return &confbase.ConfInfo{
44   - DbMysql: svconst.DbConfig,
45   - TableName: fmt.Sprintf("%s_%s", tableName, suffix),
46   - KeyName: "id",
47   - CurrentQuery: "typ = ? AND status = ? AND start_time <= ? AND end_time >= ?",
48   - CurrentArgs: []any{c.Typ, 1, timeNow, timeNow},
49   - CacheKey: fmt.Sprintf("%s:%d", cacheKey, c.Id),
50   - CacheCurrent: fmt.Sprintf("%s:%d:current", cacheKey, c.Typ),
51   - CacheTime: 300,
52   - }
53   -}
54   -
55   -// ActivityConfigRaw 房间排行活动配置 原始数据
56   -type ActivityConfigRaw struct {
57   - Id int64 `gorm:"column:id;primaryKey"` // ID
58   - Serial int64 // 轮次ID
59   - Typ int // 排行榜类型
60   - OpenLevel int // 开启等级
61   - OpenScore int64 // 开启积分
62   - PreviewTime int64 // 预告时间
63   - StartTime int64 // 开始时间
64   - EndTime int64 // 结束时间
65   - ReleaseTime string // 结算发奖时间
66   -
67   - BootConfig string // 机器人配置
68   - RoomConfig string // 房间配置
69   -
70   - Ver string // 版本号
71   - Status int // 状态 0=关闭 1=开启
72   - UpdateTime int64 // 修改时间戳
73   -}
74   -
75   -// GenerateConfigClient 生成给客户端的配置
76   -func (c *ActivityConfigRaw) GenerateConfigClient() *ActivityConfigClient {
77   - configClient := &ActivityConfigClient{
78   - Id: c.Id,
79   - Typ: c.Typ,
80   - Serial: c.Serial,
81   - OpenLevel: c.OpenLevel,
82   - OpenScore: c.OpenScore,
83   - PreviewTime: c.PreviewTime,
84   - StartTime: c.StartTime,
85   - EndTime: c.EndTime,
86   - ReleaseTime: c.ReleaseTime,
87   - Ver: c.Ver,
88   - Status: c.Status,
89   - }
90   - return configClient
91   -}
92   -
93   -// ActivityConfigClient 房间排行活动配置 给客户端数据
94   -type ActivityConfigClient struct {
95   - Id int64 `form:"id" json:"id"` // ID
96   - Typ int `form:"typ" json:"typ"` // 排行榜类型
97   - Serial int64 `form:"serial" json:"serial"` // 轮次ID
98   - OpenLevel int `form:"open_level" json:"open_level"` // 开启等级
99   - OpenScore int64 `form:"open_score" json:"open_score"` // 开启积分
100   - PreviewTime int64 `form:"preview_time" json:"preview_time"` // 预告时间
101   - StartTime int64 `form:"start_time" json:"start_time"` // 开始时间
102   - EndTime int64 `form:"end_time" json:"end_time"` // 结束时间
103   - ReleaseTime string `form:"release_time" json:"release_time"` // 结算发奖时间
104   - Ver string `form:"ver" json:"ver"` // 版本号
105   - Status int `form:"status" json:"status"` // 状态 0=关闭 1=开启
106   -}
107   -
108   -// RobotConfig 机器人配置
109   -type RobotConfig struct {
110   - Id int `json:"id"` // id
111   - MinScore int `json:"min_score"` // 最低分数
112   - TotalScore int `json:"total_score"` // 总分数
113   - Range int `json:"range"` // 总分浮动范围(%)
114   -}
115   -
116   -// RoomConfig 房间配置
117   -type RoomConfig struct {
118   - Id int `json:"id"` // id
119   - Levels []int `json:"level_range"` // 等级范围
120   - UserClass int `json:"rating"` // 评级
121   - UserScore []int `json:"score_range"` // 分数范围
122   - TotalPlayer int `json:"room_user_number"` // 房间总人数
123   - PlayerTypeCount [][]int `json:"user_type_number"` // 玩家类型数量
124   - AutoRobot []int `json:"auto_room"` // 自动填充机器人
125   - InitRobot [][]int `json:"disposition_robots"` // 配置机器人
126   - Awards map[string]string `json:"rewards"` // 奖励
127   - SettleScores []int `json:"score_adjest"` // 结算分数调整
128   - SettleUserType []int `json:"user_type"` // 结算用户类型
129   -}
configs/confroomrank/decode.go
... ... @@ -1,50 +0,0 @@
1   -package confroomrank
2   -
3   -import (
4   - "apigame/util/util-lx/lxalilog"
5   - "encoding/json"
6   -)
7   -
8   -// Decode 解析配置原始数据
9   -func (c *ActivityConfig) Decode(gameId string, rawData any) {
10   - raw := rawData.(*ActivityConfigRaw)
11   - c.GameId = gameId
12   - c.Raw = raw
13   -
14   - c.Id = raw.Id
15   - c.Typ = raw.Typ
16   - c.OpenLevel = raw.OpenLevel
17   - c.OpenScore = raw.OpenScore
18   - c.PreviewTime = raw.PreviewTime
19   - c.StartTime = raw.StartTime
20   - c.EndTime = raw.EndTime
21   - c.ReleaseTime = raw.ReleaseTime
22   -
23   - c.Robot = make(map[int]RobotConfig)
24   - c.Room = make(map[int]RoomConfig)
25   -
26   - // 解析 机器人
27   - {
28   - configs := make([]RobotConfig, 0)
29   - err := json.Unmarshal([]byte(raw.BootConfig), &configs)
30   - if err != nil {
31   - lxalilog.Errors(err, raw.BootConfig, gameId, raw.Id)
32   - return
33   - }
34   - for _, i2 := range configs {
35   - c.Robot[i2.Id] = i2
36   - }
37   - }
38   - // 解析 房间
39   - {
40   - configs := make([]RoomConfig, 0)
41   - err := json.Unmarshal([]byte(raw.RoomConfig), &configs)
42   - if err != nil {
43   - lxalilog.Errors(err, raw.RoomConfig, gameId, raw.Id)
44   - return
45   - }
46   - for _, i2 := range configs {
47   - c.Room[i2.Id] = i2
48   - }
49   - }
50   -}
configs/confroomrank/get.go
... ... @@ -1,44 +0,0 @@
1   -package confroomrank
2   -
3   -import (
4   - "apigame/configs/confbase"
5   - "apigame/util/util-lx/lxalilog"
6   - "apigame/util/util-lx/lxtime"
7   -)
8   -
9   -// GetCurrent 获取 当前配置
10   -func GetCurrent(gameId string, topType int) (conf *ActivityConfig, has bool) {
11   - conf = new(ActivityConfig)
12   - conf.Typ = topType
13   - has = confbase.GetCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf)
14   - if !has {
15   - conf = new(ActivityConfig)
16   - conf.Typ = topType
17   - has = confbase.FindCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf)
18   - }
19   - return
20   -}
21   -
22   -// GetConfig 获取 配置根据Id
23   -func GetConfig(gameId string, confId int64) (conf *ActivityConfig, has bool) {
24   - conf = new(ActivityConfig)
25   - has = confbase.GetConfig[*ActivityConfig, ActivityConfigRaw](gameId, confId, conf)
26   -
27   - return
28   -}
29   -
30   -// GetCurrentConfigs 获取当前配置列表
31   -func GetCurrentConfigs(gameId string) []*ActivityConfigRaw {
32   - obj := new(ActivityConfig)
33   - info := obj.ConfInfo(gameId)
34   - db := info.DbMysql
35   - timeNow := lxtime.NowUninx()
36   - objs := make([]*ActivityConfigRaw, 0)
37   - result := db.Table(info.TableName).Where(
38   - "status = ? AND start_time <= ? AND end_time >= ?",
39   - 1, timeNow, timeNow).Find(&objs)
40   - if result.Error != nil {
41   - lxalilog.Errors(result.Error, "confroomrank.GetCurrentConfigs error", gameId)
42   - }
43   - return objs
44   -}
configs/external.go 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +package configs
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 +)
  7 +
  8 +func Init() bool {
  9 + fmt.Println("configs Init")
  10 + Initial("./conf/bytes", "ID")
  11 +
  12 + //InitExt()
  13 + return true
  14 +}
  15 +
  16 +func GetConfig[T any](id string, t T) (obj *T) {
  17 + var table = GetTable(t)
  18 + dt := table.GetItem(id)
  19 + if dt == nil {
  20 + return nil
  21 + }
  22 + obj = dt.(*T)
  23 + return
  24 +}
  25 +
  26 +func HasConfig[T any](id string, t T) (has bool) {
  27 + var table = GetTable(t)
  28 + return table.GetItem(id) != nil
  29 +}
  30 +
  31 +func GetOne[T any](t T) (obj *T) {
  32 + var table = GetTable(t)
  33 + if len(table.Items()) > 0 {
  34 + return table.Items()[0].(*T)
  35 + }
  36 + return nil
  37 +}
  38 +
  39 +func GetTable[T any](t T) (table *DataTable) {
  40 + table = GetDataTable(reflect.TypeOf(t))
  41 + return
  42 +}
... ...
configs/init.go
... ... @@ -1,29 +0,0 @@
1   -package configs
2   -
3   -import (
4   - "apigame/configs/confapi"
5   - "apigame/configs/confcardholder"
6   - "apigame/configs/confglobal"
7   - "apigame/service-common/svconst"
8   -)
9   -
10   -func Init() bool {
11   -
12   - for _, gameId := range svconst.GameList {
13   - _, _ = confapi.GetConfig(gameId)
14   - }
15   -
16   - for _, gameId := range svconst.GameList {
17   - _, _ = confglobal.GetConfig(gameId)
18   - }
19   -
20   - for _, gameId := range svconst.GameListCardHolder {
21   - _, _ = confcardholder.GetCurrent(gameId)
22   - }
23   -
24   - //for _, gameId := range svconst.GameListRoomRank {
25   - // _, _ = confroomrank.GetCurrent(gameId)
26   - //}
27   -
28   - return true
29   -}
configs/reader.go 0 → 100644
... ... @@ -0,0 +1,280 @@
  1 +package configs
  2 +
  3 +import (
  4 + "fmt"
  5 + "os"
  6 + "reflect"
  7 + "strings"
  8 +
  9 + "google.golang.org/protobuf/proto"
  10 + "google.golang.org/protobuf/reflect/protoreflect"
  11 + "google.golang.org/protobuf/reflect/protoregistry"
  12 +)
  13 +
  14 +type DataTableMap map[string]IData
  15 +type DataItemMap map[string]IData
  16 +
  17 +type DataArray []interface{}
  18 +type DataMap map[string]interface{}
  19 +
  20 +var (
  21 + DefaultIndexKey = "ID"
  22 + BytesFileExt = ".bytes"
  23 +
  24 + dataDir = ""
  25 + dataItemMap = make(DataItemMap, 0)
  26 + dataTableMap = make(DataTableMap, 0)
  27 +)
  28 +
  29 +type IFilenameGenerator interface {
  30 + GetFilename(typeName string) string
  31 +}
  32 +
  33 +type IData interface {
  34 + DataType() reflect.Type
  35 +}
  36 +
  37 +func DataDir() string {
  38 + return dataDir
  39 +}
  40 +
  41 +func Initial(dir, defaultKeyName string) {
  42 + dataDir = strings.ReplaceAll(dir, "\\", "/")
  43 + if strings.LastIndex(dataDir, "/") != len(dataDir)-1 {
  44 + dataDir = dataDir + "/"
  45 + }
  46 +
  47 + if defaultKeyName != "" {
  48 + DefaultIndexKey = defaultKeyName
  49 + }
  50 +}
  51 +
  52 +func RegistDataTable(indexKey string, dataType reflect.Type) {
  53 + if _, ok := dataTableMap[dataType.Name()]; !ok {
  54 + var t = NewDataTable(indexKey, dataType)
  55 + dataTableMap[dataType.Name()] = t
  56 + }
  57 +}
  58 +
  59 +func RegistDataTableExt(table IData) {
  60 + var dataType = table.DataType()
  61 + if _, ok := dataTableMap[dataType.Name()]; !ok {
  62 + dataTableMap[dataType.Name()] = table
  63 + }
  64 +}
  65 +
  66 +func GetDataItem(dataType reflect.Type) *DataItem {
  67 + var dt *DataItem
  68 + if item, ok := dataItemMap[dataType.Name()]; !ok {
  69 + var t = NewDataItem(dataType)
  70 + dataItemMap[dataType.Name()] = t
  71 + dt = t
  72 + } else {
  73 + dt = item.(*DataItem)
  74 + }
  75 + return dt
  76 +}
  77 +
  78 +func GetDataTable(dataType reflect.Type) *DataTable {
  79 + var dt *DataTable
  80 + if item, ok := dataTableMap[dataType.Name()]; !ok {
  81 + var t = NewDataTable("", dataType)
  82 + dataTableMap[dataType.Name()] = t
  83 + dt = t
  84 + } else {
  85 + dt = item.(*DataTable)
  86 + }
  87 + return dt
  88 +}
  89 +
  90 +func getFullname(dataType reflect.Type) string {
  91 + var pkgs = strings.Split(dataType.PkgPath(), "/")
  92 + var pkg = pkgs[len(pkgs)-1]
  93 + var name = dataType.Name()
  94 + return fmt.Sprintf("%s.%s", pkg, name)
  95 +}
  96 +
  97 +type DataItem struct {
  98 + dataType reflect.Type
  99 + data interface{}
  100 + fileGen IFilenameGenerator
  101 +}
  102 +
  103 +func NewDataItem(dataType reflect.Type) *DataItem {
  104 + t := new(DataItem)
  105 + t.dataType = dataType
  106 + t.fileGen = t
  107 + return t
  108 +}
  109 +
  110 +func (t *DataItem) DataType() reflect.Type {
  111 + return t.dataType
  112 +}
  113 +
  114 +func (t *DataItem) Item() interface{} {
  115 + t.load()
  116 + return t.data
  117 +}
  118 +
  119 +func (t *DataItem) Clear() {
  120 + t.data = nil
  121 +}
  122 +
  123 +func (t *DataItem) GetFilename(typeName string) string {
  124 + return fmt.Sprintf("%s%s%s", dataDir, strings.ToLower(typeName), BytesFileExt)
  125 +}
  126 +
  127 +func (t *DataItem) load() {
  128 + if t.data != nil {
  129 + return
  130 + }
  131 +
  132 + var filename = t.fileGen.GetFilename(t.dataType.Name())
  133 + if ok, _ := PathExists(filename); !ok {
  134 + fmt.Printf("can not find data file %s", filename)
  135 + return
  136 + }
  137 +
  138 + fullName := getFullname(t.dataType)
  139 + msgName := protoreflect.FullName(fullName)
  140 + msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName)
  141 + if err != nil {
  142 + fmt.Printf("can not find proto message named %v, %v", fullName, err)
  143 + return
  144 + }
  145 + message := msgType.New().Interface()
  146 +
  147 + bytes, err := os.ReadFile(filename)
  148 + if err != nil {
  149 + fmt.Printf("read bytes file failed, %v", err)
  150 + return
  151 + }
  152 +
  153 + err = proto.Unmarshal(bytes, message)
  154 + if err != nil {
  155 + fmt.Printf("proto unmarshal failed, %v", err)
  156 + return
  157 + }
  158 +
  159 + t.data = message
  160 +}
  161 +
  162 +type DataTable struct {
  163 + indexKey string
  164 + dataType reflect.Type
  165 + data DataArray
  166 + dataMap DataMap
  167 + fileGen IFilenameGenerator
  168 +}
  169 +
  170 +func NewDataTable(indexKey string, dataType reflect.Type) *DataTable {
  171 + if indexKey == "" {
  172 + indexKey = DefaultIndexKey
  173 + }
  174 +
  175 + t := new(DataTable)
  176 + t.indexKey = indexKey
  177 + t.dataType = dataType
  178 + t.fileGen = t
  179 + return t
  180 +}
  181 +
  182 +func (t *DataTable) DataType() reflect.Type {
  183 + return t.dataType
  184 +}
  185 +
  186 +func (t *DataTable) Items() DataArray {
  187 + if t.data == nil {
  188 + t.load()
  189 + }
  190 + return t.data
  191 +}
  192 +
  193 +func (t *DataTable) ItemsMap() DataMap {
  194 + if t.data == nil {
  195 + t.load()
  196 + }
  197 + t.itemsAsMap()
  198 + return t.dataMap
  199 +}
  200 +
  201 +func (t *DataTable) GetItem(id string) interface{} {
  202 + var dataMap = t.ItemsMap()
  203 + if dt, ok := dataMap[id]; ok {
  204 + return dt
  205 + }
  206 + return nil
  207 +}
  208 +
  209 +func (t *DataTable) Clear() {
  210 + t.data = nil
  211 + t.dataMap = nil
  212 +}
  213 +
  214 +func (t *DataTable) GetFilename(typeName string) string {
  215 + return fmt.Sprintf("%s%s%s", dataDir, strings.ToLower(typeName), BytesFileExt)
  216 +}
  217 +
  218 +func (t *DataTable) load() {
  219 + if t.data != nil {
  220 + return
  221 + }
  222 +
  223 + var filename = t.fileGen.GetFilename(t.dataType.Name())
  224 + if ok, _ := PathExists(filename); !ok {
  225 + fmt.Printf("can not find data file %s", filename)
  226 + return
  227 + }
  228 +
  229 + fullName := getFullname(t.dataType) + "_ARRAY"
  230 + msgName := protoreflect.FullName(fullName)
  231 + msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName)
  232 + if err != nil {
  233 + fmt.Printf("can not find proto message named %v, %v", fullName, err)
  234 + return
  235 + }
  236 + message := msgType.New().Interface()
  237 +
  238 + bytes, err := os.ReadFile(filename)
  239 + if err != nil {
  240 + fmt.Printf("read bytes file failed, %v", err)
  241 + return
  242 + }
  243 +
  244 + err = proto.Unmarshal(bytes, message)
  245 + if err != nil {
  246 + fmt.Printf("proto unmarshal failed, %v", err)
  247 + return
  248 + }
  249 +
  250 + var value = reflect.ValueOf(message)
  251 + var elm = value.Elem()
  252 + if elm.Kind() != reflect.Struct {
  253 + fmt.Printf("type %s kind error", fullName)
  254 + return
  255 + }
  256 +
  257 + t.data = make(DataArray, 0)
  258 + var items = elm.FieldByName("Items").Interface()
  259 + if reflect.TypeOf(items).Kind() == reflect.Slice {
  260 + s := reflect.ValueOf(items)
  261 + for i := 0; i < s.Len(); i++ {
  262 + ele := s.Index(i)
  263 + t.data = append(t.data, ele.Interface())
  264 + }
  265 + }
  266 +}
  267 +
  268 +func (t *DataTable) itemsAsMap() {
  269 + if t.dataMap != nil {
  270 + return
  271 + }
  272 + t.dataMap = make(DataMap)
  273 +
  274 + for _, item := range t.data {
  275 + var value = reflect.ValueOf(item)
  276 + var elm = value.Elem()
  277 + var idx = elm.FieldByName(t.indexKey).Interface()
  278 + t.dataMap[fmt.Sprintf("%v", idx)] = item
  279 + }
  280 +}
... ...
configs/utils.go 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +package configs
  2 +
  3 +import "os"
  4 +
  5 +func PathExists(path string) (bool, error) {
  6 + _, err := os.Stat(path)
  7 + if err == nil {
  8 + return true, nil
  9 + }
  10 + if os.IsNotExist(err) {
  11 + return false, nil
  12 + }
  13 + return false, err
  14 +}
... ...
controllers/admin.go
1 1 package controllers
2 2  
3 3 import (
4   - "apigame/configs/confbase"
  4 + "apigame/configs-db/confbase"
5 5 "apigame/models"
6 6 "apigame/service/code-msg"
7 7 )
... ...
controllers/demo.go
1 1 package controllers
2 2  
3 3 import (
  4 + "apigame/configs"
4 5 "apigame/models"
5 6 "apigame/service/code-msg"
6   - "apigame/util/util-lx/lxalilog"
  7 + "apigame/util/zjson"
7 8 "encoding/json"
8 9 "fmt"
9 10 )
... ... @@ -23,7 +24,7 @@ func (c *DemoController) Demo() {
23 24  
24 25 fmt.Println("DemoController.demo")
25 26  
26   - lxalilog.Errors("DemoController.demo")
  27 + //lxalilog.Errors("DemoController.demo")
27 28  
28 29 //{
29 30 // gameId := "10149"
... ... @@ -42,6 +43,14 @@ func (c *DemoController) Demo() {
42 43 // fmt.Println(conf)
43 44 // }
44 45 //}
  46 + {
  47 + cs := configs.GetTable(configs.AbTestCfg{}).Items()
  48 + //for _, dt := range cs {
  49 + // conf := dt.(*configs.AbTestCfg)
  50 + // fmt.Println(conf)
  51 + //}
  52 + fmt.Println("cs", zjson.Str(cs))
  53 + }
45 54  
46 55 c.RetRspCodeData(code_msg.RECODE_OK, rsp)
47 56 }
... ...
go.mod
... ... @@ -10,9 +10,12 @@ require (
10 10 github.com/garyburd/redigo v1.6.4
11 11 github.com/go-sql-driver/mysql v1.7.0
12 12 github.com/gomodule/redigo v2.0.0+incompatible
  13 + github.com/google/uuid v1.6.0
13 14 github.com/lixu-any/go-tools v0.0.0-20221128094643-07d54c69e9bf
14 15 github.com/mitchellh/mapstructure v1.1.2
  16 + github.com/redis/go-redis/v9 v9.0.3
15 17 github.com/samber/lo v1.39.0
  18 + google.golang.org/protobuf v1.25.0
16 19 gorm.io/driver/mysql v1.5.6
17 20 gorm.io/gorm v1.25.9
18 21 )
... ... @@ -26,7 +29,6 @@ require (
26 29 github.com/go-logfmt/logfmt v0.5.0 // indirect
27 30 github.com/gogo/protobuf v1.3.2 // indirect
28 31 github.com/golang/protobuf v1.4.2 // indirect
29   - github.com/google/uuid v1.6.0 // indirect
30 32 github.com/hashicorp/golang-lru v0.5.4 // indirect
31 33 github.com/jinzhu/inflection v1.0.0 // indirect
32 34 github.com/jinzhu/now v1.1.5 // indirect
... ... @@ -37,7 +39,6 @@ require (
37 39 github.com/prometheus/client_model v0.2.0 // indirect
38 40 github.com/prometheus/common v0.10.0 // indirect
39 41 github.com/prometheus/procfs v0.1.3 // indirect
40   - github.com/redis/go-redis/v9 v9.0.3 // indirect
41 42 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect
42 43 go.uber.org/atomic v1.5.0 // indirect
43 44 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
... ... @@ -47,7 +48,6 @@ require (
47 48 golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
48 49 golang.org/x/text v0.3.7 // indirect
49 50 golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023 // indirect
50   - google.golang.org/protobuf v1.25.0 // indirect
51 51 gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
52 52 gopkg.in/yaml.v2 v2.2.8 // indirect
53 53 )
... ...
main.go
... ... @@ -2,6 +2,7 @@ package main
2 2  
3 3 import (
4 4 "apigame/configs"
  5 + "apigame/configs-db"
5 6 _ "apigame/routers"
6 7 "apigame/service"
7 8 "apigame/service-common/svconst"
... ... @@ -65,6 +66,10 @@ func Init() bool {
65 66 //
66 67 //_ = config.InitLxLimit()
67 68  
  69 + if !configs_db.Init() {
  70 + return false
  71 + }
  72 +
68 73 if !configs.Init() {
69 74 return false
70 75 }
... ...
middleware/sign/index.go
1 1 package sign
2 2  
3 3 import (
4   - "apigame/configs/confapi"
  4 + "apigame/configs-db/confapi"
5 5 "apigame/middleware/sdk"
6 6 "apigame/service/code-msg"
7 7 "apigame/util/util-lx/lxalilog"
... ...
service-common/svcommon/simulate.go
1 1 package svcommon
2 2  
3 3 import (
4   - "apigame/configs/confglobal"
5   - "apigame/util/utmisc"
  4 + "apigame/configs-db/confglobal"
  5 + "apigame/util/zmisc"
6 6 "math/rand"
7 7 )
8 8  
... ... @@ -24,7 +24,7 @@ func GetIndexNames(gameId string, amount int) []int {
24 24 if err == nil {
25 25 count := len(config.Names)
26 26 if count > 0 {
27   - return utmisc.RandomMultiple(amount, 0, count)
  27 + return zmisc.RandomMultiple(amount, 0, count)
28 28 }
29 29 }
30 30 return list
... ...
service-common/svredis/index.go
... ... @@ -3,7 +3,7 @@ package svredis
3 3 import (
4 4 "apigame/service-common/svconst"
5 5 "apigame/util/util-lx/lxredis"
6   - "apigame/util/utstring"
  6 + "apigame/util/zconvert"
7 7 "apigame/util/zjson"
8 8 "apigame/util/zredis"
9 9 "apigame/util/zredislock"
... ... @@ -33,7 +33,7 @@ func Init() bool {
33 33  
34 34 // 初始化Redis
35 35 {
36   - zredis.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, utstring.StringToInt(confRedis.Db))
  36 + zredis.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, zconvert.ToInt(confRedis.Db))
37 37 if !zredis.Check() {
38 38 return false
39 39 }
... ... @@ -43,7 +43,7 @@ func Init() bool {
43 43  
44 44 // 初始化redis锁
45 45 {
46   - zredislock.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, utstring.StringToInt(confRedis.Db))
  46 + zredislock.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, zconvert.ToInt(confRedis.Db))
47 47 fmt.Println(svconst.AppName + " zredislock init success")
48 48 }
49 49  
... ...
service/cardholder/handle.go
1 1 package cardholder
2 2  
3 3 import (
4   - "apigame/configs/confcardholder"
  4 + "apigame/configs-db/confcardholder"
5 5 "apigame/models"
6 6 "apigame/service-common/svmysql"
7 7 "apigame/service/code-msg"
8 8 "apigame/util/util-lx/lxalilog"
9 9 "apigame/util/util-lx/lxtime"
10   - "apigame/util/utslice"
11   - "apigame/util/utstring"
  10 + "apigame/util/zconvert"
  11 + "apigame/util/zslice"
12 12 )
13 13  
14 14 // HandleGetConfig 活动配置
... ... @@ -112,7 +112,7 @@ func HandleOpen(req *models.ReqCardHolderOpen) (code string, rsp models.RspCardH
112 112 sequenceId, cohort,
113 113 openMode)
114 114 // 打乱顺序
115   - utslice.Shuffle(newCards)
  115 + zslice.Shuffle(newCards)
116 116 for _, i3 := range newCards {
117 117 allNewCards = append(allNewCards, i3)
118 118 }
... ... @@ -268,7 +268,7 @@ func HandleShopExchange(req *models.ReqStarShopExchange) (code string, rsp model
268 268  
269 269 // 从配置里拿到卡包ID和数量列表
270 270 cardholderIdCount := make(map[int]int)
271   - cardholderIdCountList := utstring.StringToListListInt(confStarShop.CardBagIds, "|", ",")
  271 + cardholderIdCountList := zconvert.ToListListInt(confStarShop.CardBagIds, "|", ",")
272 272 for _, i2 := range cardholderIdCountList {
273 273 if len(i2) >= 3 {
274 274 cardholderIdCount[i2[1]] = i2[2]
... ... @@ -292,7 +292,7 @@ func HandleShopExchange(req *models.ReqStarShopExchange) (code string, rsp model
292 292 sequenceId, cohort,
293 293 openMode)
294 294 // 打乱顺序
295   - utslice.Shuffle(newCards)
  295 + zslice.Shuffle(newCards)
296 296 for _, i3 := range newCards {
297 297 allNewCards = append(allNewCards, i3)
298 298 }
... ... @@ -314,7 +314,7 @@ func HandleShopExchange(req *models.ReqStarShopExchange) (code string, rsp model
314 314 // 存档
315 315 SavePlayer(gameId, player)
316 316  
317   - utslice.Shuffle(rsp.NewCards)
  317 + zslice.Shuffle(rsp.NewCards)
318 318  
319 319 // 返回信息
320 320 rsp.CardHolderInfo = GetInfo(player, config)
... ... @@ -374,7 +374,7 @@ func HandleAutoExchangeInfo(req *models.ReqAutoExchangeInfo) (code string, rsp m
374 374 // 存档
375 375 SavePlayer(gameId, player)
376 376  
377   - utslice.Shuffle(rsp.NewCards)
  377 + zslice.Shuffle(rsp.NewCards)
378 378  
379 379 // 返回信息
380 380 rsp.CardHolderInfo = GetInfo(player, config)
... ...
service/cardholder/logic.go
1 1 package cardholder
2 2  
3 3 import (
4   - "apigame/configs/confcardholder"
  4 + "apigame/configs-db/confcardholder"
5 5 "apigame/models"
6 6 "apigame/service-common/svmysql"
7 7 "apigame/service/code-msg"
8 8 "apigame/util/util-lx/lxalilog"
9 9 "apigame/util/util-lx/lxtime"
10   - "apigame/util/utslice"
11   - "apigame/util/utstring"
  10 + "apigame/util/zconvert"
12 11 "apigame/util/zjson"
  12 + "apigame/util/zslice"
13 13 "github.com/samber/lo"
14 14 "math"
15 15 "sort"
... ... @@ -241,7 +241,7 @@ func DoOpenCheckAward(gameId string,
241 241 }
242 242 // 集齐处理发奖
243 243 player.Details.Album[albumId] += 1
244   - award := confAlbum.Rewards[utstring.IntToString(player.Details.Round)]
  244 + award := confAlbum.Rewards[zconvert.IntToStr(player.Details.Round)]
245 245 awardAlbum[albumId] = award
246 246 {
247 247 // 记录日志
... ... @@ -254,7 +254,7 @@ func DoOpenCheckAward(gameId string,
254 254 // 判断 处理 发放轮次奖励 轮次完成
255 255 if CheckRoundFinish(player, config) {
256 256 // 返回奖励
257   - awardRound = config.Awards[utstring.IntToString(player.Details.Round)]
  257 + awardRound = config.Awards[zconvert.IntToStr(player.Details.Round)]
258 258  
259 259 // 记录日志
260 260 recordBase := NewRecordBase(player.Uid, sequenceId, cohort, config.Id, player.Details.Round)
... ... @@ -395,7 +395,7 @@ func NextActivityAutoExchange(gameId string, player *Player, config *confcardhol
395 395 sequenceId, cohort,
396 396 openMode)
397 397 // 打乱顺序
398   - utslice.Shuffle(newCards)
  398 + zslice.Shuffle(newCards)
399 399 for _, i3 := range newCards {
400 400 allNewCards = append(allNewCards, i3)
401 401 }
... ...
service/cardholder/player.go
1 1 package cardholder
2 2  
3 3 import (
4   - "apigame/configs/confcardholder"
  4 + "apigame/configs-db/confcardholder"
5 5 "apigame/service-common/svmysql"
6 6 "apigame/util/util-lx/lxalilog"
7 7 "apigame/util/util-lx/lxtime"
... ...
service/roomrank/handle.go
1 1 package roomrank
2 2  
3 3 import (
4   - "apigame/configs/confroomrank"
  4 + "apigame/configs-db/confroomrank"
5 5 "apigame/models"
6 6 "apigame/service/code-msg"
7 7 "apigame/util/util-lx/lxtime"
... ...
service/roomrank/logic.go
1 1 package roomrank
2 2  
3 3 import (
4   - "apigame/configs/confroomrank"
  4 + "apigame/configs-db/confroomrank"
5 5 "apigame/service-common/svconst"
6 6 "apigame/util/util-lx/lxtime"
7   - "apigame/util/utstring"
  7 + "apigame/util/zconvert"
8 8 "apigame/util/ztime"
9 9 "fmt"
10 10 "time"
... ... @@ -91,7 +91,7 @@ func TrySettle(gameId string, topType int, player *Player) (hasChange bool) {
91 91 if !hasConfRoom {
92 92 return
93 93 }
94   - if confAward, hasConfAward := confRoom.Awards[utstring.IntToString(player.SettleRank)]; hasConfAward {
  94 + if confAward, hasConfAward := confRoom.Awards[zconvert.IntToStr(player.SettleRank)]; hasConfAward {
95 95 player.SettleAward = confAward
96 96 }
97 97 if len(confRoom.SettleScores) > rankIndex {
... ...
service/roomrank/player.go
1 1 package roomrank
2 2  
3 3 import (
4   - "apigame/configs/confroomrank"
  4 + "apigame/configs-db/confroomrank"
5 5 "apigame/models"
6 6 "apigame/service-common/svcommon"
7 7 "apigame/service-common/svmysql"
8 8 "apigame/util/util-lx/lxalilog"
9 9 "apigame/util/util-lx/lxtime"
10   - "apigame/util/utstring"
  10 + "apigame/util/zconvert"
11 11 )
12 12  
13 13 func tryInitPlayer(gameId string, player *Player) {
... ... @@ -118,7 +118,7 @@ func GetInfoFromRoom(gameId string, player *Player, room *Room, config *confroom
118 118 IsRobot: p.IsRobot(),
119 119 }
120 120 if confRoom, hasConfRoom := config.Room[room.ConfigId]; hasConfRoom {
121   - if confAward, hasConfAward := confRoom.Awards[utstring.IntToString(rank)]; hasConfAward {
  121 + if confAward, hasConfAward := confRoom.Awards[zconvert.IntToStr(rank)]; hasConfAward {
122 122 node.Award = confAward
123 123 }
124 124 }
... ...
service/roomrank/room.go
1 1 package roomrank
2 2  
3 3 import (
4   - "apigame/configs/confroomrank"
  4 + "apigame/configs-db/confroomrank"
5 5 "apigame/service-common/svcommon"
6 6 "apigame/service-common/svmysql"
7 7 "apigame/util/util-lx/lxalilog"
... ...
util/utmap/map.go
... ... @@ -1,66 +0,0 @@
1   -package utmap
2   -
3   -import (
4   - "apigame/util/uttype"
5   - "math/rand"
6   -)
7   -
8   -// Keys Keys切片
9   -func Keys[T1 comparable, T2 any](dict map[T1]T2) []T1 {
10   - list := make([]T1, 0)
11   - for k, _ := range dict {
12   - list = append(list, k)
13   - }
14   - return list
15   -}
16   -
17   -// Values Values切片
18   -func Values[T1 comparable, T2 any](dict map[T1]T2) []T2 {
19   - list := make([]T2, 0)
20   - for _, v := range dict {
21   - list = append(list, v)
22   - }
23   - return list
24   -}
25   -
26   -// ContainValue 值等于
27   -func ContainValue[T1 comparable, T2 comparable](dict map[T1]T2, value T2) bool {
28   - for _, v := range dict {
29   - if v == value {
30   - return true
31   - }
32   - }
33   - return false
34   -}
35   -
36   -// ContainValueEquals 值等于
37   -func ContainValueEquals[T1 comparable, T2 uttype.EqualAble](dict map[T1]T2, value T2) bool {
38   - for _, v := range dict {
39   - if v.Equals(value) {
40   - return true
41   - }
42   - }
43   - return false
44   -}
45   -
46   -// ContainValueBy 值符合
47   -func ContainValueBy[T1 comparable, T2 any](dict map[T1]T2, value T2, equals func(v1 T2, v2 T2) bool) bool {
48   - for _, v := range dict {
49   - if equals(v, value) {
50   - return true
51   - }
52   - }
53   - return false
54   -}
55   -
56   -// RandomOne 随机一个值
57   -func RandomOne[T1 comparable, T2 any](dict map[T1]T2) T2 {
58   - if len(dict) <= 0 {
59   - return *new(T2)
60   - }
61   - list := make([]T1, 0)
62   - for i, _ := range dict {
63   - list = append(list, i)
64   - }
65   - return dict[list[rand.Intn(len(list))]]
66   -}
util/utmisc/goroutine.go
... ... @@ -1,15 +0,0 @@
1   -package utmisc
2   -
3   -import (
4   - "fmt"
5   - "runtime"
6   -)
7   -
8   -// GetGoroutineID 获取携程ID
9   -func GetGoroutineID() int {
10   - var buf [64]byte
11   - runtime.Stack(buf[:], false)
12   - var id int
13   - fmt.Sscanf(string(buf[:]), "goroutine %d", &id)
14   - return id
15   -}
util/utmisc/random.go
... ... @@ -1,21 +0,0 @@
1   -package utmisc
2   -
3   -import "math/rand"
4   -
5   -func RandomMultiple(count, minNum, maxNum int) []int {
6   - list := make([]int, 0)
7   - if maxNum > minNum {
8   - if count > maxNum-minNum {
9   - count = maxNum - minNum
10   - }
11   - m := make(map[int]struct{})
12   - for len(m) < count {
13   - v := minNum + rand.Intn(maxNum-minNum)
14   - if _, ok := m[v]; !ok {
15   - m[v] = struct{}{}
16   - list = append(list, v)
17   - }
18   - }
19   - }
20   - return list
21   -}
util/utslice/slice.go
... ... @@ -1,161 +0,0 @@
1   -package utslice
2   -
3   -import (
4   - "apigame/util/uttype"
5   - "math/rand"
6   -)
7   -
8   -// Contains 判断切片是否包含某元素
9   -func Contains[T comparable](list []T, value T) bool {
10   - for _, v := range list {
11   - if v == value {
12   - return true
13   - }
14   - }
15   - return false
16   -}
17   -
18   -// RandomOne 随机一个元素
19   -func RandomOne[T any](list []T) T {
20   - if len(list) <= 0 {
21   - return *new(T)
22   - }
23   - return list[rand.Intn(len(list))]
24   -}
25   -
26   -// Remove 切片删除一个元素
27   -func Remove[T comparable](list []T, item T) []T {
28   - for i := 0; i < len(list); i++ {
29   - if item == list[i] {
30   - list = append(list[:i], list[i+1:]...)
31   - i = i - 1
32   - }
33   - }
34   - return list
35   -}
36   -
37   -// RemoveList 切片删除多个元素
38   -func RemoveList[T comparable](list []T, items []T) []T {
39   - dMap := make(map[T]bool)
40   - for _, s := range items {
41   - dMap[s] = true
42   - }
43   -
44   - for i := 0; i < len(list); i++ {
45   - if _, ok := dMap[list[i]]; ok {
46   - list = append(list[:i], list[i+1:]...)
47   - i = i - 1
48   - }
49   - }
50   - return list
51   -}
52   -
53   -// Sum 求和
54   -func Sum[T uttype.UtNumber](list []T) T {
55   - var result T = 0
56   - for _, v := range list {
57   - result += v
58   - }
59   - return result
60   -}
61   -
62   -// Any 其中有一个元素符合就返回true
63   -func Any[T uttype.UtNumber](list []T, value T) bool {
64   - for _, v := range list {
65   - if v == value {
66   - return true
67   - }
68   - }
69   - return false
70   -}
71   -
72   -// AnyEquals 其中有一个元素符合就返回true
73   -func AnyEquals[T uttype.EqualAble](list []T, value T) bool {
74   - for _, v := range list {
75   - if v.Equals(value) {
76   - return true
77   - }
78   - }
79   - return false
80   -}
81   -
82   -// AnyBy 其中有一个元素符合就返回true
83   -func AnyBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) bool {
84   - for _, v := range list {
85   - if equals(v, value) {
86   - return true
87   - }
88   - }
89   - return false
90   -}
91   -
92   -// All 所有元素符合就返回true
93   -func All[T uttype.UtNumber](list []T, value T) bool {
94   - for _, v := range list {
95   - if v != value {
96   - return false
97   - }
98   - }
99   - return true
100   -}
101   -
102   -// AllEquals 所有元素符合就返回true
103   -func AllEquals[T uttype.EqualAble](list []T, value T) bool {
104   - for _, v := range list {
105   - if !v.Equals(value) {
106   - return false
107   - }
108   - }
109   - return true
110   -}
111   -
112   -// AllBy 所有元素符合就返回true
113   -func AllBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) bool {
114   - for _, v := range list {
115   - if !equals(v, value) {
116   - return false
117   - }
118   - }
119   - return true
120   -}
121   -
122   -// Filter 过滤
123   -func Filter[T comparable](list []T, value T) []T {
124   - result := make([]T, 0)
125   - for _, v := range list {
126   - if v == value {
127   - result = append(result, v)
128   - }
129   - }
130   - return result
131   -}
132   -
133   -// FilterEquals 过滤
134   -func FilterEquals[T uttype.EqualAble](list []T, value T) []T {
135   - result := make([]T, 0)
136   - for _, v := range list {
137   - if v.Equals(value) {
138   - result = append(result, v)
139   - }
140   - }
141   - return result
142   -}
143   -
144   -// FilterBy 过滤
145   -func FilterBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) []T {
146   - result := make([]T, 0)
147   - for _, v := range list {
148   - if equals(v, value) {
149   - result = append(result, v)
150   - }
151   - }
152   - return result
153   -}
154   -
155   -// Shuffle 打乱
156   -func Shuffle[T any](list []T) {
157   - for i := len(list) - 1; i > 0; i-- {
158   - j := rand.Intn(i + 1)
159   - list[i], list[j] = list[j], list[i]
160   - }
161   -}
util/utstring/list.go
... ... @@ -1,51 +0,0 @@
1   -package utstring
2   -
3   -import "strings"
4   -
5   -func ListStringToListInt(list []string) []int {
6   - result := make([]int, 0)
7   - for _, v := range list {
8   - result = append(result, StringToInt(v))
9   - }
10   - return result
11   -}
12   -func ListStringToListInt64(list []string) []int64 {
13   - result := make([]int64, 0)
14   - for _, v := range list {
15   - result = append(result, StringToInt64(v))
16   - }
17   - return result
18   -}
19   -func StringToListString(str string, sep string) []string {
20   - return strings.Split(str, sep)
21   -}
22   -func StringToListInt(str string, sep string) []int {
23   - return ListStringToListInt(strings.Split(str, sep))
24   -}
25   -func StringToListListString(str string, sep1, sep2 string) [][]string {
26   - result := make([][]string, 0)
27   - list1 := strings.Split(str, sep1)
28   - for _, v := range list1 {
29   - list2 := strings.Split(v, sep2)
30   - result = append(result, list2)
31   - }
32   - return result
33   -}
34   -func StringToListListInt(str string, sep1, sep2 string) [][]int {
35   - result := make([][]int, 0)
36   - list1 := strings.Split(str, sep1)
37   - for _, v := range list1 {
38   - list2 := strings.Split(v, sep2)
39   - result = append(result, ListStringToListInt(list2))
40   - }
41   - return result
42   -}
43   -func StringToListListInt64(str string, sep1, sep2 string) [][]int64 {
44   - result := make([][]int64, 0)
45   - list1 := strings.Split(str, sep1)
46   - for _, v := range list1 {
47   - list2 := strings.Split(v, sep2)
48   - result = append(result, ListStringToListInt64(list2))
49   - }
50   - return result
51   -}
util/utstring/string.go
... ... @@ -1,30 +0,0 @@
1   -package utstring
2   -
3   -import (
4   - "strconv"
5   -)
6   -
7   -func StringToInt(str string) int {
8   - if value, err := strconv.Atoi(str); err == nil {
9   - return value
10   - }
11   - return 0
12   -}
13   -func StringToInt32(str string) int32 {
14   - return int32(StringToInt(str))
15   -}
16   -func StringToInt64(str string) int64 {
17   - if value, err := strconv.ParseInt(str, 10, 64); err == nil {
18   - return value
19   - }
20   - return 0
21   -}
22   -func IntToString(value int) string {
23   - return strconv.Itoa(value)
24   -}
25   -func Int32ToString(value int32) string {
26   - return IntToString(int(value))
27   -}
28   -func Int64ToString(value int64) string {
29   - return strconv.FormatInt(value, 10)
30   -}
util/uttype/equals.go
... ... @@ -1,8 +0,0 @@
1   -package uttype
2   -
3   -// EqualAble 可比较的
4   -type EqualAble interface {
5   - Equals(T EqualAble) bool
6   -}
7   -
8   -type FuncEquals[T any] func(v1 T, v2 T) bool
util/uttype/type.go
... ... @@ -1,21 +0,0 @@
1   -package uttype
2   -
3   -type UtInt interface {
4   - ~int | ~int8 | ~int16 | ~int32 | ~int64
5   -}
6   -
7   -type UtUint interface {
8   - ~uint | ~uint8 | ~uint16 | ~uint32
9   -}
10   -
11   -type UtFloat interface {
12   - ~float32 | ~float64
13   -}
14   -
15   -type UtNumber interface {
16   - UtInt | UtUint | UtFloat
17   -}
18   -
19   -type UtBase interface {
20   - UtNumber | string
21   -}
util/utuuid/uuid.go
... ... @@ -1,7 +0,0 @@
1   -package utuuid
2   -
3   -import "github.com/google/uuid"
4   -
5   -func GetUint32() uint32 {
6   - return uuid.New().ID()
7   -}
util/zconvert/list.go 0 → 100644
... ... @@ -0,0 +1,109 @@
  1 +package zconvert
  2 +
  3 +import (
  4 + "apigame/util/ztype"
  5 + "strings"
  6 +)
  7 +
  8 +/* ----- list<number> -> list<number> ----- */
  9 +
  10 +func ListNumberToListNumber[T1 ztype.UtNumber, T2 ztype.UtNumber](in []T1) (out []T2) {
  11 + for _, t1 := range in {
  12 + out = append(out, T2(t1))
  13 + }
  14 + return
  15 +}
  16 +
  17 +/* ----- list<string> -> list<number> ----- */
  18 +
  19 +func ListStrToListNumber[T ztype.UtNumber](list []string) []T {
  20 + result := make([]T, 0)
  21 + for _, v := range list {
  22 + result = append(result, T(ToInt64(v)))
  23 + }
  24 + return result
  25 +}
  26 +func ListStrToListInt(list []string) []int {
  27 + result := make([]int, 0)
  28 + for _, v := range list {
  29 + result = append(result, ToInt(v))
  30 + }
  31 + return result
  32 +}
  33 +func ListStrToListInt32(list []string) []int32 {
  34 + result := make([]int32, 0)
  35 + for _, v := range list {
  36 + result = append(result, ToInt32(v))
  37 + }
  38 + return result
  39 +}
  40 +func ListStrToListInt64(list []string) []int64 {
  41 + result := make([]int64, 0)
  42 + for _, v := range list {
  43 + result = append(result, ToInt64(v))
  44 + }
  45 + return result
  46 +}
  47 +
  48 +/* ----- string -> list<number> ----- */
  49 +
  50 +func ToListStr(str string, sep string) []string {
  51 + return strings.Split(str, sep)
  52 +}
  53 +func ToListNumber[T ztype.UtNumber](str string, sep string) []T {
  54 + return ListStrToListNumber[T](strings.Split(str, sep))
  55 +}
  56 +func ToListInt(str string, sep string) []int {
  57 + return ListStrToListInt(strings.Split(str, sep))
  58 +}
  59 +func ToListInt32(str string, sep string) []int32 {
  60 + return ListStrToListInt32(strings.Split(str, sep))
  61 +}
  62 +
  63 +/* ----- string -> list<list<number>> ----- */
  64 +
  65 +func ToListListStr(str string, sep1, sep2 string) [][]string {
  66 + result := make([][]string, 0)
  67 + list1 := strings.Split(str, sep1)
  68 + for _, v := range list1 {
  69 + list2 := strings.Split(v, sep2)
  70 + result = append(result, list2)
  71 + }
  72 + return result
  73 +}
  74 +func ToListListNumber[T ztype.UtNumber](str string, sep1, sep2 string) [][]T {
  75 + result := make([][]T, 0)
  76 + list1 := strings.Split(str, sep1)
  77 + for _, v := range list1 {
  78 + list2 := strings.Split(v, sep2)
  79 + result = append(result, ListStrToListNumber[T](list2))
  80 + }
  81 + return result
  82 +}
  83 +func ToListListInt(str string, sep1, sep2 string) [][]int {
  84 + result := make([][]int, 0)
  85 + list1 := strings.Split(str, sep1)
  86 + for _, v := range list1 {
  87 + list2 := strings.Split(v, sep2)
  88 + result = append(result, ListStrToListInt(list2))
  89 + }
  90 + return result
  91 +}
  92 +func ToListListInt32(str string, sep1, sep2 string) [][]int32 {
  93 + result := make([][]int32, 0)
  94 + list1 := strings.Split(str, sep1)
  95 + for _, v := range list1 {
  96 + list2 := strings.Split(v, sep2)
  97 + result = append(result, ListStrToListInt32(list2))
  98 + }
  99 + return result
  100 +}
  101 +func ToListListInt64(str string, sep1, sep2 string) [][]int64 {
  102 + result := make([][]int64, 0)
  103 + list1 := strings.Split(str, sep1)
  104 + for _, v := range list1 {
  105 + list2 := strings.Split(v, sep2)
  106 + result = append(result, ListStrToListInt64(list2))
  107 + }
  108 + return result
  109 +}
... ...
util/zconvert/map.go 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +package zconvert
  2 +
  3 +/* ----- string -> map ----- */
  4 +
  5 +func ToMapStr(str string, sep1, sep2 string) map[string]string {
  6 + result := make(map[string]string)
  7 + list := ToListListStr(str, sep1, sep2)
  8 + for _, i2 := range list {
  9 + if len(i2) >= 2 {
  10 + result[i2[0]] = i2[1]
  11 + }
  12 + }
  13 + return result
  14 +}
  15 +
  16 +func ToMapInt32(str string, sep1, sep2 string) map[int32]int32 {
  17 + result := make(map[int32]int32)
  18 + list := ToListListInt32(str, sep1, sep2)
  19 + for _, i2 := range list {
  20 + if len(i2) >= 2 {
  21 + result[i2[0]] = i2[1]
  22 + }
  23 + }
  24 + return result
  25 +}
... ...
util/zconvert/number.go 0 → 100644
... ... @@ -0,0 +1,45 @@
  1 +package zconvert
  2 +
  3 +import (
  4 + "apigame/util/ztype"
  5 + "strconv"
  6 +)
  7 +
  8 +/* -----泛型----- */
  9 +
  10 +func ToStr[T ztype.UtInteger](t T) string {
  11 + return strconv.FormatInt(int64(t), 10)
  12 +}
  13 +func IToStr[T ztype.UtInt](t T) string {
  14 + return strconv.FormatInt(int64(t), 10)
  15 +}
  16 +func UToStr[T ztype.UtUint](t T) string {
  17 + return strconv.FormatUint(uint64(t), 10)
  18 +}
  19 +
  20 +/* ----- string -> number ----- */
  21 +
  22 +func ToInt(str string) int {
  23 + if value, err := strconv.Atoi(str); err == nil {
  24 + return value
  25 + }
  26 + return 0
  27 +}
  28 +func ToInt32(str string) int32 {
  29 + return int32(ToInt(str))
  30 +}
  31 +func ToInt64(str string) int64 {
  32 + if value, err := strconv.ParseInt(str, 10, 64); err == nil {
  33 + return value
  34 + }
  35 + return 0
  36 +}
  37 +func IntToStr(value int) string {
  38 + return strconv.Itoa(value)
  39 +}
  40 +func Int32ToStr(value int32) string {
  41 + return IntToStr(int(value))
  42 +}
  43 +func Int64ToStr(value int64) string {
  44 + return strconv.FormatInt(value, 10)
  45 +}
... ...
util/zmap/map.go 0 → 100644
... ... @@ -0,0 +1,66 @@
  1 +package zmap
  2 +
  3 +import (
  4 + "apigame/util/ztype"
  5 + "math/rand"
  6 +)
  7 +
  8 +// Keys Keys切片
  9 +func Keys[T1 comparable, T2 any](dict map[T1]T2) []T1 {
  10 + list := make([]T1, 0)
  11 + for k, _ := range dict {
  12 + list = append(list, k)
  13 + }
  14 + return list
  15 +}
  16 +
  17 +// Values Values切片
  18 +func Values[T1 comparable, T2 any](dict map[T1]T2) []T2 {
  19 + list := make([]T2, 0)
  20 + for _, v := range dict {
  21 + list = append(list, v)
  22 + }
  23 + return list
  24 +}
  25 +
  26 +// ContainValue 值等于
  27 +func ContainValue[T1 comparable, T2 comparable](dict map[T1]T2, value T2) bool {
  28 + for _, v := range dict {
  29 + if v == value {
  30 + return true
  31 + }
  32 + }
  33 + return false
  34 +}
  35 +
  36 +// ContainValueEquals 值等于
  37 +func ContainValueEquals[T1 comparable, T2 ztype.EqualAble](dict map[T1]T2, value T2) bool {
  38 + for _, v := range dict {
  39 + if v.Equals(value) {
  40 + return true
  41 + }
  42 + }
  43 + return false
  44 +}
  45 +
  46 +// ContainValueBy 值符合
  47 +func ContainValueBy[T1 comparable, T2 any](dict map[T1]T2, value T2, equals func(v1 T2, v2 T2) bool) bool {
  48 + for _, v := range dict {
  49 + if equals(v, value) {
  50 + return true
  51 + }
  52 + }
  53 + return false
  54 +}
  55 +
  56 +// RandomOne 随机一个值
  57 +func RandomOne[T1 comparable, T2 any](dict map[T1]T2) T2 {
  58 + if len(dict) <= 0 {
  59 + return *new(T2)
  60 + }
  61 + list := make([]T1, 0)
  62 + for i, _ := range dict {
  63 + list = append(list, i)
  64 + }
  65 + return dict[list[rand.Intn(len(list))]]
  66 +}
... ...
util/zmisc/goroutine.go 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +package zmisc
  2 +
  3 +import (
  4 + "fmt"
  5 + "runtime"
  6 +)
  7 +
  8 +// GetGoroutineID 获取携程ID
  9 +func GetGoroutineID() int {
  10 + var buf [64]byte
  11 + runtime.Stack(buf[:], false)
  12 + var id int
  13 + fmt.Sscanf(string(buf[:]), "goroutine %d", &id)
  14 + return id
  15 +}
... ...
util/zmisc/random.go 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +package zmisc
  2 +
  3 +import "math/rand"
  4 +
  5 +func RandomMultiple(count, minNum, maxNum int) []int {
  6 + list := make([]int, 0)
  7 + if maxNum > minNum {
  8 + if count > maxNum-minNum {
  9 + count = maxNum - minNum
  10 + }
  11 + m := make(map[int]struct{})
  12 + for len(m) < count {
  13 + v := minNum + rand.Intn(maxNum-minNum)
  14 + if _, ok := m[v]; !ok {
  15 + m[v] = struct{}{}
  16 + list = append(list, v)
  17 + }
  18 + }
  19 + }
  20 + return list
  21 +}
... ...
util/zslice/slice.go 0 → 100644
... ... @@ -0,0 +1,161 @@
  1 +package zslice
  2 +
  3 +import (
  4 + "apigame/util/ztype"
  5 + "math/rand"
  6 +)
  7 +
  8 +// Contains 判断切片是否包含某元素
  9 +func Contains[T comparable](list []T, value T) bool {
  10 + for _, v := range list {
  11 + if v == value {
  12 + return true
  13 + }
  14 + }
  15 + return false
  16 +}
  17 +
  18 +// RandomOne 随机一个元素
  19 +func RandomOne[T any](list []T) T {
  20 + if len(list) <= 0 {
  21 + return *new(T)
  22 + }
  23 + return list[rand.Intn(len(list))]
  24 +}
  25 +
  26 +// Remove 切片删除一个元素
  27 +func Remove[T comparable](list []T, item T) []T {
  28 + for i := 0; i < len(list); i++ {
  29 + if item == list[i] {
  30 + list = append(list[:i], list[i+1:]...)
  31 + i = i - 1
  32 + }
  33 + }
  34 + return list
  35 +}
  36 +
  37 +// RemoveList 切片删除多个元素
  38 +func RemoveList[T comparable](list []T, items []T) []T {
  39 + dMap := make(map[T]bool)
  40 + for _, s := range items {
  41 + dMap[s] = true
  42 + }
  43 +
  44 + for i := 0; i < len(list); i++ {
  45 + if _, ok := dMap[list[i]]; ok {
  46 + list = append(list[:i], list[i+1:]...)
  47 + i = i - 1
  48 + }
  49 + }
  50 + return list
  51 +}
  52 +
  53 +// Sum 求和
  54 +func Sum[T ztype.UtNumber](list []T) T {
  55 + var result T = 0
  56 + for _, v := range list {
  57 + result += v
  58 + }
  59 + return result
  60 +}
  61 +
  62 +// Any 其中有一个元素符合就返回true
  63 +func Any[T ztype.UtNumber](list []T, value T) bool {
  64 + for _, v := range list {
  65 + if v == value {
  66 + return true
  67 + }
  68 + }
  69 + return false
  70 +}
  71 +
  72 +// AnyEquals 其中有一个元素符合就返回true
  73 +func AnyEquals[T ztype.EqualAble](list []T, value T) bool {
  74 + for _, v := range list {
  75 + if v.Equals(value) {
  76 + return true
  77 + }
  78 + }
  79 + return false
  80 +}
  81 +
  82 +// AnyBy 其中有一个元素符合就返回true
  83 +func AnyBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) bool {
  84 + for _, v := range list {
  85 + if equals(v, value) {
  86 + return true
  87 + }
  88 + }
  89 + return false
  90 +}
  91 +
  92 +// All 所有元素符合就返回true
  93 +func All[T ztype.UtNumber](list []T, value T) bool {
  94 + for _, v := range list {
  95 + if v != value {
  96 + return false
  97 + }
  98 + }
  99 + return true
  100 +}
  101 +
  102 +// AllEquals 所有元素符合就返回true
  103 +func AllEquals[T ztype.EqualAble](list []T, value T) bool {
  104 + for _, v := range list {
  105 + if !v.Equals(value) {
  106 + return false
  107 + }
  108 + }
  109 + return true
  110 +}
  111 +
  112 +// AllBy 所有元素符合就返回true
  113 +func AllBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) bool {
  114 + for _, v := range list {
  115 + if !equals(v, value) {
  116 + return false
  117 + }
  118 + }
  119 + return true
  120 +}
  121 +
  122 +// Filter 过滤
  123 +func Filter[T comparable](list []T, value T) []T {
  124 + result := make([]T, 0)
  125 + for _, v := range list {
  126 + if v == value {
  127 + result = append(result, v)
  128 + }
  129 + }
  130 + return result
  131 +}
  132 +
  133 +// FilterEquals 过滤
  134 +func FilterEquals[T ztype.EqualAble](list []T, value T) []T {
  135 + result := make([]T, 0)
  136 + for _, v := range list {
  137 + if v.Equals(value) {
  138 + result = append(result, v)
  139 + }
  140 + }
  141 + return result
  142 +}
  143 +
  144 +// FilterBy 过滤
  145 +func FilterBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) []T {
  146 + result := make([]T, 0)
  147 + for _, v := range list {
  148 + if equals(v, value) {
  149 + result = append(result, v)
  150 + }
  151 + }
  152 + return result
  153 +}
  154 +
  155 +// Shuffle 打乱
  156 +func Shuffle[T any](list []T) {
  157 + for i := len(list) - 1; i > 0; i-- {
  158 + j := rand.Intn(i + 1)
  159 + list[i], list[j] = list[j], list[i]
  160 + }
  161 +}
... ...
util/ztype/compare.go 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +package ztype
  2 +
  3 +// Min 最小值
  4 +func Min[T UtNumber](v1, v2 T) T {
  5 + if v1 < v2 {
  6 + return v1
  7 + }
  8 + return v2
  9 +}
  10 +
  11 +// Max 最大值
  12 +func Max[T UtNumber](v1, v2 T) T {
  13 + if v1 > v2 {
  14 + return v1
  15 + }
  16 + return v2
  17 +}
... ...
util/ztype/equals.go 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +package ztype
  2 +
  3 +// EqualAble 可比较的
  4 +type EqualAble interface {
  5 + Equals(T EqualAble) bool
  6 +}
  7 +
  8 +type FuncEquals[T any] func(v1 T, v2 T) bool
... ...
util/ztype/type.go 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +package ztype
  2 +
  3 +type UtInt interface {
  4 + ~int | ~int8 | ~int16 | ~int32 | ~int64
  5 +}
  6 +
  7 +type UtUint interface {
  8 + ~uint | ~uint8 | ~uint16 | ~uint32
  9 +}
  10 +
  11 +type UtFloat interface {
  12 + ~float32 | ~float64
  13 +}
  14 +
  15 +type UtInteger interface {
  16 + UtInt | UtUint
  17 +}
  18 +
  19 +type UtNumber interface {
  20 + UtInt | UtUint | UtFloat
  21 +}
  22 +
  23 +type UtBase interface {
  24 + UtNumber | string
  25 +}
... ...
util/zuuid/uuid.go 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +package utuuid
  2 +
  3 +import "github.com/google/uuid"
  4 +
  5 +func GetUint32() uint32 {
  6 + return uuid.New().ID()
  7 +}
... ...