You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
6.0 KiB
176 lines
6.0 KiB
<?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.
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
public function countAvailableByUser($userId)
|
|
{
|
|
return mt_rand(0,10);
|
|
}
|
|
|
|
/**
|
|
* 缓存优惠券今日使用情况
|
|
* @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);
|
|
}
|
|
// 缓存使用记录
|
|
$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);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Db::commit();
|
|
} catch (\Exception $e) {
|
|
Db::rollBack();
|
|
throw new ErrorCodeException(ErrorCode::COUPON_USE_FAILURE, $e->getMessage());
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* 退还优惠券,订单取消,申请退款成功时
|
|
* 先查询是否正常使用优惠券
|
|
* 修改状态,退还领取记录库存,删除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;
|
|
}
|
|
}
|
|
}
|