156 lines
4.3 KiB
PHP
156 lines
4.3 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
use App\Models\Coupon;
|
||
use App\Models\ProductPart;
|
||
use App\Models\ReceivePartCouponLog;
|
||
use App\Models\User;
|
||
use App\Models\UserCoupon;
|
||
|
||
class CouponService
|
||
{
|
||
/**
|
||
* 根据SKU商品获取可用优惠券
|
||
*
|
||
* @param User $user
|
||
* @param array $products 至少包含以下内容
|
||
* [
|
||
* ['sku' => 商品SKU, 'quantity' => 10]
|
||
* ]
|
||
* @return array
|
||
*/
|
||
public function getAvailableCoupons(User $user, array $products): array
|
||
{
|
||
$coupons = $user->coupons()->onlyAvailable()->get();
|
||
|
||
$coupons->load(['ranges' => function ($query) {
|
||
$query->isEnable();
|
||
}]);
|
||
|
||
$availableCoupons = [];
|
||
|
||
foreach ($coupons as $coupon) {
|
||
// 是否满足券使用规则
|
||
$passes = false;
|
||
|
||
// 可用优惠券的商品的总额
|
||
$amount = 0;
|
||
|
||
foreach ($products as $product) {
|
||
$sku = $product['sku'];
|
||
|
||
if ($coupon->isSupport($sku)) {
|
||
$passes = true;
|
||
|
||
$amount += $sku->getRealPrice($user) * $product['quantity'];
|
||
}
|
||
}
|
||
|
||
if ($passes && $amount >= $coupon->coupon_threshold) {
|
||
$availableCoupons[] = $coupon;
|
||
}
|
||
}
|
||
|
||
return $availableCoupons;
|
||
}
|
||
|
||
/**
|
||
* 根据分区,领取优惠券
|
||
*/
|
||
public function receivePartCoupon(ProductPart $part, User $user)
|
||
{
|
||
//如果分区不显示,直接退出;
|
||
if (!$part->is_show) {
|
||
return;
|
||
}
|
||
//如果用户已领取过该分区设置的券,直接退出;
|
||
if (ReceivePartCouponLog::where(['user_id'=>$user->id, 'part_id'=>$part->id])->exists()) {
|
||
return;
|
||
}
|
||
|
||
//取出需要发放的券
|
||
$coupons = Coupon::whereIn('id', $part->coupons->pluck('coupon_id')->toArray())->get();
|
||
$coupons = $coupons->keyBy('id');
|
||
$someCoupons = [];
|
||
foreach ($part->coupons as $coupon) {
|
||
$someCoupons[] = [
|
||
'coupon'=>$coupons[$coupon->coupon_id],
|
||
'num'=>$coupon->num,
|
||
];
|
||
}
|
||
$this->receiveSomeCoupons($user, $someCoupons);
|
||
|
||
ReceivePartCouponLog::create(['user_id'=>$user->id, 'part_id'=>$part->id]);
|
||
}
|
||
|
||
/**
|
||
* 领取一批券
|
||
*
|
||
* @param User $user
|
||
* @param array $coupons
|
||
* @return void
|
||
*/
|
||
protected function receiveSomeCoupons(User $user, array $coupons)
|
||
{
|
||
$userCoupons = [];
|
||
foreach ($coupons as $coupon) {
|
||
for ($i=0; $i<$coupon['num']; $i++) {
|
||
$userCoupons[] = self::createUserCouponData($user->id, $coupon['coupon']);
|
||
}
|
||
//更新对应券发送量,余量;
|
||
$coupon['coupon']->increment('sent', $coupon['num']);
|
||
if ($coupon['coupon']->limit > 0) {//限量才减少余量
|
||
$coupon['coupon']->decrement('stock', $coupon['num']);
|
||
}
|
||
}
|
||
|
||
UserCoupon::insert($userCoupons);
|
||
}
|
||
|
||
/**
|
||
* todo-领取指定券
|
||
*
|
||
* @param User $user
|
||
* @param Coupon $coupon
|
||
* @param int $num
|
||
* @return void
|
||
*/
|
||
public function receiveCoupon(User $user, Coupon $coupon, int $num = 1)
|
||
{
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* 创建用户券数据
|
||
*
|
||
* @return array
|
||
*/
|
||
public static function createUserCouponData(int $userId, Coupon $coupon)
|
||
{
|
||
//如果userId小于等于0,直接退出
|
||
if ($userId <= 0) {
|
||
return [];
|
||
}
|
||
if ($coupon->use_start_at && $coupon->use_end_at) {
|
||
$useStartAt = $coupon->use_start_at;
|
||
$useEndAt = $coupon->use_end_at;
|
||
} else {
|
||
$useStartAt = now();
|
||
$useEndAt = now()->addDays($coupon->use_day);
|
||
}
|
||
return [
|
||
'user_id' => $userId,
|
||
'coupon_id' => $coupon->id,
|
||
'coupon_name' => $coupon->name,
|
||
'coupon_type' => $coupon->type,
|
||
'coupon_amount' => (int) bcmul($coupon->amount, 100),
|
||
'coupon_threshold'=> (int) bcmul($coupon->threshold, 100),
|
||
'use_start_at' => $useStartAt,
|
||
'use_end_at' => $useEndAt,
|
||
'created_at' => now(),
|
||
'updated_at' => now(),
|
||
];
|
||
}
|
||
}
|