You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
3.4 KiB
Go

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
}