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
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
|
|
}
|