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

219 lines
6.7 KiB
PHP

<?php
namespace App\Services\Dealer;
use App\Enums\DealerLvl;
use App\Enums\DealerOrderStatus;
use App\Exceptions\BizException;
use App\Models\DealerOrder;
use App\Models\DealerProduct;
use App\Models\ShippingAddress;
use App\Models\User;
use App\Models\UserInfo;
use Illuminate\Database\QueryException;
class OrderService
{
/**
* 计算订单价格
*
* @param DealerProduct $product
* @param integer $number
* @return string
*/
public function totalAmount(User $user, DealerProduct $product, int $number = 0)
{
//获取等级规则,判断当前用户等级是否配置等级价格
$salePrice = $product->price;
if ($user->dealer) {
foreach ($product->lvlRules as $rule) {
if ($rule->lvl == $user->dealer->lvl) {
$salePrice = $rule->sale_price;
break;
}
}
}
//获取销售规则,判断当前用户购买数量价格
foreach ($product->saleRules as $rule) {
if ($number >= $rule->qty) {
if ($salePrice > $rule->price) {
$salePrice = $rule->price;
}
break;
}
}
// dd($salePrice, $number);
return bcmul($salePrice, $number, 2);
}
/**
* 创建订单
*
* @param User $user
* @param DealerProduct $product
* @param integer $number
* @param integer $shippingAddressId
* @return DealerOrder $order
*/
public function createOrder(User $user, DealerProduct $product, int $number = 0, int $shippingAddressId)
{
//判断是否满足当前等级最低补货价
$totalAmount = $this->totalAmount($user, $product, $number);
foreach ($product->lvlRules as $rule) {
if ($user->dealer && $rule->lvl == $user->dealer->lvl && $totalAmount < $rule->min_order_amount) {
throw new BizException('当前单次补货价格不能低于'.$rule->min_order_amount.'元');
}
}
//找到发货人
$consignor = $this->getConsignor($user, $totalAmount);
//找到收货地址
$shippingAddress = $this->getShippingAddress($user, $shippingAddressId);
//保存订单
$order = new DealerOrder();
do {
try {
$order->sn = serial_number();
$order->user_id = $user->id;
$order->consignor_id = $consignor?->user_id;
$order->total_amount = $totalAmount;
$order->consignee_name = $shippingAddress->consignee;
$order->consignee_telephone = $shippingAddress->telephone;
$order->consignee_zone = $shippingAddress->zone;
$order->consignee_address = $shippingAddress->address;
$order->save();
break;
} catch (QueryException $e) {
if (strpos($e->getMessage(), 'Duplicate entry') === false) {
throw $e;
}
}
} while (true);
//保存订单商品-----一个订单对应一个商品
$order->products()->create([
'order_id' => $order->id,
'product_id'=> $product->id,
'name'=> $product->name,
'subtitle'=> $product->subtitle,
'cover'=> $product->cover,
'price' => $product->price,
'sale_price'=> bcdiv($totalAmount, $number, 2),
'qty'=> $number,
]);
return $order;
}
/**
* 确认接单
*
* @param DealerOrder $order
* @return void
*/
public function confirmOrder(DealerOrder $order)
{
if (!$order->isPending()) {
throw new BizException('订单状态异常,请刷新后再试');
}
$order->update([
'status' => DealerOrderStatus::Paying,
]);
}
/**
* 确认打款
*
* @return void
*/
public function payOrder(DealerOrder $order, string $payImage)
{
if (!$order->isPendinged()) {
throw new BizException('订单状态异常,请刷新后再试');
}
$order->update([
'status' => DealerOrderStatus::Confirming,
'pay_image' => $payImage,
'pay_info' => $order->getConsignorPayInfo()??null,
'pay_time' => now(),
]);
}
/**
* 更新订单发货人
*
* @return void
*/
protected function updateOrderConsignor(DealerOrder $order)
{
$consignor = $this->getConsignor($order->user, $order->consignor);
$order->update([
'consignor_id' => $consignor?->user_id,
]);
}
/**
* 获取收货地址
*
* @param \App\Models\User $user
* @param int|null $shippingAddressId
* @return \App\Models\ShippingAddress|null
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
protected function getShippingAddress(User $user, ?int $shippingAddressId = null): ?ShippingAddress
{
if ($shippingAddressId) {
return $user->shippingAddresses()->findOrFail($shippingAddressId);
}
return $user->shippingAddresses()->where('is_default', true)->first();
}
public function getConsignor(User $user, $totalAmount, ?User $lastConsignor = null)
{
//todo-改成配置
$rules = [
[
'amount'=>'26400.00',
'lvl'=>DealerLvl::Contracted,
],
[
'amount' =>'8600.00',
'lvl'=>DealerLvl::Special,
],
[
'amount' =>'2520.00',
'lvl'=>DealerLvl::Gold,
],
];
$lvl = $user->dealer->lvl;
foreach ($rules as $rule) {
if ($totalAmount >= $rule['amount'] && $lvl->value < $rule['lvl']->value) {
$lvl = $rule['lvl'];
}
}
//如果是签约单,直接抛到公司后台发货
if ($lvl->value >= DealerLvl::Contracted->value) {
return null;
}
$query = UserInfo::with('dealer');
if ($lastConsignor) {
$query->whereIn('user_id', $lastConsignor->userInfo->real_parent_ids);//上个发货人的上级
} else {
$query->whereIn('user_id', $user->userInfo->real_parent_ids);//自己的上级
}
$consignor = $query->whereHas('dealer', function ($q) use ($lvl) {
return $q->where('lvl', '>', $lvl);//经销商身份大于自己的
})->orderBy('depth', 'desc')->first();//深度逆序第一个
if (!$consignor) {
$consignor = $lastConsignor;
}
return $consignor;
}
}