Seckill.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. namespace addons\shopro\library\activity\provider;
  3. use addons\shopro\service\StockSale;
  4. use addons\shopro\exception\ShoproException;
  5. /**
  6. * 秒杀
  7. */
  8. class Seckill extends Base
  9. {
  10. protected $rules = [
  11. "is_commission" => "require|boolean",
  12. "is_free_shipping" => "require|boolean",
  13. "sales_show_type" => "require",
  14. "limit_num" => "number|egt:0",
  15. "order_auto_close" => "float|egt:0",
  16. ];
  17. protected $message = [
  18. ];
  19. protected $default = [
  20. "is_commission" => 0, // 是否参与分销
  21. "is_free_shipping" => 0, // 是否包邮
  22. "sales_show_type" => "real", // real=真实活动销量|goods=商品总销量(包含虚拟销量)
  23. "limit_num" => 0, // 每人限购数量 0:不限购
  24. "order_auto_close" => 0, // 订单自动关闭时间,如果为 0 将使用系统级订单自动关闭时间
  25. ];
  26. public function check($params, $activity_id = 0)
  27. {
  28. // 数据验证
  29. $params = parent::check($params);
  30. // 验证添加的活动商品是否至少设置了一个活动规格
  31. $this->checkActivitySkuPrice($params['goods_list']);
  32. // 检测活动之间是否存在冲突
  33. $this->checkActivityConflict($params, $params['goods_list'], $activity_id);
  34. return $params;
  35. }
  36. public function save($activity, $params = [])
  37. {
  38. $goodsList = $params['goods_list'];
  39. $this->saveSkuPrice($goodsList, $activity);
  40. }
  41. public function recoverSkuPrices($goods, $activity)
  42. {
  43. $activitySkuPrices = $activity['activity_sku_prices'];
  44. $skuPrices = $goods->sku_prices;
  45. foreach ($skuPrices as $key => &$skuPrice) {
  46. $stock = $skuPrice->stock; // 下面要用
  47. $skuPrice->stock = 0;
  48. $skuPrice->sales = 0;
  49. foreach ($activitySkuPrices as $activitySkuPrice) {
  50. if ($skuPrice['id'] == $activitySkuPrice['goods_sku_price_id']) {
  51. // 采用活动的 规格内容
  52. $skuPrice->old_price = $skuPrice->price; // 保存原始普通商品规格的价格(计算活动的优惠)
  53. $skuPrice->stock = ($activitySkuPrice['stock'] > $stock) ? $stock : $activitySkuPrice['stock']; // 活动库存不能超过商品库存
  54. $skuPrice->sales = $activitySkuPrice['sales'];
  55. $skuPrice->price = $activitySkuPrice['price'];
  56. $skuPrice->status = $activitySkuPrice['status']; // 采用活动的上下架
  57. $skuPrice->min_price = $activitySkuPrice['price']; // 当前活动规格最小价格,这里是秒杀价
  58. $skuPrice->max_price = $activitySkuPrice['price']; // 用作计算活动中最大价格
  59. // 记录相关活动类型
  60. $skuPrice->activity_type = $activity['type'];
  61. $skuPrice->activity_id = $activity['id'];
  62. // 下单的时候需要存活动 的 sku_price_id)
  63. $skuPrice->item_goods_sku_price = $activitySkuPrice;
  64. break;
  65. }
  66. }
  67. }
  68. return $skuPrices;
  69. }
  70. /**
  71. * 这里要使用 shoproException 抛出异常
  72. *
  73. * @param array $buyInfo
  74. * @param array $activity
  75. * @return array
  76. */
  77. public function buyCheck($buyInfo, $activity)
  78. {
  79. // 秒杀
  80. $rules = $activity['rules'];
  81. $currentSkuPrice = $buyInfo['current_sku_price'];
  82. // 当前库存,小于要购买的数量
  83. $need_num = $buyInfo['goods_num'] + ($need_add_num ?? 0);
  84. if ($currentSkuPrice['stock'] < $need_num) {
  85. throw new ShoproException('商品库存不足');
  86. }
  87. $buyInfo['is_commission'] = $rules['is_commission'] ?? 0; // 是否参与分销
  88. return $buyInfo;
  89. }
  90. public function buy($buyInfo, $activity)
  91. {
  92. $user = auth_user();
  93. // 判断 并 增加 redis 销量
  94. $stockSale = new StockSale();
  95. $stockSale->cacheForwardSale($buyInfo);
  96. return $buyInfo;
  97. }
  98. public function buyOk($order, $user)
  99. {
  100. // 不需要处理
  101. }
  102. /**
  103. * 购买失败
  104. *
  105. * @param array $order
  106. * @return void
  107. */
  108. public function buyFail($order, $type)
  109. {
  110. // 判断扣除预销量 (活动信息还在 redis)
  111. $stockSale = new StockSale();
  112. $stockSale->cacheBackSale($order);
  113. }
  114. }