CouponService.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <?php
  2. namespace app\admin\service\coupon;
  3. use app\model\Coupon;
  4. use app\model\CouponDetail;
  5. use app\model\Goods;
  6. use support\Db;
  7. use support\exception\BusinessException;
  8. use support\Log;
  9. class CouponService
  10. {
  11. /**
  12. * @Desc 优惠券自动过期
  13. * @Author Gorden
  14. * @Date 2024/8/26 17:58
  15. *
  16. * @return void
  17. */
  18. public static function checkCouponExpired()
  19. {
  20. $couponDetails = Db::select("select * from app_coupon_detail where (coupon_detail_status = 'INIT' OR coupon_detail_status = 'PENDING' OR coupon_detail_status = 'ACTIVED' OR coupon_detail_status = 'WAITING') AND coupon_detail_deadline_datetime != '' AND CAST(UNIX_TIMESTAMP(coupon_detail_deadline_datetime) as SIGNED) < " . time());
  21. foreach ($couponDetails as $detail) {
  22. $endTimeUnix = strtotime($detail->coupon_detail_deadline_datetime);
  23. if ($endTimeUnix < time()) {
  24. CouponDetail::where('coupon_detail_id', $detail->coupon_detail_id)->update(['coupon_detail_status' => 'EXPIRED']);
  25. echo $detail->coupon_detail_id . "已过期\n";
  26. }
  27. }
  28. }
  29. /**
  30. * @Desc
  31. * @Author Gorden
  32. * @Date 2024/9/18 11:44
  33. *
  34. * @return void
  35. */
  36. public static function sendPeriodCoupon()
  37. {
  38. Db::beginTransaction();
  39. try {
  40. $coupons = Coupon::where('coupon_is_period', 'Y')->where('coupon_status', 'ACTIVED')->get()->toArray();
  41. // dump("周期全",$coupons);
  42. foreach ($coupons as $coupon) {
  43. if (!empty($coupon['coupon_validdate_end']) && time() > strtotime($coupon['coupon_validdate_end'])) {
  44. continue;
  45. }
  46. $details = CouponDetail::where('join_detail_coupon_id', $coupon['coupon_id'])
  47. ->where('join_coupon_detail_member_id', '<>', '')
  48. ->selectRaw('join_coupon_detail_member_id,COUNT(*) as count')
  49. ->groupBy('join_coupon_detail_member_id')
  50. ->get();
  51. foreach ($details as $item) {
  52. $detail = CouponDetail::where('join_detail_coupon_id', $coupon['coupon_id'])
  53. ->where('join_coupon_detail_member_id', $item->join_coupon_detail_member_id)
  54. ->orderBy('coupon_detail_addtimes', 'DESC')
  55. ->first();
  56. if (strtotime($detail->coupon_detail_deadline_datetime) > time()) {
  57. continue;
  58. } elseif (empty($coupon['coupon_validdate_end']) && !empty($coupon['coupon_validdate_day'])) {
  59. $firstDetail = CouponDetail::where('join_detail_coupon_id', $coupon['coupon_id'])
  60. ->where('join_coupon_detail_member_id', $item->join_coupon_detail_member_id)
  61. ->orderBy('coupon_detail_addtimes', 'ASC')
  62. ->first();
  63. if ((time() - strtotime($firstDetail->coupon_detail_addtimes)) > (3600 * 24 * $coupon['coupon_validdate_day'])) {
  64. continue;
  65. }
  66. }
  67. $params = [
  68. 'coupon_detail_gain_datetime' => date('Y-m-d 00:00:00'),
  69. 'coupon_id' => $coupon['coupon_id'],
  70. 'member_id' => $detail->join_coupon_detail_member_id,
  71. 'coupon_detail_period_num' => $detail->coupon_detail_period_num + 1
  72. ];
  73. // 超出期数
  74. if (!empty($coupon['coupon_period_json'])) {
  75. $periodJson = json_decode($coupon['coupon_period_json'], true);
  76. if ($periodJson['nbr'] < $params['coupon_detail_period_num']) {
  77. continue;
  78. }
  79. if ($periodJson['unit'] == 'day') {
  80. $val = $periodJson['val'] - 1;
  81. if ($val < 1) {
  82. $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59');
  83. } else {
  84. $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime("+" . $val . " day"));
  85. }
  86. } elseif ($periodJson['unit'] == 'week') {
  87. $val = $periodJson['val'] - 1;
  88. if ($val < 1) {
  89. $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime('this week Sunday'));
  90. } else {
  91. $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime("+" . $val . ' week', date('Y-m-d', strtotime("+" . $val . " month"))));
  92. }
  93. } elseif ($periodJson['unit'] == 'month') {
  94. $val = $periodJson['val'] - 1;
  95. if ($val < 1) {
  96. $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59');
  97. } else {
  98. $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime("+" . $val . " month"));
  99. }
  100. }
  101. }
  102. if (CouponDetail::whereIn('coupon_detail_status', ['INIT', 'PENDING'])->exists()) {
  103. // 匹配已发行的优惠券
  104. $params['chooseCouponNbr'] = 1;
  105. CouponDetailService::customSendCouponHave($params);
  106. } else {
  107. // 写入优惠券
  108. CouponDetailService::customSendCoupon($params);
  109. }
  110. _syslog("周期券", "发放周期券", false, $params, 1001);
  111. }
  112. }
  113. Db::commit();
  114. } catch (\Exception $e) {
  115. dump($e->getTrace());
  116. Db::rollBack();
  117. }
  118. }
  119. public static function couponClassifyInfo($classify, $category, $value, $limit)
  120. {
  121. try {
  122. switch ($classify) {
  123. case "满减券":
  124. if (!empty($limit) && $category == 'NORMAL') {
  125. return "满" . $limit . '减' . $value;
  126. } elseif (!empty($limit) && !empty($value) && $category == 'PIECE') {
  127. return "满" . intval($limit) . '件减' . $value;
  128. }
  129. break;
  130. case "立减券":
  131. return "立减" . $value;
  132. break;
  133. case "抵用券":
  134. return "抵用券";
  135. break;
  136. case "折扣券":
  137. if (!empty($limit) && $category == 'NORMAL') {
  138. return "满" . $limit . '打' . ($value / 10) . '折';
  139. } else if (!empty($limit) && !empty($value) && $category == 'PIECE') {
  140. return "满" . intval($limit) . '件打' . ($value / 10) . '折';
  141. } else {
  142. return $value / 10 . '折';
  143. }
  144. break;
  145. case "赠品券":
  146. return "赠品券";
  147. break;
  148. case "福利券":
  149. return '抵扣' . $value;
  150. break;
  151. case "年卡":
  152. return "年卡";
  153. break;
  154. case "季卡":
  155. return "季卡";
  156. break;
  157. case "月卡":
  158. return "月卡";
  159. break;
  160. }
  161. } catch (\Exception $e) {
  162. }
  163. }
  164. /**
  165. * @Desc
  166. * @Author Gorden
  167. * @Date 2024/9/28 14:00
  168. *
  169. * @param $params
  170. * join_sheet_goods_id 关联测产品
  171. * member_id 接收人
  172. * @return void
  173. * @throws BusinessException
  174. */
  175. public static function autoSendCouponByGoods($params)
  176. {
  177. try {
  178. $gettype = $params['gettype'] ?? '';
  179. $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])->select('goods_attribute_json')->first();
  180. if (!empty($goods) && !empty($goods->goods_attribute_json)) {
  181. $goodsAttributeJson = json_decode($goods->goods_attribute_json, true);
  182. if (!empty($goodsAttributeJson['coupon'])) {
  183. foreach ($goodsAttributeJson['coupon'] as $key => $coupon) {
  184. $couponModel = Coupon::where('coupon_id', $key)->select('coupon_id', 'coupon_validdate_day', 'coupon_validdate_end', 'coupon_is_period', 'coupon_number')->first();
  185. if (empty($couponModel)) {
  186. continue;
  187. }
  188. // 券是否过期
  189. if (!empty($couponModel->coupon_validdate_end) && strtotime($couponModel->coupon_validdate_end) < time()) {
  190. continue;
  191. }
  192. // 发周期券
  193. if ($couponModel->coupon_is_period == 'Y') {
  194. // 发券参数
  195. $couponSendParams = ['gettype' => $gettype, 'coupon_id' => $key, 'member_id' => $params['member_id']];
  196. Log::info("发周期券参数", $couponSendParams);
  197. CouponDetailService::sendPeriodCoupon($couponSendParams);
  198. continue;
  199. }
  200. $couponResidue = 'all';
  201. if ($couponModel->coupon_number != 0) {
  202. $couponResidue = CouponDetail::where('join_detail_coupon_id', $key)->whereIn('coupon_detail_status', ['INIT', 'PENDING'])->count();
  203. // 超出优惠券设置的数量
  204. if ($couponResidue < $coupon['num']) {
  205. continue;
  206. }
  207. }
  208. $endDate = '';
  209. if (!empty($couponModel->coupon_validdate_end)) {
  210. $endDate = $couponModel->coupon_validdate_end;
  211. } elseif ($couponModel->coupon_validdate_day > 0) {
  212. $endDate = date('Y-m-d H:i:s', time() + ($couponModel->coupon_validdate_day * 24 * 3600) - 1);
  213. }
  214. // 发券参数
  215. $couponSendParams = [
  216. 'gettype' => $gettype,
  217. 'coupon_id' => $key,
  218. 'chooseCouponNbr' => $coupon['num'],
  219. 'member_id' => $params['member_id'],
  220. 'coupon_detail_gain_datetime' => date('Y-m-d H:i:s'),
  221. 'coupon_detail_deadline_datetime' => $endDate,
  222. ];
  223. Log::info("发普通券参数", $couponSendParams);
  224. if ($couponResidue != 'all' && $couponResidue - $coupon['num'] >= 0) {
  225. CouponDetailService::customSendCouponHave($couponSendParams);
  226. } else {
  227. for ($i = 0; $i < $coupon['num']; $i++) {
  228. CouponDetailService::customSendCoupon($couponSendParams);
  229. }
  230. }
  231. }
  232. }
  233. }
  234. }catch (\Exception $e){
  235. Log::info("优惠券发放失败:".$e->getMessage());
  236. throw new BusinessException("优惠券发放失败");
  237. }
  238. }
  239. }