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.

228 lines
8.7 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. <?php
  2. namespace App\Service\v3\Implementations;
  3. use App\Model\v3\Coupon;
  4. use App\Model\v3\CouponRec;
  5. use App\Service\v3\Interfaces\CouponRecServiceInterface;
  6. use App\Service\v3\Interfaces\ShopCartServiceInterface;
  7. use Hyperf\DbConnection\Db;
  8. use Hyperf\Redis\Redis;
  9. use Hyperf\Utils\ApplicationContext;
  10. use Hyperf\Di\Annotation\Inject;
  11. class CouponRecService implements CouponRecServiceInterface
  12. {
  13. /**
  14. * @Inject
  15. * @var ShopCartServiceInterface
  16. */
  17. protected $shopCartService;
  18. public function do()
  19. {
  20. // TODO: Implement do() method.
  21. }
  22. public function check()
  23. {
  24. // TODO: Implement check() method.
  25. }
  26. public function undo()
  27. {
  28. // TODO: Implement undo() method.
  29. }
  30. /**
  31. * 获取当前订单可使用的优惠券
  32. * @param $totalAmount
  33. * @param $userId
  34. * @param $marketId
  35. * @param $type
  36. * @param $storeTypeIds
  37. * @return array
  38. */
  39. public function allForOrderOlAvailable($totalAmount, $userId, $marketId, $type, $storeTypeIds = [])
  40. {
  41. // 用户今日使用过的优惠券
  42. $redis = ApplicationContext::getContainer()->get(Redis::class);
  43. $couponTodayUsedIds = $redis->sMembers('coupon_'.date('Ymd').'_used_'.$userId);
  44. $currentTime = time();
  45. $builder = Db::table('lanzu_coupon_receive as receive')
  46. ->join('lanzu_coupon as coupon', 'coupon.id', '=', 'receive.coupon_id', 'inner');
  47. if (is_array($couponTodayUsedIds)&&!empty($couponTodayUsedIds)) {
  48. $builder->whereNotIn('coupon.id', $couponTodayUsedIds);
  49. }
  50. foreach ($storeTypeIds as $key => &$item) {
  51. $item = (string)$item;
  52. }
  53. if (!empty($storeTypeIds)) {
  54. $builder->whereJsonContains('coupon.category_ids', $storeTypeIds);
  55. }
  56. $builder->where(['receive.user_id' => $userId])
  57. ->whereIn('receive.status', [0,1])
  58. ->where('receive.number_remain', '>', 0)
  59. ->whereIn('coupon.type', [1,$type])
  60. ->where('coupon.full_amount', '<=', $totalAmount)
  61. ->where('coupon.usable_start_time', '<=', $currentTime)
  62. ->where('coupon.usable_end_time', '>=', $currentTime)
  63. ->where('coupon.usable_number', '<=', Db::raw('receive.number_remain'));
  64. if ($marketId) {
  65. $builder->whereJsonContains('coupon.market_ids', [(string)$marketId]);
  66. }
  67. return $builder->orderByRaw('coupon.discounts DESC, coupon.full_amount DESC')
  68. ->get()
  69. ->toArray();
  70. }
  71. /**
  72. * 用户优惠券列表
  73. * @param $userId
  74. * @param $type
  75. * @param int $page
  76. * @param int $pagesize
  77. * @return array
  78. */
  79. public function getListByUser($userId,$type,$page = 1,$pagesize = 5)
  80. {
  81. //查询优惠券
  82. $builder = CouponRec::query()->join('lanzu_coupon', 'lanzu_coupon.id', '=', 'lanzu_coupon_receive.coupon_id')
  83. ->where([
  84. ['lanzu_coupon_receive.user_id' ,'=', $userId],
  85. ]);
  86. /**
  87. * $type unused 未使用 used 已使用 expired 已失效
  88. */
  89. switch ($type){
  90. case 'unused':
  91. $builder = $builder->where([
  92. ['lanzu_coupon.usable_end_time' ,'>', time()],
  93. ['lanzu_coupon_receive.number_remain' ,'>', 0]
  94. ])
  95. ->whereIn('lanzu_coupon_receive.status',[0,1]);
  96. break;
  97. case 'used':
  98. $builder = $builder->whereIn('lanzu_coupon_receive.status',[1,2]);
  99. break;
  100. case 'expired':
  101. $builder = $builder->where(function ($query) {
  102. $query->where('lanzu_coupon.usable_end_time', '<', time())
  103. ->orWhere('lanzu_coupon.status', '<>', 1);
  104. });
  105. break;
  106. }
  107. $builder = $builder->select(
  108. 'lanzu_coupon.title',
  109. 'lanzu_coupon.discounts',
  110. 'lanzu_coupon.full_amount',
  111. 'lanzu_coupon.discount_type',
  112. 'lanzu_coupon.introduce',
  113. 'lanzu_coupon.usable_start_time',
  114. 'lanzu_coupon.usable_end_time',
  115. 'lanzu_coupon_receive.number',
  116. 'lanzu_coupon_receive.number_remain'
  117. )
  118. ->orderBy('lanzu_coupon.weigh','desc');
  119. $paginate = $builder->paginate($pagesize);
  120. $couponList = $paginate->toArray();
  121. foreach ($couponList['data'] as $key => &$coupon) {
  122. //拼接满减文字提示
  123. $coupon['full_amount_text'] = '满' . $coupon['full_amount'] . "可用";
  124. //判断是折扣优惠券还是满减优惠券
  125. if($coupon['discount_type'] == 1){
  126. $coupon['discounts_text'] = '¥'.$coupon['discounts'];
  127. }elseif($coupon['discount_type'] == 2){
  128. $coupon['discounts_text'] = floatval($coupon['discounts'])."";
  129. }
  130. //拼接时间文字提示
  131. $coupon['time_text'] = date("Y-m-d H:i:s",$coupon['usable_start_time']). ' - ' .date("Y-m-d H:i:s",$coupon['usable_end_time']);
  132. }
  133. return ['has_more_pages' => $paginate->hasMorePages(), 'coupon_list' => $couponList['data']];
  134. }
  135. /**
  136. * 获取用户当前线上订单可以使用的优惠券
  137. * 1、所有未过期额优惠券,并且满足订单的金额要求
  138. * 2、筛选出其中当日使用过的优惠券
  139. * 3、筛选出其中活动商品不可用的优惠券(订单中有活动商品且活动商品不可使用优惠券)
  140. * 4、筛选出其中活动商品可用但商品的活动类型不符合优惠券活动使用类型的要求(订单中有活动商品可以用优惠券,但是活动类型type和优惠券中的available活动类型不可用)
  141. * @param $userId
  142. * @param $marketId
  143. */
  144. public function allForOnlineOrderAvailable($userId, $marketId)
  145. {
  146. // 获取购物车数据
  147. $carts = $this->shopCartService->allForUser($userId, $marketId);
  148. $totalAmount = $carts['total'];
  149. // 获取购物车中商品和店铺的类别
  150. $storeCategoryIds = [];
  151. $goodsCategoryIds = [];
  152. foreach ($carts as $key => &$cart) {
  153. if (isset($cart['store']['category_id']) && $cart['store']['category_id']) {
  154. array_push($storeCategoryIds, $cart['store']['category_id']);
  155. }
  156. if (isset($cart['shopping_cart']) && is_array($cart['shopping_cart'])) {
  157. foreach ($cart['shopping_cart'] as $key2 => &$goods) {
  158. if (isset($goods['goods']['category_id']) && $goods['goods']['category_id']) {
  159. array_push($goodsCategoryIds, $goods['goods']['category_id']);
  160. }
  161. }
  162. }
  163. }
  164. $categoryIds = array_merge($storeCategoryIds, $goodsCategoryIds);
  165. $coupon = ApplicationContext::getContainer()->get(Coupon::class);
  166. $couponRec = ApplicationContext::getContainer()->get(Coupon::class);
  167. $couponTable = $coupon->getTable();
  168. $receiveTable = $couponRec->getTable();
  169. $currentTime = time();
  170. // 获取用户已领取的优惠券,同时是在使用期内的优惠券
  171. $builder = $couponRec->join($couponTable, "{$couponTable}.id", "=", "{$receiveTable}.coupon_id")
  172. ->where("{$receiveTable}.user_id", $userId)
  173. ->where("{$receiveTable}.number_remain", ">", 0)
  174. ->whereIn("{$receiveTable}.status", [0,1])
  175. ->where("{$couponTable}.usable_start_time", "<=", $currentTime)
  176. ->where("{$couponTable}.usable_end_time", ">=", $currentTime);
  177. if (!empty($marketId)) { # 市场限制
  178. $builder->where(function ($query) use ($marketId, $couponTable) {
  179. return $query->whereJsonContains("{$couponTable}.market_ids", [(string)$marketId])
  180. ->orWhereJsonLength("{$couponTable}.market_ids", '=', 0);
  181. });
  182. }
  183. if (!empty($categoryIds)) { # 分类限制
  184. $builder->where(function ($query) use ($categoryIds, $couponTable) {
  185. return $query->whereJsonContains("{$couponTable}.category_ids", $categoryIds)
  186. ->orWhereJsonLength("{$couponTable}.category_ids", '=', 0);
  187. });
  188. }
  189. $couponReceives = $builder->orderByRaw("{$couponTable}.usable_end_time ASC")->get();
  190. // 循环摘出失效不可用的优惠券
  191. foreach ($couponReceives as $key => &$couponReceive) {
  192. // 有活动商品不可用优惠券,全部都不可用了
  193. // 不满订单金额
  194. // 今日已使用
  195. }
  196. }
  197. }