'CUDT' . date("ymdHi") . random_string(4, 'up'), 'join_detail_coupon_id' => $params['coupon_id'], 'join_coupon_detail_member_id' => $params['member_id'], 'coupon_detail_status' => 'ACTIVED', 'coupon_detail_gain_datetime' => $params['coupon_detail_gain_datetime'], 'coupon_detail_deadline_datetime' => $params['coupon_detail_deadline_datetime'], 'coupon_detail_period_num' => $params['coupon_detail_period_num'] ?? 0, 'coupon_detail_extend_json' => json_encode(['gettype' => $gettype]), 'coupon_detail_addtimes' => time(), ]); } catch (\Exception $e) { throw new BusinessException('写入优惠券失败'); } } public static function customSendCouponHave($params) { $gettype = 'SEND'; if (!empty($params['gettype'])) { $gettype = $params['gettype']; } try { CouponDetail::where('join_detail_coupon_id', $params['coupon_id']) ->whereIn('coupon_detail_status', ['INIT', 'PENDING']) ->limit($params['chooseCouponNbr']) ->update([ 'join_coupon_detail_member_id' => $params['member_id'], 'coupon_detail_gain_datetime' => $params['coupon_detail_gain_datetime'], 'coupon_detail_deadline_datetime' => $params['coupon_detail_deadline_datetime'], 'coupon_detail_extend_json' => json_encode(['gettype' => $gettype]), 'coupon_detail_period_num' => $params['coupon_detail_period_num'] ?? 0, 'coupon_detail_status' => 'ACTIVED', 'coupon_detail_addtimes' => time() ]); } catch (\Exception $e) { throw new BusinessException('写入优惠券失败'); } } /** * @Desc 发周期优惠券 - 没有发行数量 * @Author Gorden * @Date 2024/9/27 13:44 * * @param $params * @return void */ public static function sendPeriodCoupon($params) { Db::beginTransaction(); try { $coupon = Coupon::where('coupon_id', $params['coupon_id'])->first(); if ($coupon->coupon_is_period != 'Y') { return; } $detailCount = -1; if ($coupon->coupon_number > 0) { $detailCount = CouponDetail::where('join_detail_coupon_id', $params['coupon_id'])->whereIn('coupon_detail_status', ['INIT', 'PENDING'])->count(); } $periodJson = json_decode($coupon->coupon_period_json, true); if ($detailCount != -1 && $detailCount - $periodJson['nbr'] < 0) { throw new BusinessException("优惠券余量不足"); } $periodJson['now_nbr'] = 1; // 手动发券会传来时间 $periodJson['gain_datetime'] = $params['coupon_detail_gain_datetime'] ?? date('Y-m-d H:i:s'); if (!empty($periodJson['nbr'])) { for ($i = 0; $i < $periodJson['nbr']; $i++) { $periodParams = self::generatePeriod($periodJson); $periodParams['gettype'] = $params['gettype'] ?? ''; $periodParams['coupon_id'] = $params['coupon_id']; $periodParams['member_id'] = $params['member_id']; $periodParams['coupon_detail_period_num'] = $periodJson['now_nbr']; if ($detailCount > 0) { $periodParams['chooseCouponNbr'] = 1; self::sendPeriodCouponHave($periodParams); } else { self::sendPeriodCouponNoLimit($periodParams); } $periodJson['now_nbr'] += 1; } } Db::commit(); } catch (BusinessException $e) { Db::rollBack(); Log::error("发券失败:" . $e->getMessage()); throw new BusinessException($e->getMessage()); } catch (\Exception $e) { Db::rollBack(); Log::error("发券失败:" . $e->getMessage()); throw new BusinessException("优惠券发放失败"); } } /** * @Desc 有发行数量 * @Author Gorden * @Date 2024/9/27 13:45 * * @param $params * @return void */ public static function sendPeriodCouponHave($params) { $gettype = 'SEND'; if (!empty($params['gettype'])) { $gettype = $params['gettype']; } try { CouponDetail::where('join_detail_coupon_id', $params['coupon_id']) ->whereIn('coupon_detail_status', ['INIT', 'PENDING']) ->limit($params['chooseCouponNbr']) ->update([ 'join_coupon_detail_member_id' => $params['member_id'], 'coupon_detail_gain_datetime' => $params['coupon_detail_gain_datetime'], 'coupon_detail_deadline_datetime' => $params['coupon_detail_deadline_datetime'], 'coupon_detail_extend_json' => json_encode(['gettype' => $gettype]), 'coupon_detail_period_num' => $params['coupon_detail_period_num'] ?? 0, 'coupon_detail_status' => 'ACTIVED', 'coupon_detail_addtimes' => time() ]); } catch (\Exception $e) { dump($e->getMessage()); throw new BusinessException('写入优惠券失败'); } } /** * @Desc 发行量不限 * @Author Gorden * @Date 2024/9/27 16:19 * * @param $params * @return void * @throws BusinessException */ public static function sendPeriodCouponNoLimit($params) { $gettype = 'SEND'; if (!empty($params['gettype'])) { $gettype = $params['gettype']; } try { CouponDetail::insert([ 'coupon_detail_id' => 'CUDT' . date("ymdHi") . random_string(4, 'up'), 'join_detail_coupon_id' => $params['coupon_id'], 'join_coupon_detail_member_id' => $params['member_id'], 'coupon_detail_status' => 'ACTIVED', 'coupon_detail_gain_datetime' => $params['coupon_detail_gain_datetime'], 'coupon_detail_deadline_datetime' => $params['coupon_detail_deadline_datetime'], 'coupon_detail_period_num' => $params['coupon_detail_period_num'] ?? 0, 'coupon_detail_extend_json' => json_encode(['gettype' => $gettype]), 'coupon_detail_addtimes' => time(), ]); } catch (\Exception $e) { throw new BusinessException('写入优惠券失败'); } } /** * @Desc * @Author Gorden * @Date 2024/9/27 13:54 * * @param $periodJson * @return array */ public static function generatePeriod($periodJson) { // 当前第几期 $now_nbr = $periodJson['now_nbr']; $params = []; if ($periodJson['unit'] == 'day') { $val = $periodJson['val'] - 1; if ($val < 1) { if ($now_nbr == 1) { $params['coupon_detail_gain_datetime'] = date('Y-m-d 00:00:00', strtotime($periodJson['gain_datetime'])); $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime($periodJson['gain_datetime'])); } else { $now_nbr -= 1; $params['coupon_detail_gain_datetime'] = date('Y-m-d 00:00:00', strtotime($periodJson['gain_datetime'] . "+" . $now_nbr . ' day')); $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime($periodJson['gain_datetime'] . "+" . $now_nbr . ' day')); } } else { if ($now_nbr == 1) { $params['coupon_detail_gain_datetime'] = date('Y-m-d 00:00:00', strtotime($periodJson['gain_datetime'])); $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime($periodJson['gain_datetime'] . "+" . $val . ' day')); } else { $now_nbr -= 1; $params['coupon_detail_gain_datetime'] = date('Y-m-d 00:00:00', strtotime($periodJson['gain_datetime'] . "+" . ((($val + 1) * $now_nbr)) . " day")); $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime($periodJson['gain_datetime'] . "+" . ((($val + 1) * $now_nbr) + $val) . " day")); } } } elseif ($periodJson['unit'] == 'week') { $val = $periodJson['val'] - 1; // 选的日期的周一距离今周周一是几个周 $timestamp = strtotime($periodJson['gain_datetime']); $gainWeekDay = date("w", $timestamp); $gainWeekAdd = date("w", $gainWeekDay) == 1 ? 0 : 1 - $gainWeekDay; $gainMonday = date("Y-m-d 00:00:00", strtotime("$gainWeekAdd days", $timestamp)); $nowMonday = date('Y-m-d 00:00:00', strtotime('this week Monday')); $interval = (new \DateTime(date($gainMonday)))->diff(new \DateTime($nowMonday)); $weekCut = $interval->days / 7; if (strtotime($periodJson['gain_datetime']) < time() && $weekCut > 0) { $weekCut = -$weekCut; } if ($val < 1) { if ($now_nbr == 1) { $params['coupon_detail_gain_datetime'] = $gainMonday; $params['coupon_detail_deadline_datetime'] = date('Y-m-d 23:59:59', strtotime($gainMonday . "+6 days")); } else { $now_nbr -= 1; $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')); $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')); } } else { if ($now_nbr == 1) { $params['coupon_detail_gain_datetime'] = $gainMonday; $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')); } else { $now_nbr -= 1; $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')); $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')); } } } elseif ($periodJson['unit'] == 'month') { $val = $periodJson['val'] - 1; // 选的日期的1号距离今月1号是几个月 $interval = (new \DateTime(date('Y-m-02 00:00:00', strtotime($periodJson['gain_datetime']))))->diff(new \DateTime(date('Y-m-02 00:00:00'))); $monthCut = $interval->m + ($interval->y * 12); if (strtotime($periodJson['gain_datetime']) < time() && $monthCut > 0) { $monthCut = -$monthCut; } if ($val < 1) { if ($now_nbr == 1) { $params['coupon_detail_gain_datetime'] = date('Y-m-01 00:00:00', strtotime($periodJson['gain_datetime'])); $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime($periodJson['gain_datetime'])); } else { $now_nbr -= 1; $params['coupon_detail_gain_datetime'] = date('Y-m-01 00:00:00', strtotime("+" . ($now_nbr + $monthCut) . ' month')); $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime(date('Y-m-01 00:00:00') . "+" . ($now_nbr + $monthCut) . ' month')); } } else { if ($now_nbr == 1) { $params['coupon_detail_gain_datetime'] = date('Y-m-01 00:00:00', strtotime($periodJson['gain_datetime'])); $params['coupon_detail_deadline_datetime'] = date('Y-m-t 23:59:59', strtotime(date('Y-m-01 00:00:00') . "+" . ($val + $monthCut) . ' month')); } else { $now_nbr -= 1; $params['coupon_detail_gain_datetime'] = date('Y-m-01 00:00:00', strtotime("+" . ((($val + 1) * $now_nbr) + $monthCut) . ' month')); $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')); } } } return $params; } }