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