109 lines
3.1 KiB
PHP
109 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Exceptions\BizException;
|
|
use App\Models\BargainOrder;
|
|
use App\Models\BargainOrderLog;
|
|
use App\Models\BargainSku;
|
|
use App\Models\ProductSku;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Arr;
|
|
|
|
class BargainService
|
|
{
|
|
/**
|
|
* 创建砍价单
|
|
*
|
|
* @param User $user
|
|
* @param ProductSku $productSku
|
|
* @return void
|
|
*/
|
|
public function createBargainOrder(User $user, ProductSku $productSku)
|
|
{
|
|
$bargainSku = BargainSku::with(['activity'=>function ($query) {
|
|
return $query->where('is_enable', true)->where('start_at', '<=', now())->where('end_at', '>=', now());
|
|
}])->where('sku_id', $productSku->id)->first();
|
|
if (!($bargainSku && $bargainSku->activity)) {
|
|
throw new BizException('砍价商品活动已结束');
|
|
}
|
|
|
|
$order = new BargainOrder();
|
|
$order->activity_id = $bargainSku->activity_id;
|
|
$order->user_id = $user->id;
|
|
$order->sku_id = $productSku->id;
|
|
$order->sku_price = $productSku->getRealPrice($user);
|
|
$order->status = BargainOrder::ORDER_STATUS_START;
|
|
$order->expire_at = now()->addHours($bargainSku->activity->expire_hours);
|
|
$order->save();
|
|
|
|
return $order;
|
|
}
|
|
|
|
/**
|
|
* 用户砍价
|
|
*
|
|
* @param User $user
|
|
* @param BargainOrder $order
|
|
* @return void
|
|
*/
|
|
public function bargain(User $user, BargainOrder $order)
|
|
{
|
|
$order->lockForUpdate();
|
|
$order->load('sku');
|
|
|
|
//不能给自己砍
|
|
if ($user->id == $order->user_id) {
|
|
throw new BizException('不能帮自己砍价');
|
|
}
|
|
|
|
//已砍完
|
|
if ($order->isFinished()) {
|
|
throw new BizException('当前砍价单已完成,无法再砍');
|
|
}
|
|
|
|
//已下单
|
|
if ($order->order_id > 0) {
|
|
throw new BizException('当前砍价单已下单,无法再砍');
|
|
}
|
|
|
|
//砍价超时
|
|
if ($order->expire_at < now()) {
|
|
throw new BizException('当前砍价已结束,无法再砍');
|
|
}
|
|
|
|
//如果砍价活动结束了,也不能砍了
|
|
$activity = $order->sku->isBargaing();
|
|
if (!$activity) {
|
|
throw new BizException('当前砍价已结束,无法再砍');
|
|
}
|
|
|
|
//如果已经砍过了,不能再砍了
|
|
if ($order->logs()->where('user_id', $user->id)->exists()) {
|
|
throw new BizException('您已砍价');
|
|
}
|
|
|
|
//执行砍价动作;
|
|
//计算第几次砍价,并获得当前砍价金额
|
|
$nowBargainCount = $order->logs->count();
|
|
|
|
$bargainRules = json_decode($activity->rules, true);
|
|
|
|
$log = new BargainOrderLog([
|
|
'user_id'=>$user->id,
|
|
'bargain_amount'=> bcmul(Arr::get($bargainRules, $nowBargainCount, 0), 100),
|
|
]);
|
|
|
|
$order->logs()->save($log);
|
|
$order->bargain_price += $log->bargain_amount;
|
|
$nowBargainCount ++;
|
|
|
|
if ($activity->times > 0 && $nowBargainCount >= $activity->times) {
|
|
$order->status = BargainOrder::ORDER_STATUS_FINISHED;
|
|
}
|
|
$order->save();
|
|
|
|
return $order;
|
|
}
|
|
}
|