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.

275 lines
8.7 KiB

5 years ago
5 years ago
5 years ago
  1. <?php
  2. namespace App\Service;
  3. use Hyperf\Di\Annotation\Inject;
  4. use Hyperf\DbConnection\Db;
  5. use App\Model\CouponUserRecType;
  6. use App\Model\Coupon;
  7. use App\Model\CouponRec;
  8. use App\Model\CouponUserUse;
  9. use Hyperf\Utils\ApplicationContext;
  10. use App\TaskWorker\SSDBTask;
  11. use App\Constants\SsdbKeysPrefix;
  12. use App\Constants\LogLabel;
  13. use App\Commons\Log;
  14. use Exception;
  15. use App\Service\CommonService;
  16. use Hyperf\Redis\Redis;
  17. class CouponService implements CouponServiceInterface
  18. {
  19. /**
  20. * @Inject
  21. * @var Log
  22. */
  23. protected $log;
  24. /**
  25. * @Inject
  26. * @var CommonService
  27. */
  28. protected $commonService;
  29. /**
  30. * 获取用户可领取优惠卷接口
  31. */
  32. public function getSystemCouponUserList($userId,$receiveType)
  33. {
  34. /* 优惠券活动标志 2 */
  35. $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
  36. $couponActivity = $ssdb->exec('hgetall', SsdbKeysPrefix::COUPON_REBATE_ACTIVITY);
  37. $activityType = $couponActivity === false ? 0 : $couponActivity['activity'];
  38. $result = [
  39. 'active_type' => 1,
  40. 'not_receive' => [],
  41. 'jump_data' => [
  42. 'src' => "/zh_cjdianc/pages/couponrebate/index?activity_type=".$activityType,
  43. 'src2' => "/zh_cjdianc/pages/couponrebate/index?activity_type=".$activityType,
  44. 'share_bg' => env('OSS_IMG_HOST').'/static/img/coupon_share.png',
  45. 'receive_bg' => env('OSS_IMG_HOST').'/static/img/coupon_bg.png',
  46. 'coupons' => []
  47. ]
  48. ];
  49. $nowTime = time();
  50. $c_ids = [];
  51. $whereC = [
  52. ['end_time','>',$nowTime],
  53. ['start_time','<=',$nowTime],
  54. ['status','=',1]
  55. ];
  56. // 渠道开启,查询该渠道可以领取的优惠券ID
  57. // 渠道未开启,查询所有优惠券
  58. if (env('SUB_CHANNEL') == 1) {
  59. $c_ids = CouponUserRecType::where('receive_type', $receiveType)->where($whereC)->pluck('system_coupon_user_id');
  60. } else {
  61. $c_ids = Coupon::where($whereC)->pluck('id');
  62. }
  63. $couponReceive = CouponRec::where('user_id',$userId);
  64. // 渠道开启,查询该用户在此渠道领过的优惠券ID
  65. if (env('SUB_CHANNEL') == 1) {
  66. $couponReceive->where('receive_type', $receiveType);
  67. }
  68. $cr_ids = $couponReceive->pluck('system_coupon_user_id');
  69. // 可领取的券ID
  70. $c_ids = $c_ids->toArray();
  71. // 已经领取的券ID
  72. $cr_ids = $cr_ids->toArray();
  73. // 当前用户可领的优惠券ID
  74. $couponIds = array_diff($c_ids, $cr_ids);
  75. // 转发型优惠券
  76. $couponReceiveIds = ($couponActivity === false || $this->commonService->empty($couponActivity['forward']) )? [] : explode(',',$couponActivity['forward']);
  77. // 所有优惠券
  78. $couponIds = array_merge($couponIds,$couponReceiveIds);
  79. $whereC = [
  80. ['u.end_time','>',$nowTime],
  81. ['u.start_time','<=',$nowTime],
  82. ['u.status','=',1]
  83. ];
  84. // 查询领取型1 和 转发型2
  85. $whereActiveType = [1,2];
  86. if (env('SUB_CHANNEL') == 1) {
  87. array_push($whereC, ['type.receive_type','=', $receiveType]);
  88. }
  89. $coupons = Db::table('ims_system_coupon_user as u')
  90. ->join('ims_system_coupon_user_receivetype as type', 'u.id', '=', 'type.system_coupon_user_id')
  91. ->whereIn('u.id', $couponIds)
  92. ->whereIn('u.active_type', $whereActiveType)
  93. ->where($whereC)
  94. ->whereRaw('u.inventory_use < u.inventory and u.inventory-u.inventory_use >= type.one_receive_number')
  95. ->select('u.*','type.one_receive_number')
  96. ->orderBy('u.weigh','desc')
  97. ->get();
  98. foreach ($coupons as $k => &$v){
  99. if($v->active_type == 1 && count($result['not_receive']) < 4){
  100. $result['not_receive'][] = $v;
  101. }else if($v->active_type == 2 && in_array($v->id,$couponReceiveIds)){
  102. $result['jump_data']['coupons'][] = $v->id;
  103. }
  104. if($v->discount_type == 2){
  105. $v->discounts = floatval($v->discounts);
  106. }
  107. }
  108. $result['active_type'] = count($result['jump_data']['coupons']) > 0 ? 2 : $result['active_type'] ;
  109. return $result;
  110. }
  111. //统计用户
  112. public function userCouponAccount()
  113. {
  114. }
  115. /**
  116. * 用户领取优惠卷
  117. */
  118. public function userReceiveCoupon()
  119. {
  120. }
  121. /**
  122. * 获取用户已经领取的优惠卷列表
  123. */
  124. public function getUserReceiveCouponList()
  125. {
  126. }
  127. /**
  128. * 获取用户当前订单可用的优惠券列表
  129. * 按分类(1订单 等优惠)分组返回
  130. */
  131. public function getUserAvailableCoupons()
  132. {
  133. }
  134. /**
  135. * @inheritDoc
  136. */
  137. public function getOrderCanUseCoupons($orderAmount, $marketId, $userId, $fields=[], $type = 1, $storeTypeIds = [0])
  138. {
  139. // 用户今日使用过的优惠券
  140. $redis = ApplicationContext::getContainer()->get(Redis::class);
  141. $couponTodayUsedIds = $redis->sMembers('coupon_'.date('Ymd').'_used_'.$userId);
  142. $currentTime = time();
  143. $builder = Db::table('ims_system_coupon_user_receive as receive')
  144. ->join('ims_system_coupon_user as coupon', 'coupon.id', '=', 'receive.system_coupon_user_id', 'inner');
  145. if (is_array($fields)&&!empty($fields)) {
  146. $builder->select($fields);
  147. }
  148. if (is_array($couponTodayUsedIds)&&!empty($couponTodayUsedIds)) {
  149. $builder->whereNotIn('coupon.id', $couponTodayUsedIds);
  150. }
  151. return $builder->where(['receive.user_id' => $userId])
  152. ->whereIn('receive.status', [0,1])
  153. ->where('receive.number_remain', '>', 0)
  154. ->whereIn('coupon.type', [1,$type])
  155. ->where('coupon.full_amount', '<=', $orderAmount)
  156. ->where('coupon.usable_start_time', '<=', $currentTime)
  157. ->where('coupon.usable_end_time', '>=', $currentTime)
  158. ->where('coupon.usable_number', '<=', Db::raw('receive.number_remain'))
  159. ->where('coupon.market_id', 'in', [0, $marketId])
  160. ->whereIn('coupon.storetype_id', $storeTypeIds)
  161. ->orderByRaw('coupon.discounts DESC, coupon.full_amount DESC')
  162. ->get()
  163. ->toArray();
  164. }
  165. /**
  166. * 缓存优惠券今日使用情况
  167. * @param $userId
  168. * @param $couponId
  169. * @param $couponRecId
  170. * @return bool
  171. */
  172. function cacheTodayCouponUsed($userId, $couponId, $couponRecId)
  173. {
  174. $redis = ApplicationContext::getContainer()->get(Redis::class);
  175. $setRes = $redis->sAdd(
  176. 'coupon_'.date('Ymd').'_used_'.$userId,
  177. $couponId
  178. );
  179. $expireRes = $redis->expire(
  180. 'coupon_'.date('Ymd').'_used_'.$userId,
  181. strtotime(date('Y-m-d').' 23:59:59')-time()
  182. );
  183. return $setRes&&$expireRes;
  184. }
  185. /**
  186. * 取消订单返券
  187. * @param $order_id
  188. * @return bool
  189. */
  190. public function refundOrderCoupons($order_id,$user_id){
  191. $coupon = CouponUserUse::where([
  192. ['order_main_id','=',$order_id],
  193. ['status','=',CouponUserUse::COUPON_USE_STATE_USED],
  194. ])
  195. ->select('id','user_receive_id','number')
  196. ->first();
  197. // 返回用户优惠券数量并更新状态
  198. $res = Db::update("UPDATE ims_system_coupon_user_receive SET number_remain=number_remain+{$coupon->number}, status=IF(number=number_remain,0,1), update_time=".time().""
  199. ." WHERE id={$coupon->user_receive_id} AND number>=(number_remain+{$coupon->number})");
  200. // 更新使用记录状态为已退回
  201. CouponUserUse::where([
  202. ['id','=',$coupon->id],
  203. ['status','=',CouponUserUse::COUPON_USE_STATE_USED],
  204. ])
  205. ->update([
  206. 'status' => CouponUserUse::COUPON_USE_STATE_CANCEL,
  207. 'return_time' => time(),
  208. 'update_time' => time(),
  209. ]);
  210. //删除当日 redis 使用记录缓存
  211. $redis = ApplicationContext::getContainer()->get(Redis::class);
  212. $remRes = $redis->sRem(
  213. 'coupon_'.date('Ymd').'_used_'.$user_id,
  214. $coupon->system_coupon_id
  215. );
  216. return $res;
  217. }
  218. /* 删除-优惠券今日使用的缓存
  219. * @param $userId
  220. * @param $couponId
  221. * @param $couponRecId
  222. * @return bool
  223. */
  224. function clearTodayCouponUsed($userId, $couponId)
  225. {
  226. $redis = ApplicationContext::getContainer()->get(Redis::class);
  227. $res = $redis->sRem(
  228. 'coupon_'.date('Ymd').'_used_'.$userId,
  229. $couponId
  230. );
  231. }
  232. }