CouponSend.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. namespace addons\shopro\traits;
  3. use think\Db;
  4. use think\exception\HttpResponseException;
  5. use app\admin\model\shopro\Coupon;
  6. use app\admin\model\shopro\user\Coupon as UserCouponModel;
  7. /**
  8. * 发放优惠券
  9. */
  10. trait CouponSend
  11. {
  12. /**
  13. * 用户自己领取优惠券
  14. *
  15. * @param [type] $id
  16. * @return void
  17. */
  18. public function getCoupon($id)
  19. {
  20. $user = auth_user();
  21. $userCoupon = Db::transaction(function () use ($user, $id) {
  22. $coupon = Coupon::normal() // 正常的可以展示的优惠券
  23. ->canGet() // 在领取时间之内的
  24. ->lock(true)
  25. ->where('id', $id)
  26. ->find();
  27. if (!$coupon) {
  28. error_stop('优惠券未找到');
  29. }
  30. $userCoupon = $this->send($user, $coupon);
  31. return $userCoupon;
  32. });
  33. return $userCoupon;
  34. }
  35. /**
  36. * 赠送优惠券
  37. *
  38. * @param array $user
  39. * @param array|string $ids
  40. * @return array
  41. */
  42. public function giveCoupons($user, $ids)
  43. {
  44. $ids = is_array($ids) ? $ids : explode(',', $ids);
  45. $result = Db::transaction(function () use ($user, $ids) {
  46. $errors = []; // 发送失败的优惠券,包含失败原因
  47. $success = []; // 发送成功的优惠券
  48. $coupons = Coupon::statusHidden() // 只查询隐藏券(后台发放的券)
  49. ->canGet()
  50. ->whereIn('id', $ids)
  51. ->select();
  52. $findCouponIds = array_column($coupons, 'id'); // 找到的优惠券 ids
  53. $nofundIds = array_diff($ids, $findCouponIds);
  54. foreach ($nofundIds as $nofund_id) {
  55. $errors[] = ['id' => $nofund_id, 'error' => '优惠券未找到'];
  56. }
  57. foreach ($coupons as $coupon) {
  58. try {
  59. $userCoupon = $this->send($user, $coupon);
  60. $success[] = $coupon->id;
  61. } catch (HttpResponseException $e) {
  62. $data = $e->getResponse()->getData();
  63. $message = $data ? ($data['msg'] ?? '') : $e->getMessage();
  64. $errors[] = ['id' => $coupon->id, 'error' => $message];
  65. } catch (\Exception $e) {
  66. $errors[] = ['id' => $coupon->id, 'error' => $e->getMessage()];
  67. }
  68. }
  69. $result['success'] = $success;
  70. $result['errors'] = $errors;
  71. return $result;
  72. });
  73. return $result;
  74. }
  75. public function manualSend($users, $id)
  76. {
  77. $coupon = Coupon::canGet() // 在领取时间之内的
  78. ->lock(true)
  79. ->where('id', $id)
  80. ->find();
  81. if (!$coupon) {
  82. // 不在发放时间段
  83. error_stop('优惠券不在发放时间段');
  84. }
  85. if ($coupon->stock < count($users)) {
  86. // 库存不足
  87. error_stop('优惠券库存不足');
  88. }
  89. // 扣除库存
  90. $coupon->setDec('stock', count($users));
  91. $sends = [];
  92. foreach ($users as $user) {
  93. $current = [
  94. 'user_id' => $user->id,
  95. 'coupon_id' => $coupon->id,
  96. 'use_time' => null,
  97. 'createtime' => time(),
  98. 'updatetime' => time(),
  99. ];
  100. $sends[] = $current;
  101. }
  102. UserCouponModel::insertAll($sends);
  103. }
  104. /**
  105. * 发放优惠券
  106. *
  107. * @param array|object $user 发放用户
  108. * @param array|object $coupon 要发放的优惠券
  109. * @return array|object
  110. */
  111. private function send($user, $coupon) {
  112. if ($coupon->get_status == 'cannot_get') {
  113. error_stop('您已经领取过了');
  114. }
  115. if ($coupon->stock <= 0) {
  116. error_stop('优惠券已经被领完了');
  117. }
  118. $coupon->setDec('stock');
  119. $userCoupon = new UserCouponModel();
  120. $userCoupon->user_id = $user->id;
  121. $userCoupon->coupon_id = $coupon->id;
  122. $userCoupon->use_time = null;
  123. $userCoupon->save();
  124. return $userCoupon;
  125. }
  126. /**
  127. * 退回用户优惠券
  128. *
  129. * @param integer $user_coupon_id
  130. * @return void
  131. */
  132. public function backUserCoupon($user_coupon_id)
  133. {
  134. $userCoupon = UserCouponModel::where('id', $user_coupon_id)->find();
  135. if ($userCoupon) {
  136. $userCoupon->use_time = null;
  137. $userCoupon->save();
  138. }
  139. }
  140. }