package cachecurd import ( "context" "joybuywork/internal/app" "joybuywork/internal/utils" "joybuywork/internal/utils/lockdo" "fmt" "strconv" "time" grds "github.com/go-redis/redis/v8" ) type HMap struct { ctx context.Context cli *grds.Client key string exp time.Duration build *HMapBuild data map[string]string } func NewHMap(ctx context.Context, key string, opts ...HMapOption) (*HMap, error) { hmap := &HMap{ ctx: ctx, cli: app.Redis.Cache, key: key, exp: lockdo.Rand2HourExp(), } for _, opt := range opts { opt(hmap) } err := hmap.Build() if err != nil { return nil, err } return hmap, nil } func (s *HMap) Get(field string) (value string, err error) { if s.data != nil { return s.data[field], nil } data, err := s.GetAll() if err != nil { return } return data[field], nil } func (s *HMap) GetInt64(field string) (value int64, err error) { val, err := s.Get(field) if err != nil { return } return utils.StrToInt64(val), nil } // GetAll 获取数据 func (s *HMap) GetAll() (data map[string]string, err error) { if s.data != nil { return s.data, nil } data, err = s.cli.HGetAll(s.ctx, s.key).Result() if err != nil { return } s.data = data return } // Set 设置数据 func (s *HMap) Set(values ...string) (err error) { s.cli.HSet(s.ctx, s.key, values) if s.data != nil { for i := 0; i < len(values); i += 2 { s.data[values[i]] = values[i+1] } } s.setExp() return } // Incr 追加值 func (s *HMap) Incr(key string, val int64) (num int64, err error) { num, err = s.cli.HIncrBy(s.ctx, s.key, key, val).Result() if err != nil { return } if s.data != nil { v, _ := strconv.ParseInt(s.data[key], 10, 64) s.data[key] = fmt.Sprintf("%d", v+val) } s.setExp() return } // Del 删除值 func (s *HMap) Del(key string) (err error) { s.cli.HDel(s.ctx, s.key, key) if s.data != nil { delete(s.data, key) } s.setExp() return } // Clear 清楚HMap func (s *HMap) Clear() (err error) { return s.cli.Del(s.ctx, s.key).Err() } // Exist 是否存在key func (s *HMap) Exist(key string) bool { data, _ := s.GetAll() _, ok := data[key] return ok } // Int64ToInt64 把数据变成map[int64]int64 func (s *HMap) Int64ToInt64() (data map[int64]int64, err error) { vals, err := s.GetAll() if err != nil { return } data = make(map[int64]int64, len(vals)) for k, v := range vals { key, _ := strconv.ParseInt(k, 10, 64) value, _ := strconv.ParseInt(v, 10, 64) data[key] = value } return } func (s *HMap) setExp() { s.cli.Expire(s.ctx, s.key, s.exp) } func (s *HMap) CustomBuild(fc func() ([]string, error)) (*HMap, error) { err := lockdo.ExistDo(s.ctx, s.key, func(exist bool) (err error) { if exist { return } values, err := fc() if err != nil { return } s.data = make(map[string]string, len(values)/2) return s.Set(values...) }) return s, err } type HMapBuild struct { t string CpnId int64 RewardId int64 RewardLimit int64 SceneId int64 UserId int64 Tz int32 } func (s *HMap) Build() (err error) { if s.build == nil { return } switch s.build.t { case tKeepRewardSelect: return s.keepRewardSelect(s.build) case tCampaignRewardStock: return s.campaignRewardStock(s.build) case tRewardSelectStock: return s.rewardSelectStock(s.build) case tCampaignStock: return s.campaignStock(s.build) case tCoinScene: return s.coinScene(s.build) case tMallItemStock: return s.mallItemStock(s.build) } return }