UserCoupon.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. /**
  3. *
  4. * @copyright ©2020 点小铺
  5. * @author hanj
  6. * @link: https://dyuit.com
  7. * Created by VSCode
  8. */
  9. namespace app\api\model;
  10. use app\common\library\helper;
  11. use app\common\model\UserCoupon as UserCouponModel;
  12. /**
  13. * 用户优惠券模型
  14. * Class UserCoupon
  15. * @package app\api\model
  16. */
  17. class UserCoupon extends UserCouponModel
  18. {
  19. /**
  20. * 获取用户优惠券列表
  21. * @param $user_id
  22. * @param bool $is_use 是否已使用
  23. * @param bool $is_expire 是否已过期
  24. * @return false|\PDOStatement|string|\think\Collection
  25. * @throws \think\db\exception\DataNotFoundException
  26. * @throws \think\db\exception\ModelNotFoundException
  27. * @throws \think\exception\DbException
  28. */
  29. public function getList($user_id, $is_use = false, $is_expire = false)
  30. {
  31. return $this->where('user_id', '=', $user_id)
  32. ->where('is_use', '=', $is_use ? 1 : 0)
  33. ->where('is_expire', '=', $is_expire ? 1 : 0)
  34. ->select();
  35. }
  36. /**
  37. * 获取用户优惠券总数量(可用)
  38. * @param $user_id
  39. * @return int|string
  40. * @throws \think\Exception
  41. */
  42. public function getCount($user_id)
  43. {
  44. return $this->where('user_id', '=', $user_id)
  45. ->where('is_use', '=', 0)
  46. ->where('is_expire', '=', 0)
  47. ->count();
  48. }
  49. /**
  50. * 获取用户优惠券ID集
  51. * @param $user_id
  52. * @return array
  53. */
  54. public function getUserCouponIds($user_id)
  55. {
  56. return $this->where('user_id', '=', $user_id)->column('coupon_id');
  57. }
  58. /**
  59. * 领取优惠券
  60. * @param $user
  61. * @param $coupon_id
  62. * @return bool|false|int
  63. * @throws \think\exception\DbException
  64. */
  65. public function receive($user, $coupon_id)
  66. {
  67. // 获取优惠券信息
  68. $coupon = Coupon::detail($coupon_id);
  69. // 验证优惠券是否可领取
  70. if (!$this->checkReceive($user, $coupon)) {
  71. return false;
  72. }
  73. // 添加领取记录
  74. return $this->add($user, $coupon);
  75. }
  76. /**
  77. * 添加领取记录
  78. * @param $user
  79. * @param Coupon $coupon
  80. * @return bool
  81. */
  82. private function add($user, $coupon)
  83. {
  84. // 计算有效期
  85. if ($coupon['expire_type'] == 10) {
  86. $start_time = time();
  87. $end_time = $start_time + ($coupon['expire_day'] * 86400);
  88. } else {
  89. $start_time = $coupon['start_time']['value'];
  90. $end_time = $coupon['end_time']['value'];
  91. }
  92. // 整理领取记录
  93. $data = [
  94. 'coupon_id' => $coupon['coupon_id'],
  95. 'name' => $coupon['name'],
  96. 'color' => $coupon['color']['value'],
  97. 'coupon_type' => $coupon['coupon_type']['value'],
  98. 'reduce_price' => $coupon['reduce_price'],
  99. 'discount' => $coupon->getData('discount'),
  100. 'min_price' => $coupon['min_price'],
  101. 'expire_type' => $coupon['expire_type'],
  102. 'expire_day' => $coupon['expire_day'],
  103. 'start_time' => $start_time,
  104. 'end_time' => $end_time,
  105. 'apply_range' => $coupon['apply_range'],
  106. 'user_id' => $user['user_id'],
  107. 'wxapp_id' => self::$wxapp_id
  108. ];
  109. return $this->transaction(function () use ($data, $coupon) {
  110. // 添加领取记录
  111. $status = $this->save($data);
  112. if ($status) {
  113. // 更新优惠券领取数量
  114. $coupon->setIncReceiveNum();
  115. }
  116. return $status;
  117. });
  118. }
  119. /**
  120. * 验证优惠券是否可领取
  121. * @param $user
  122. * @param Coupon $coupon
  123. * @return bool
  124. */
  125. private function checkReceive($user, $coupon)
  126. {
  127. if (!$coupon) {
  128. $this->error = '优惠券不存在';
  129. return false;
  130. }
  131. if (!$coupon->checkReceive()) {
  132. $this->error = $coupon->getError();
  133. return false;
  134. }
  135. // 验证是否已领取
  136. $userCouponIds = $this->getUserCouponIds($user['user_id']);
  137. if (in_array($coupon['coupon_id'], $userCouponIds)) {
  138. $this->error = '该优惠券已领取';
  139. return false;
  140. }
  141. return true;
  142. }
  143. /**
  144. * 订单结算优惠券列表
  145. * @param int $user_id 用户id
  146. * @param double $orderPayPrice 订单商品总金额
  147. * @return mixed
  148. * @throws \think\db\exception\DataNotFoundException
  149. * @throws \think\db\exception\ModelNotFoundException
  150. * @throws \think\exception\DbException
  151. */
  152. public static function getUserCouponList($user_id, $orderPayPrice)
  153. {
  154. // todo: 新增筛选条件: 最低消费金额
  155. // 获取用户可用的优惠券列表
  156. $list = (new self)->getList($user_id);
  157. $data = [];
  158. foreach ($list as $coupon) {
  159. // 最低消费金额
  160. if ($orderPayPrice < $coupon['min_price']) continue;
  161. // 有效期范围内
  162. if ($coupon['start_time']['value'] > time()) continue;
  163. $key = $coupon['user_coupon_id'];
  164. $data[$key] = [
  165. 'user_coupon_id' => $coupon['user_coupon_id'],
  166. 'name' => $coupon['name'],
  167. 'color' => $coupon['color'],
  168. 'coupon_type' => $coupon['coupon_type'],
  169. 'reduce_price' => $coupon['reduce_price'],
  170. 'discount' => $coupon['discount'],
  171. 'min_price' => $coupon['min_price'],
  172. 'expire_type' => $coupon['expire_type'],
  173. 'start_time' => $coupon['start_time'],
  174. 'end_time' => $coupon['end_time'],
  175. ];
  176. // 计算打折金额
  177. if ($coupon['coupon_type']['value'] == 20) {
  178. // $reduce_price = $orderPayPrice * ($coupon['discount'] / 10);
  179. $reducePrice = helper::bcmul($orderPayPrice, $coupon['discount'] / 10);
  180. $data[$key]['reduced_price'] = bcsub($orderPayPrice, $reducePrice, 2);
  181. } else
  182. $data[$key]['reduced_price'] = $coupon['reduce_price'];
  183. }
  184. // 根据折扣金额排序并返回
  185. return array_sort($data, 'reduced_price', true);
  186. }
  187. }