|
|
|
@ -4,7 +4,9 @@ namespace App\Service\v3\Implementations; |
|
|
|
|
|
|
|
use App\Model\v3\Coupon; |
|
|
|
use App\Model\v3\CouponRec; |
|
|
|
use App\Model\v3\CouponRecType; |
|
|
|
use App\Model\v3\GoodsActivity; |
|
|
|
use App\Service\CommonService; |
|
|
|
use App\Service\v3\Interfaces\CouponRecServiceInterface; |
|
|
|
use App\Service\v3\Interfaces\CouponServiceInterface; |
|
|
|
use App\Service\v3\Interfaces\ShopCartServiceInterface; |
|
|
|
@ -12,6 +14,8 @@ use Hyperf\DbConnection\Db; |
|
|
|
use Hyperf\Redis\Redis; |
|
|
|
use Hyperf\Utils\ApplicationContext; |
|
|
|
use Hyperf\Di\Annotation\Inject; |
|
|
|
use App\Constants\v3\SsdbKeys; |
|
|
|
use App\TaskWorker\SSDBTask; |
|
|
|
|
|
|
|
class CouponRecService implements CouponRecServiceInterface |
|
|
|
{ |
|
|
|
@ -28,6 +32,12 @@ class CouponRecService implements CouponRecServiceInterface |
|
|
|
*/ |
|
|
|
protected $couponService; |
|
|
|
|
|
|
|
/** |
|
|
|
* @Inject |
|
|
|
* @var HelperService |
|
|
|
*/ |
|
|
|
protected $helperService; |
|
|
|
|
|
|
|
public function do() |
|
|
|
{ |
|
|
|
// TODO: Implement do() method.
|
|
|
|
@ -290,4 +300,181 @@ class CouponRecService implements CouponRecServiceInterface |
|
|
|
} |
|
|
|
return $res; |
|
|
|
} |
|
|
|
|
|
|
|
public function getAvailableList($userId,$receiveType) |
|
|
|
{ |
|
|
|
/* 优惠券活动标志 2 */ |
|
|
|
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); |
|
|
|
$couponActivity = $ssdb->exec('hgetall', SsdbKeys::COUPON_REBATE_ACTIVITY); |
|
|
|
$activityType = $couponActivity === false ? 0 : $couponActivity['activity']; |
|
|
|
|
|
|
|
$result = [ |
|
|
|
'active_type' => 1, |
|
|
|
'not_receive' => [], |
|
|
|
'jump_data' => [ |
|
|
|
'src' => "/zh_cjdianc/pages/couponrebate/index?activity_type=".$activityType, |
|
|
|
'src2' => "/zh_cjdianc/pages/couponrebate/index?activity_type=".$activityType, |
|
|
|
'share_bg' => env('OSS_IMG_HOST').'/static/img/coupon_share.png', |
|
|
|
'receive_bg' => env('OSS_IMG_HOST').'/static/img/coupon_bg.png', |
|
|
|
'coupons' => [] |
|
|
|
] |
|
|
|
]; |
|
|
|
$nowTime = time(); |
|
|
|
$c_ids = []; |
|
|
|
// 渠道开启,查询该渠道可以领取的优惠券ID
|
|
|
|
// 渠道未开启,查询所有优惠券
|
|
|
|
if (env('SUB_CHANNEL') == 1) { |
|
|
|
$c_ids = CouponRecType::join('lanzu_coupon','lanzu_coupon.id','lanzu_coupon_receive_type.coupon_id') |
|
|
|
->where([ |
|
|
|
['lanzu_coupon_receive_type.receive_type','=',$receiveType], |
|
|
|
['lanzu_coupon.end_time','>',$nowTime], |
|
|
|
['lanzu_coupon.start_time','<=',$nowTime], |
|
|
|
['lanzu_coupon.status','=',1] |
|
|
|
]) |
|
|
|
->pluck('lanzu_coupon.id'); |
|
|
|
} else { |
|
|
|
$c_ids = Coupon::where([ |
|
|
|
['end_time','>',$nowTime], |
|
|
|
['start_time','<=',$nowTime], |
|
|
|
['status','=',1] |
|
|
|
])->pluck('id'); |
|
|
|
} |
|
|
|
|
|
|
|
$couponReceive = CouponRec::where('user_id',$userId); |
|
|
|
|
|
|
|
// 渠道开启,查询该用户在此渠道领过的优惠券ID
|
|
|
|
if (env('SUB_CHANNEL') == 1) { |
|
|
|
$couponReceive->where('receive_type', $receiveType); |
|
|
|
} |
|
|
|
$cr_ids = $couponReceive->pluck('coupon_id'); |
|
|
|
|
|
|
|
// 可领取的券ID
|
|
|
|
$c_ids = $c_ids->toArray(); |
|
|
|
// 已经领取的券ID
|
|
|
|
$cr_ids = $cr_ids->toArray(); |
|
|
|
|
|
|
|
// 当前用户可领的优惠券ID
|
|
|
|
$couponIds = array_diff($c_ids, $cr_ids); |
|
|
|
|
|
|
|
// 转发型优惠券
|
|
|
|
$couponReceiveIds = ($couponActivity === false || $this->helperService->nonempty($couponActivity['forward']) )? [] : explode(',',$couponActivity['forward']); |
|
|
|
// 所有优惠券
|
|
|
|
$couponIds = array_merge($couponIds,$couponReceiveIds); |
|
|
|
|
|
|
|
$whereC = [ |
|
|
|
['lanzu_coupon.end_time','>',$nowTime], |
|
|
|
['lanzu_coupon.start_time','<=',$nowTime], |
|
|
|
['lanzu_coupon.status','=',1] |
|
|
|
]; |
|
|
|
// 查询领取型1 和 转发型2
|
|
|
|
$whereActiveType = [1,2]; |
|
|
|
|
|
|
|
if (env('SUB_CHANNEL') == 1) { |
|
|
|
array_push($whereC, ['type.receive_type','=', $receiveType]); |
|
|
|
} |
|
|
|
|
|
|
|
$coupons = Coupon::join('lanzu_coupon_receive_type as type', 'lanzu_coupon.id', '=', 'type.coupon_id') |
|
|
|
->whereIn('lanzu_coupon.id', $couponIds) |
|
|
|
->whereIn('lanzu_coupon.active_type', $whereActiveType) |
|
|
|
->where($whereC) |
|
|
|
->whereRaw('lanzu_coupon.inventory_use < lanzu_coupon.inventory and lanzu_coupon.inventory-lanzu_coupon.inventory_use >= type.one_receive_number') |
|
|
|
->select('lanzu_coupon.*','type.one_receive_number') |
|
|
|
->orderBy('lanzu_coupon.weigh','desc') |
|
|
|
->get(); |
|
|
|
|
|
|
|
foreach ($coupons as $k => &$v){ |
|
|
|
|
|
|
|
if($v->active_type == 1){ |
|
|
|
$result['not_receive'][] = $v; |
|
|
|
}else if($v->active_type == 2 && in_array($v->id,$couponReceiveIds)){ |
|
|
|
$result['jump_data']['coupons'][] = $v->id; |
|
|
|
} |
|
|
|
|
|
|
|
if($v->discount_type == 2){ |
|
|
|
$v->discounts = floatval($v->discounts); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
$result['active_type'] = count($result['jump_data']['coupons']) > 0 ? 2 : $result['active_type'] ; |
|
|
|
|
|
|
|
return $result; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param $userId |
|
|
|
* @param $receiveType |
|
|
|
* @param $ids |
|
|
|
*/ |
|
|
|
public function receive($userId, $receiveType, $ids) |
|
|
|
{ |
|
|
|
$ids = explode(',', $ids); |
|
|
|
$now = time(); |
|
|
|
|
|
|
|
$success = []; |
|
|
|
$fail = []; |
|
|
|
|
|
|
|
// if ($this->empty($userId) || $this->empty($receiveType) || $this->empty($ids)) {
|
|
|
|
// return [
|
|
|
|
// 'success' => $success,
|
|
|
|
// 'fail' => $fail,
|
|
|
|
// ];
|
|
|
|
// }
|
|
|
|
|
|
|
|
Db::transaction(function () use ($ids,$receiveType,$userId,&$success,&$fail,$now) { |
|
|
|
//读写锁,完全控制,性能底
|
|
|
|
|
|
|
|
$builder = Coupon::whereIn('id', $ids); |
|
|
|
if (env('SUB_CHANNEL') == 1) { |
|
|
|
$builder->where('receive_type',$receiveType); |
|
|
|
} |
|
|
|
$cps = $builder->lockForUpdate()->get(); |
|
|
|
//写锁,可能在高并发下,读取到脏数据,写入可能有超发情况
|
|
|
|
//$cps = Coupon::whereIn('id', $ids)->sharedLock()->get();
|
|
|
|
|
|
|
|
foreach ($cps as $key => $cp) { |
|
|
|
|
|
|
|
$where = [ |
|
|
|
'coupon_id' => $cp->id, |
|
|
|
]; |
|
|
|
|
|
|
|
$oneReceiveNumber = CouponRecType::where($where)->value('one_receive_number'); |
|
|
|
$couponInventory = $cp->inventory - $cp->inventory_use; |
|
|
|
|
|
|
|
if($couponInventory < $oneReceiveNumber){ |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
$couponReceiveExists = CouponRec::query()->where(['coupon_id'=>$cp->id,'user_id'=>$userId])->exists(); |
|
|
|
|
|
|
|
if($couponReceiveExists){ |
|
|
|
continue; |
|
|
|
} |
|
|
|
$cr = new CouponRec; |
|
|
|
$cr->user_id = $userId; |
|
|
|
$cr->coupon_id = $cp->id; |
|
|
|
$cr->order_main_id = 0; |
|
|
|
$cr->receive_time = $now; |
|
|
|
$cr->number = $oneReceiveNumber; |
|
|
|
$cr->number_remain = $oneReceiveNumber; |
|
|
|
$cr->status = 0; |
|
|
|
$cr->update_time = $now; |
|
|
|
$cr->receive_type = $receiveType; |
|
|
|
//如果优惠卷库存小于等于已领取的数量, 则返回领取失败的优惠券
|
|
|
|
if ($cp->inventory<=$cp->inventory_use||$cp->inventory<($cp->inventory_use+$cr->number)){ |
|
|
|
$fail[] = $cp; |
|
|
|
}else{ |
|
|
|
$cp->inventory_use += $cr->number;//记录已领取的数量
|
|
|
|
if ($cr->save()&&$cp->save()) { |
|
|
|
$success[] = $cp; |
|
|
|
} else { |
|
|
|
$fail[] = $cp; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
return [ |
|
|
|
'success' => $success, |
|
|
|
'fail' => $fail, |
|
|
|
]; |
|
|
|
} |
|
|
|
} |