You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

OrderFlash.php 4.7 KiB

4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: zhengmingwei
  5. * Date: 2020/4/15
  6. * Time: 3:29 PM
  7. */
  8. namespace addons\unishop\behavior;
  9. use addons\unishop\extend\Hashids;
  10. use addons\unishop\extend\Redis;
  11. use addons\unishop\model\Address;
  12. use addons\unishop\model\Config;
  13. use addons\unishop\model\DeliveryRule as DeliveryRuleModel;
  14. use addons\unishop\model\FlashProduct;
  15. use addons\unishop\model\FlashSale;
  16. use addons\unishop\model\Product;
  17. use app\admin\model\unishop\Coupon;
  18. use think\Db;
  19. use think\Exception;
  20. /**
  21. * 秒杀订单相关行为
  22. * Class OrderFlash
  23. * @package addons\unishop\behavior
  24. */
  25. class OrderFlash
  26. {
  27. /**
  28. * 检查是否符合创建订单的条件
  29. * 条件1:判断是否卖完秒杀量和是否下架
  30. * 条件2:商品是否存在
  31. * 条件3:收货地址是否在范围内
  32. * 条件4:商品库存情况
  33. * @param array $params
  34. * @param array $extra
  35. * @throws Exception
  36. * @throws \think\exception\DbException
  37. */
  38. public function createOrderBefore(&$params, $extra)
  39. {
  40. // 条件一
  41. $numbers = explode(',', $extra['number']);
  42. $redis = new Redis();
  43. $totalNumber = $redis->handler->hGet('flash_sale_' . $extra['flash_id'] . '_' . $extra['product_id'], 'number');
  44. $totalSold = $redis->handler->hGet('flash_sale_' . $extra['flash_id'] . '_' . $extra['product_id'], 'sold');
  45. $switch = $redis->handler->hGet('flash_sale_' . $extra['flash_id'] . '_' . $extra['product_id'], 'switch');
  46. $starttime = $redis->handler->hGet('flash_sale_' . $extra['flash_id'] . '_' . $extra['product_id'], 'starttime');
  47. $endtime = $redis->handler->hGet('flash_sale_' . $extra['flash_id'] . '_' . $extra['product_id'], 'endtime');
  48. //判断是否开始或结束
  49. if (time() < $starttime) {
  50. $this->error(__('Activity not started'));
  51. }
  52. if ($endtime < time()) {
  53. $this->error(__('Activity ended'));
  54. }
  55. // 截流
  56. if ($totalSold >= $totalNumber) {
  57. throw new Exception(__('Item sold out'));
  58. }
  59. if ($switch == FlashSale::SWITCH_NO) {
  60. throw new Exception(__('Item is off the shelves'));
  61. }
  62. // 条件二
  63. $products = Db::name('unishop_product')->where(['id' => $extra['product_id']])->select();
  64. if (!$products) {
  65. throw new Exception(__('Product not exist'));
  66. }
  67. $specs = explode(',', $extra['spec']);
  68. foreach ($specs as &$spec) {
  69. $spec = str_replace('|', ',', $spec);
  70. }
  71. // 条件三
  72. $delivery = (new DeliveryRuleModel())->cityInScopeOfDelivery($extra['city_id'], $extra['delivery_id']);
  73. if (!$delivery) {
  74. throw new Exception(__('Your receiving address is not within the scope of delivery'));
  75. } else {
  76. if ($delivery['min'] > array_sum($numbers)) {
  77. throw new Exception(__('You must purchase at least %s item to use this shipping method', $delivery['min']));
  78. }
  79. }
  80. $address = (new Address)->where(['id' => $extra['address_id'], 'user_id' => $extra['userId']])->find();
  81. if (!$address) {
  82. throw new Exception(__('Address not exist'));
  83. }
  84. // 条件四
  85. $orderPrice = 0;
  86. foreach ($products as $key => $product) {
  87. $productInfo = (new \addons\unishop\extend\Product())->getBaseData($product, $specs[$key] ? $specs[$key] : '');
  88. $sold = $redis->handler->hIncrBy('flash_sale_' . $extra['flash_id'] . '_' . $extra['product_id'], 'sold', $numbers[$key]);
  89. if ($totalNumber < $sold) {
  90. $redis->handler->hIncrBy('flash_sale_' . $extra['flash_id'] . '_' . $extra['product_id'], 'sold', -$numbers[$key]);
  91. throw new Exception(__('Insufficient inventory,%s pieces left', $totalNumber - $totalSold));
  92. }
  93. $orderPrice = bcadd($orderPrice, bcmul($productInfo['sales_price'], $numbers[$key], 2), 2);
  94. $baseProductInfo[] = $productInfo;
  95. }
  96. // 没有优惠券
  97. $coupon = [];
  98. $params = [$products, $delivery, $coupon, $baseProductInfo, $address, $orderPrice, $specs, $numbers];
  99. }
  100. /**
  101. * 创建订单之后
  102. * 行为一:更新秒杀商品销售量
  103. * 行为二:增加商品的下单未付款数量
  104. * @param array $params 商品属性
  105. * @param array $extra
  106. */
  107. public function createOrderAfter(&$params, $extra)
  108. {
  109. // 行为一
  110. (new FlashProduct)->where(['flash_id' => $extra['flash_id'], 'product_id' => $extra['product_id']])->setInc('sold', $extra['number']);
  111. // 行为二
  112. (new Product)->where(['id' => $extra['product_id']])->setInc('no_buy_yet', $extra['number']);
  113. }
  114. }