123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- <?php
- namespace app\admin\service\coupon;
- use app\model\Coupon;
- use app\model\CouponDetail;
- use app\model\Member;
- use app\model\SysSerial;
- use support\Db;
- use support\exception\BusinessException;
- use support\Log;
- class CouponDetailService
- {
- /**
- * @Desc 手动发券
- * @Author Gorden
- * @Date 2024/8/27 9:57
- *
- * @param $params
- * @return void
- * @throws BusinessException
- */
- public static function customSendCoupon($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, 'order_id' => $params['order_id'] ?? '']),
- 'coupon_detail_addtimes' => time(),
- ]);
- } catch (\Exception $e) {
- Log::error('写入优惠券失败',['msg'=>$e->getMessage()]);
- 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, 'order_id' => $params['order_id'] ?? '']),
- 'coupon_detail_period_num' => $params['coupon_detail_period_num'] ?? 0,
- 'coupon_detail_status' => 'ACTIVED',
- 'coupon_detail_addtimes' => time()
- ]);
- } catch (\Exception $e) {
- Log::error("写入优惠券失败", ['msg' => $e->getMessage()]);
- 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['order_id'] = $params['order_id'] ?? '';
- $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, 'order_id' => $params['order_id'] ?? '']),
- '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, 'order_id' => $params['order_id'] ?? '']),
- '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(date('Y-m-01 00:00:00') . "+" . ($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(date('Y-m-01 00:00:00') . "+" . ((($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;
- }
- public static function customSendService($chooseCoupons, $couponUseMember, $memberList, $condition)
- {
- if ($couponUseMember == 'condition') {
- if ($condition == 'is_employ') {
- $memberList = Member::where('member_classify', 'EMPLOY')->pluck('member_id')->toArray();
- } elseif ($condition == 'is_member') {
- $memberList = Member::where('member_classify', 'MEMBER')->pluck('member_id')->toArray();
- } elseif ($condition == 'is_vip') {
- $memberList = Member::where('member_is_vip', 'Y')->pluck('member_id')->toArray();
- }
- }
- $couponNbr = [];
- Db::beginTransaction();
- try {
- $couponIds = array_column($chooseCoupons, 'id');
- $coupons = Coupon::whereIn('coupon_id', $couponIds)->get()->toArray();
- foreach ($coupons as $coupon) {
- foreach ($chooseCoupons as $chooseCoupon) {
- if ($chooseCoupon['id'] == $coupon['coupon_id']) {
- if (empty($chooseCoupon['gain_datetime'])) {
- $chooseCoupon['gain_datetime'] = date('Y-m-d H:i:s');
- }
- $params['coupon_id'] = $coupon['coupon_id'];
- $params['coupon_detail_gain_datetime'] = date('Y-m-d H:i:s', strtotime($chooseCoupon['gain_datetime']));
- if (($coupon['coupon_validdate_day'] == 0 || $coupon['coupon_validdate_day'] == '') && !empty($coupon['coupon_validdate_end'])) {
- $params['coupon_detail_deadline_datetime'] = $coupon['coupon_validdate_end'];
- } elseif ($coupon['coupon_validdate_day'] > 0) {
- $endUnix = strtotime($chooseCoupon['gain_datetime']);
- $params['coupon_detail_deadline_datetime'] = date('Y-m-d H:i:s', $endUnix + ($coupon['coupon_validdate_day'] * 24 * 3600) - 1);
- }
- foreach ($memberList as $item) {
- $params['member_id'] = $item;
- if ($coupon['coupon_is_period'] == 'Y') {
- // if (CouponDetail::where('join_coupon_detail_member_id', $item)->where('join_detail_coupon_id', $coupon['coupon_id'])->exists()) {
- // throw new BusinessException("请勿重复发放周期券");
- // }
- $params['coupon_detail_period_num'] = 1;
- $periodJson = json_decode($coupon['coupon_period_json'], true);
- // for ($i=0;$i<$periodJson['nbr'];$i++){
- CouponDetailService::sendPeriodCoupon($params);
- // }
- continue;
- }
- if ($chooseCoupon['nbr'] > 0) {
- // 有发行数量
- if ($coupon['coupon_number'] != 0) {
- // 查询还有多少张没领的
- $count = CouponDetail::where('join_detail_coupon_id', $coupon['coupon_id'])
- ->whereIn('coupon_detail_status', ['INIT', 'PENDING'])
- ->count();
- if (!isset($couponNbr[$coupon['coupon_id']])) {
- $couponNbr[$coupon['coupon_id']] = $count;
- }
- if ($couponNbr[$coupon['coupon_id']] - $chooseCoupon['nbr'] < 0) {
- throw new BusinessException($coupon['coupon_name'] . "超出发行数量");
- }
- $couponNbr[$coupon['coupon_id']] = $couponNbr[$coupon['coupon_id']] - $chooseCoupon['nbr'];
- $params['chooseCouponNbr'] = $chooseCoupon['nbr'];
- // 匹配已发行的优惠券
- CouponDetailService::customSendCouponHave($params);
- } else {
- for ($i = 0; $i < $chooseCoupon['nbr']; $i++) {
- CouponDetailService::customSendCoupon($params);
- }
- }
- }
- }
- }
- }
- }
- Db::commit();
- } catch (BusinessException $e) {
- Db::rollBack();
- Log::error('优惠券发放失败', ['msg' => $e->getMessage()]);
- throw new BusinessException($e->getMessage());
- } catch (\Exception $e) {
- Db::rollBack();
- Log::error('优惠券发放失败', ['msg' => $e->getMessage()]);
- throw new BusinessException('优惠券发放失败');
- }
- }
- /**
- * @Desc 把指定账户的优惠券加到另一个账户
- * @Author Gorden
- * @Date 2024/11/7 16:33
- *
- * @param $originMemberId
- * @param $memberId
- * @return void
- */
- public static function transCoupon($originMemberId, $memberId)
- {
- $details = CouponDetail::where('join_coupon_detail_member_id', $originMemberId)
- ->where('coupon_detail_status', 'ACTIVED')
- ->get()
- ->toArray();
- foreach ($details as $detail) {
- $detailModel = new CouponDetail();
- $detailModel->coupon_detail_id = 'CUDT' . date('ymdHi') . random_string(4, 'up');
- $detailModel->join_detail_coupon_id = $detail['join_detail_coupon_id'];
- $detailModel->join_coupon_detail_member_id = $memberId;
- $detailModel->coupon_detail_status = $detail['coupon_detail_status'];
- $detailModel->coupon_detail_deadline_datetime = $detail['coupon_detail_deadline_datetime'];
- $detailModel->coupon_detail_gain_datetime = date('Y-m-d H:i:s');
- $detailModel->coupon_detail_extend_json = $detail['coupon_detail_extend_json'];
- $detailModel->coupon_detail_addtimes = time();
- $detailModel->save();
- }
- }
- }
|