6
0
Fork 0
jiqu-library-server/app/Services/CouponService.php

156 lines
4.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?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(),
];
}
}