CouponDetailService.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <?php
  2. namespace app\admin\service\coupon;
  3. use app\model\Coupon;
  4. use app\model\CouponDetail;
  5. use app\model\SysSerial;
  6. use support\Db;
  7. use support\exception\BusinessException;
  8. use support\Log;
  9. class CouponDetailService
  10. {
  11. /**
  12. * @Desc 手动发券
  13. * @Author Gorden
  14. * @Date 2024/8/27 9:57
  15. *
  16. * @param $params
  17. * @return void
  18. * @throws BusinessException
  19. */
  20. public static function customSendCoupon($params)
  21. {
  22. $gettype = 'SEND';
  23. if (!empty($params['gettype'])) {
  24. $gettype = $params['gettype'];
  25. }
  26. try {
  27. CouponDetail::insert([
  28. 'coupon_detail_id' => 'CUDT' . date("ymdHi") . random_string(4, 'up'),
  29. 'join_detail_coupon_id' => $params['coupon_id'],
  30. 'join_coupon_detail_member_id' => $params['member_id'],
  31. 'coupon_detail_status' => 'ACTIVED',
  32. 'coupon_detail_gain_datetime' => $params['coupon_detail_gain_datetime'],
  33. 'coupon_detail_deadline_datetime' => $params['coupon_detail_deadline_datetime'],
  34. 'coupon_detail_period_num' => $params['coupon_detail_period_num'] ?? 0,
  35. 'coupon_detail_extend_json' => json_encode(['gettype' => $gettype, 'order_id' => $params['order_id'] ?? '']),
  36. 'coupon_detail_addtimes' => time(),
  37. ]);
  38. } catch (\Exception $e) {
  39. throw new BusinessException('写入优惠券失败');
  40. }
  41. }
  42. public static function customSendCouponHave($params)
  43. {
  44. $gettype = 'SEND';
  45. if (!empty($params['gettype'])) {
  46. $gettype = $params['gettype'];
  47. }
  48. try {
  49. CouponDetail::where('join_detail_coupon_id', $params['coupon_id'])
  50. ->whereIn('coupon_detail_status', ['INIT', 'PENDING'])
  51. ->limit($params['chooseCouponNbr'])
  52. ->update([
  53. 'join_coupon_detail_member_id' => $params['member_id'],
  54. 'coupon_detail_gain_datetime' => $params['coupon_detail_gain_datetime'],
  55. 'coupon_detail_deadline_datetime' => $params['coupon_detail_deadline_datetime'],
  56. 'coupon_detail_extend_json' => json_encode(['gettype' => $gettype, 'order_id' => $params['order_id'] ?? '']),
  57. 'coupon_detail_period_num' => $params['coupon_detail_period_num'] ?? 0,
  58. 'coupon_detail_status' => 'ACTIVED',
  59. 'coupon_detail_addtimes' => time()
  60. ]);
  61. } catch (\Exception $e) {
  62. throw new BusinessException('写入优惠券失败');
  63. }
  64. }
  65. /**
  66. * @Desc 发周期优惠券 - 没有发行数量
  67. * @Author Gorden
  68. * @Date 2024/9/27 13:44
  69. *
  70. * @param $params
  71. * @return void
  72. */
  73. public static function sendPeriodCoupon($params)
  74. {
  75. Db::beginTransaction();
  76. try {
  77. $coupon = Coupon::where('coupon_id', $params['coupon_id'])->first();
  78. if ($coupon->coupon_is_period != 'Y') {
  79. return;
  80. }
  81. $detailCount = -1;
  82. if ($coupon->coupon_number > 0) {
  83. $detailCount = CouponDetail::where('join_detail_coupon_id', $params['coupon_id'])->whereIn('coupon_detail_status', ['INIT', 'PENDING'])->count();
  84. }
  85. $periodJson = json_decode($coupon->coupon_period_json, true);
  86. if ($detailCount != -1 && $detailCount - $periodJson['nbr'] < 0) {
  87. throw new BusinessException("优惠券余量不足");
  88. }
  89. $periodJson['now_nbr'] = 1;
  90. // 手动发券会传来时间
  91. $periodJson['gain_datetime'] = $params['coupon_detail_gain_datetime'] ?? date('Y-m-d H:i:s');
  92. if (!empty($periodJson['nbr'])) {
  93. for ($i = 0; $i < $periodJson['nbr']; $i++) {
  94. $periodParams = self::generatePeriod($periodJson);
  95. $periodParams['gettype'] = $params['gettype'] ?? '';
  96. $periodParams['order_id'] = $params['order_id'] ?? '';
  97. $periodParams['coupon_id'] = $params['coupon_id'];
  98. $periodParams['member_id'] = $params['member_id'];
  99. $periodParams['coupon_detail_period_num'] = $periodJson['now_nbr'];
  100. if ($detailCount > 0) {
  101. $periodParams['chooseCouponNbr'] = 1;
  102. self::sendPeriodCouponHave($periodParams);
  103. } else {
  104. self::sendPeriodCouponNoLimit($periodParams);
  105. }
  106. $periodJson['now_nbr'] += 1;
  107. }
  108. }
  109. Db::commit();
  110. } catch (BusinessException $e) {
  111. Db::rollBack();
  112. Log::error("发券失败:" . $e->getMessage());
  113. throw new BusinessException($e->getMessage());
  114. } catch (\Exception $e) {
  115. Db::rollBack();
  116. Log::error("发券失败:" . $e->getMessage());
  117. throw new BusinessException("优惠券发放失败");
  118. }
  119. }
  120. /**
  121. * @Desc 有发行数量
  122. * @Author Gorden
  123. * @Date 2024/9/27 13:45
  124. *
  125. * @param $params
  126. * @return void
  127. */
  128. public static function sendPeriodCouponHave($params)
  129. {
  130. $gettype = 'SEND';
  131. if (!empty($params['gettype'])) {
  132. $gettype = $params['gettype'];
  133. }
  134. try {
  135. CouponDetail::where('join_detail_coupon_id', $params['coupon_id'])
  136. ->whereIn('coupon_detail_status', ['INIT', 'PENDING'])
  137. ->limit($params['chooseCouponNbr'])
  138. ->update([
  139. 'join_coupon_detail_member_id' => $params['member_id'],
  140. 'coupon_detail_gain_datetime' => $params['coupon_detail_gain_datetime'],
  141. 'coupon_detail_deadline_datetime' => $params['coupon_detail_deadline_datetime'],
  142. 'coupon_detail_extend_json' => json_encode(['gettype' => $gettype, 'order_id' => $params['order_id'] ?? '']),
  143. 'coupon_detail_period_num' => $params['coupon_detail_period_num'] ?? 0,
  144. 'coupon_detail_status' => 'ACTIVED',
  145. 'coupon_detail_addtimes' => time()
  146. ]);
  147. } catch (\Exception $e) {
  148. dump($e->getMessage());
  149. throw new BusinessException('写入优惠券失败');
  150. }
  151. }
  152. /**
  153. * @Desc 发行量不限
  154. * @Author Gorden
  155. * @Date 2024/9/27 16:19
  156. *
  157. * @param $params
  158. * @return void
  159. * @throws BusinessException
  160. */
  161. public static function sendPeriodCouponNoLimit($params)
  162. {
  163. $gettype = 'SEND';
  164. if (!empty($params['gettype'])) {
  165. $gettype = $params['gettype'];
  166. }
  167. try {
  168. CouponDetail::insert([
  169. 'coupon_detail_id' => 'CUDT' . date("ymdHi") . random_string(4, 'up'),
  170. 'join_detail_coupon_id' => $params['coupon_id'],
  171. 'join_coupon_detail_member_id' => $params['member_id'],
  172. 'coupon_detail_status' => 'ACTIVED',
  173. 'coupon_detail_gain_datetime' => $params['coupon_detail_gain_datetime'],
  174. 'coupon_detail_deadline_datetime' => $params['coupon_detail_deadline_datetime'],
  175. 'coupon_detail_period_num' => $params['coupon_detail_period_num'] ?? 0,
  176. 'coupon_detail_extend_json' => json_encode(['gettype' => $gettype, 'order_id' => $params['order_id'] ?? '']),
  177. 'coupon_detail_addtimes' => time(),
  178. ]);
  179. } catch (\Exception $e) {
  180. throw new BusinessException('写入优惠券失败');
  181. }
  182. }
  183. /**
  184. * @Desc
  185. * @Author Gorden
  186. * @Date 2024/9/27 13:54
  187. *
  188. * @param $periodJson
  189. * @return array
  190. */
  191. public static function generatePeriod($periodJson)
  192. {
  193. // 当前第几期
  194. $now_nbr = $periodJson['now_nbr'];
  195. $params = [];
  196. if ($periodJson['unit'] == 'day') {
  197. $val = $periodJson['val'] - 1;
  198. if ($val < 1) {
  199. if ($now_nbr == 1) {
  200. $params['coupon_detail_gain_datetime'] = date('Y-m-d 00:00:00', strtotime($periodJson['gain_datetime']));
  201. $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime($periodJson['gain_datetime']));
  202. } else {
  203. $now_nbr -= 1;
  204. $params['coupon_detail_gain_datetime'] = date('Y-m-d 00:00:00', strtotime($periodJson['gain_datetime'] . "+" . $now_nbr . ' day'));
  205. $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime($periodJson['gain_datetime'] . "+" . $now_nbr . ' day'));
  206. }
  207. } else {
  208. if ($now_nbr == 1) {
  209. $params['coupon_detail_gain_datetime'] = date('Y-m-d 00:00:00', strtotime($periodJson['gain_datetime']));
  210. $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime($periodJson['gain_datetime'] . "+" . $val . ' day'));
  211. } else {
  212. $now_nbr -= 1;
  213. $params['coupon_detail_gain_datetime'] = date('Y-m-d 00:00:00', strtotime($periodJson['gain_datetime'] . "+" . ((($val + 1) * $now_nbr)) . " day"));
  214. $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime($periodJson['gain_datetime'] . "+" . ((($val + 1) * $now_nbr) + $val) . " day"));
  215. }
  216. }
  217. } elseif ($periodJson['unit'] == 'week') {
  218. $val = $periodJson['val'] - 1;
  219. // 选的日期的周一距离今周周一是几个周
  220. $timestamp = strtotime($periodJson['gain_datetime']);
  221. $gainWeekDay = date("w", $timestamp);
  222. $gainWeekAdd = date("w", $gainWeekDay) == 1 ? 0 : 1 - $gainWeekDay;
  223. $gainMonday = date("Y-m-d 00:00:00", strtotime("$gainWeekAdd days", $timestamp));
  224. $nowMonday = date('Y-m-d 00:00:00', strtotime('this week Monday'));
  225. $interval = (new \DateTime(date($gainMonday)))->diff(new \DateTime($nowMonday));
  226. $weekCut = $interval->days / 7;
  227. if (strtotime($periodJson['gain_datetime']) < time() && $weekCut > 0) {
  228. $weekCut = -$weekCut;
  229. }
  230. if ($val < 1) {
  231. if ($now_nbr == 1) {
  232. $params['coupon_detail_gain_datetime'] = $gainMonday;
  233. $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime($gainMonday . "+6 days"));
  234. } else {
  235. $now_nbr -= 1;
  236. $params['coupon_detail_gain_datetime'] = date('Y-m-d 00:00:00', strtotime(date('Y-m-d 00:00:00', strtotime('this week Monday')) . "+" . ($now_nbr + $weekCut) . ' week'));
  237. $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime(date('Y-m-d 23:59:59', strtotime('this week Sunday')) . "+" . ($now_nbr + $weekCut) . ' week'));
  238. }
  239. } else {
  240. if ($now_nbr == 1) {
  241. $params['coupon_detail_gain_datetime'] = $gainMonday;
  242. $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime(date('Y-m-d 23:59:59', strtotime('this week Sunday')) . "+" . ($val + $weekCut) . ' week'));
  243. } else {
  244. $now_nbr -= 1;
  245. $params['coupon_detail_gain_datetime'] = date('Y-m-d 00:00:00', strtotime(date('Y-m-d 00:00:00', strtotime('this week Monday')) . "+" . ((($val + 1) * $now_nbr) + $weekCut) . ' week'));
  246. $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime(date('Y-m-d 23:59:59', strtotime('this week Sunday')) . "+" . ((($val + 1) * $now_nbr) + $val + $weekCut) . ' week'));
  247. }
  248. }
  249. } elseif ($periodJson['unit'] == 'month') {
  250. $val = $periodJson['val'] - 1;
  251. // 选的日期的1号距离今月1号是几个月
  252. $interval = (new \DateTime(date('Y-m-02 00:00:00', strtotime($periodJson['gain_datetime']))))->diff(new \DateTime(date('Y-m-02 00:00:00')));
  253. $monthCut = $interval->m + ($interval->y * 12);
  254. if (strtotime($periodJson['gain_datetime']) < time() && $monthCut > 0) {
  255. $monthCut = -$monthCut;
  256. }
  257. if ($val < 1) {
  258. if ($now_nbr == 1) {
  259. $params['coupon_detail_gain_datetime'] = date('Y-m-01 00:00:00', strtotime($periodJson['gain_datetime']));
  260. $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime($periodJson['gain_datetime']));
  261. } else {
  262. $now_nbr -= 1;
  263. $params['coupon_detail_gain_datetime'] = date('Y-m-01 00:00:00', strtotime("+" . ($now_nbr + $monthCut) . ' month'));
  264. $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime(date('Y-m-01 00:00:00') . "+" . ($now_nbr + $monthCut) . ' month'));
  265. }
  266. } else {
  267. if ($now_nbr == 1) {
  268. $params['coupon_detail_gain_datetime'] = date('Y-m-01 00:00:00', strtotime($periodJson['gain_datetime']));
  269. $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime(date('Y-m-01 00:00:00') . "+" . ($val + $monthCut) . ' month'));
  270. } else {
  271. $now_nbr -= 1;
  272. $params['coupon_detail_gain_datetime'] = date('Y-m-01 00:00:00', strtotime("+" . ((($val + 1) * $now_nbr) + $monthCut) . ' month'));
  273. $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime(date('Y-m-01 00:00:00') . "+" . ((($val + 1) * $now_nbr) + $val + $monthCut) . ' month'));
  274. }
  275. }
  276. }
  277. return $params;
  278. }
  279. }