|
|
<?php
namespace App\Service\v3\Implementations;
use App\Constants\v3\ErrorCode;use App\Constants\v3\LogLabel;use App\Exception\ErrorCodeException;use App\Model\v3\CouponRec;use App\Model\v3\CouponUse;use App\Model\v3\OrderMain;use App\Service\v3\Interfaces\CouponServiceInterface;use Hyperf\DbConnection\Db;use Hyperf\Redis\Redis;use Hyperf\Utils\ApplicationContext;
class CouponService implements CouponServiceInterface{
/** * @inheritDoc */ public function do() { // TODO: Implement do() method.
}
/** * @inheritDoc */ public function check() { // TODO: Implement check() method.
}
/** * @inheritDoc */ public function undo() { // TODO: Implement undo() method.
}
/** * 缓存优惠券今日使用情况 * @param $userId * @param $couponId * @param $couponRecId * @return bool */ public function cacheTodayCouponUsed($userId, $couponId, $couponRecId) { $redis = ApplicationContext::getContainer()->get(Redis::class); $setRes = $redis->sAdd('coupon_' . date('Ymd') . '_used_' . $userId, $couponId); $expireRes = $redis->expire('coupon_' . date('Ymd') . '_used_' . $userId, strtotime(date('Y-m-d') . ' 23:59:59') - time()); return $setRes && $expireRes; }
public function allTodayCouponUsed($userId) { $redis = ApplicationContext::getContainer()->get(Redis::class); return $couponTodayUsedIds = $redis->sMembers('coupon_'.date('Ymd').'_used_'.$userId); }
public function orderUseCoupons($globalOrderId, $couponRecs) { Db::beginTransaction(); try { if (is_array($couponRecs)&&!empty($couponRecs)) { # 使用记录、更新当前优惠券
foreach ($couponRecs as $key => &$coupon) {
$couponUse = [ 'user_id' => $coupon['user_id'], 'user_receive_id' => $coupon['id'], 'coupon_id' => $coupon['coupon_id'], 'order_main_id' => $globalOrderId, 'use_time' => time(), 'return_time' => 0, 'number' => 1, 'status' => 1, 'update_time' => 0, ];
$insertRes = CouponUse::query()->insert($couponUse); if ($insertRes) { $status = 0; $numberRemain = $coupon['number_remain'] - 1; if ($numberRemain == 0) { $status = 2; } elseif ($numberRemain > 0 && $numberRemain < $coupon['number']) { $status = 1; } elseif ($numberRemain == $coupon['number']) { $status = 0; }
$upRes = CouponRec::query()->where(['id' => $coupon['id']]) ->update(['number_remain' => $numberRemain, 'status' => $status]); if (!$upRes) { Db::rollBack(); throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE, '更新优惠券数量失败', ['id' => $coupon['id'],'number_remain' => $numberRemain, 'status' => $status]); } // 缓存使用记录
$usedRes = $this->cacheTodayCouponUsed($coupon['user_id'], $coupon['coupon_id'], $coupon['id']); if (!$usedRes) { Db::rollBack(); throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE, '缓存优惠券使用记录失败'); } } else { Db::rollBack(); throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE, '新增优惠券使用记录到数据库失败', [ 'user_id' => $coupon['user_id'], 'user_receive_id' => $coupon['id'], 'coupon_id' => $coupon['coupon_id'], 'order_main_id' => $globalOrderId, 'use_time' => time(), 'return_time' => 0, 'number' => 1, 'status' => 1, 'update_time' => 0, ]); }
} }
Db::commit(); } catch (\Exception $e) { Db::rollBack(); $this->log->event(LogLabel::ORDER_ONLINE_LOG, ['msg' => '下单时优惠券使用失败'.$e->getMessage(), 'data' => '']); throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE); }
}
/** * 退还优惠券,订单取消,申请退款成功时 * 先查询是否正常使用优惠券 * 修改状态,退还领取记录库存,删除ssdb缓存 * @param $globalOrderId * @return bool */ public function orderRefundCoupons($globalOrderId) { $currentTime = time(); Db::beginTransaction(); try { $couponUses = CouponUse::query() ->where('order_main_id', $globalOrderId) ->where('status', 1) ->get(); if (!empty($couponUses)) { foreach ($couponUses as $use) { $use->status = 1; $use->return_time = $currentTime; $use->update_time = $currentTime; $res = $use->save(); $couponReceive = CouponRec::query() ->where('id', $use->user_receive_id) ->whereRaw('number >= number_remain+' . $use->number) ->update([ 'number_remain' => Db::raw('number_remain+' . $use->number), 'status' => Db::raw('IF(number=number_remain, 0,1)'), 'update_time' => $currentTime ]);
if ($res && $couponReceive) { $redis = ApplicationContext::getContainer()->get(Redis::class); $clearUseRedis = $redis->sRem('coupon_' . date('Ymd') . '_used_' . $use->user_id, $use->coupon_id); } } } Db::commit(); return true; } catch (\Exception $e) { $this->log->event(LogLabel::COUPON_REFUND_LOG, ['msg' => '订单取消/退款退还优惠券', 'exception' => $e->getMessage()]); Db::rollBack(); return false; } }}
|