GoodsStock.php 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <?php
  2. namespace app\frontend\modules\goods\stock;
  3. use app\common\events\goods\ActualStockForOrderEvent;
  4. use app\common\events\goods\StockReduceByOrderEvent;
  5. use app\common\models\Goods;
  6. use app\common\models\GoodsOption;
  7. use Illuminate\Support\Facades\Redis;
  8. class GoodsStock
  9. {
  10. /**
  11. * @var Goods|GoodsOption
  12. */
  13. private $source;
  14. public function __construct($source)
  15. {
  16. $this->source = $source;
  17. }
  18. public function withhold($num)
  19. {
  20. return Redis::incrby($this->withholdStockKey(), $num);
  21. }
  22. public function rollback($num)
  23. {
  24. if (Redis::get($this->withholdStockKey()) - $num < 0) {
  25. return false;
  26. }
  27. return Redis::decrby($this->withholdStockKey(), $num);
  28. }
  29. public function reduce($num)
  30. {
  31. try {
  32. \Log::debug('商品扣库存', "商品(" . get_class($this->source()) . ":{$this->source()->id}-{$this->source()->stock})减库存{$num}件");
  33. }catch (\Exception $e){
  34. }
  35. if (($this->source()->stock - $num) <= 0) {
  36. $this->source()->fireStockNotEnoughtEvent($this->source());
  37. }
  38. // 数据库减库存
  39. event(new StockReduceByOrderEvent($this->source(),$num));
  40. return $this->source()->decrement('stock', $num);
  41. }
  42. public function enough($num)
  43. {
  44. return $this->usableStock() >= $num;
  45. }
  46. public function usableStock()
  47. {
  48. event($event = new ActualStockForOrderEvent($this->source()));
  49. $stock = $event->getReplaceStock() === false ? $this->stock() : $event->getReplaceStock();
  50. return $stock - $this->withholdStock();
  51. }
  52. public function withholdStock()
  53. {
  54. return Redis::get($this->withholdStockKey()) ?: 0;
  55. }
  56. public function stock()
  57. {
  58. return $this->source()->getOriginal('stock');
  59. }
  60. /**
  61. * @return Goods|GoodsOption
  62. */
  63. private function source()
  64. {
  65. return $this->source;
  66. }
  67. private function withholdStockKey()
  68. {
  69. return $this->source()->getTable() . ":{$this->source()->id}:withhold_stock";
  70. }
  71. }