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.

162 lines
2.9 KiB
Go

package stocks
import (
"context"
"joybuywork/internal/repository/dao"
"joybuywork/internal/service/provider/cachecurd"
"joybuywork/internal/utils/logic"
"joybuywork/internal/utils/merr"
"strconv"
)
type IStock interface {
Key(id int64) string // 缓存key
BuildStock(id int64) (*cachecurd.HMap, error) // 构建库存缓存
}
type stocks struct {
logic.Context
ids []int64
stockMap map[int64]*cachecurd.HMap
im IStock
}
func (s *stocks) Init(ctx context.Context, im IStock, ids []int64) (err error) {
s.Context.Init(ctx, dao.Q, merr.NewBE(ctx))
s.ids = ids
s.stockMap = make(map[int64]*cachecurd.HMap, len(ids))
s.im = im
for _, id := range ids {
s.stockMap[id], err = im.BuildStock(id)
if err != nil {
return
}
}
return
}
// Total 奖品总库存
func (s *stocks) Total(id int64) (num int64, err error) {
return s.getField(id, cachecurd.StockFieldStock)
}
// GetUseStock 获取奖品已使用库存数量
func (s *stocks) GetUseStock(id int64) (num int64, err error) {
return s.getField(id, cachecurd.StockFieldUseStock)
}
// AddUseStock 添加库存使用量
func (s *stocks) AddUseStock(total int64, ids ...int64) (err error) {
if len(ids) == 0 {
ids = s.ids
}
for _, id := range ids {
stock, ok := s.stockMap[id]
if !ok {
continue
}
_, err = stock.Incr(cachecurd.StockFieldUseStock, total)
if err != nil {
return
}
}
return
}
// AllUseStock 奖品集合已使用库存数量
func (s *stocks) AllUseStock(ids ...int64) (data map[int64]int64, err error) {
if len(ids) == 0 {
ids = s.ids
}
data = make(map[int64]int64, len(ids))
for _, id := range ids {
data[id], err = s.GetUseStock(id)
if err != nil {
return
}
}
return
}
// ClearUseStock 清空缓存
func (s *stocks) ClearUseStock(ids ...int64) (err error) {
clearIds := s.ids
if len(ids) > 0 {
clearIds = ids
}
for _, id := range clearIds {
stock, ok := s.stockMap[id]
if !ok {
continue
}
err = stock.Clear()
if err != nil {
return
}
}
return
}
// DecrPoolAndAdd 扣除奖品池成功增加库存使用
func (s *stocks) DecrPoolAndAdd(id, val int64) (ok bool, err error) {
stock, err := s.getAndSet(id)
if err != nil {
return
}
num, err := stock.Incr(cachecurd.StockFieldPoolNum, -val)
if err != nil {
return
}
if num < 0 {
return
}
err = s.AddUseStock(val, id)
if err != nil {
return
}
return true, nil
}
// 获取缓存,没有就设置
func (s *stocks) getAndSet(id int64) (stock *cachecurd.HMap, err error) {
stock, ok := s.stockMap[id]
if ok {
return
}
stock, err = s.im.BuildStock(id)
if err != nil {
return
}
s.stockMap[id] = stock
s.ids = append(s.ids, id)
return
}
// 获取库存缓存的某个字段
func (s *stocks) getField(id int64, field string) (total int64, err error) {
stock, err := s.getAndSet(id)
if err != nil {
return
}
val, err := stock.Get(field)
if err != nil {
return
}
return strconv.ParseInt(val, 10, 64)
}