6
0
Fork 0
jiqu-library-server/app/Services/BargainService.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;
}
}