6
0
Fork 0
jiqu-library-server/app/Endpoint/Api/Http/Controllers/Dealer/OrderController.php

480 lines
15 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\Endpoint\Api\Http\Controllers\Dealer;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\Dealer\OrderResource;
use App\Endpoint\Api\Http\Resources\Dealer\OrderSimpleResource;
use App\Enums\DealerLvl;
use App\Enums\PayWay;
use App\Exceptions\BizException;
use App\Exceptions\PayPasswordIncorrectException;
use App\Helpers\Paginator as PaginatorHelper;
use App\Models\DealerOrder;
use App\Models\DealerOrderProduct;
use App\Models\DealerProduct;
use App\Services\Dealer\OrderService;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Throwable;
class OrderController extends Controller
{
/**
* @param \Illuminate\Http\Request $request
* @return void
*/
public function index(Request $request)
{
$cate = $request->input('cate', 'purchase');//获取订单类别
$user = $request->user();
switch ($cate) {
case 'consignor'://发货单
$query = $user->dealerConsignOrders();
break;
default://采购单
$query = $user->dealerOrders();
break;
}
$perPage = PaginatorHelper::resolvePerPage('per_page', 20, 50);
$orders = $query->with('products')
->filter($request->all())
->latest('id')
->simplePaginate($perPage);
return OrderSimpleResource::collection($orders);
}
public function store(Request $request, OrderService $orderService)
{
$input = $request->validate([
'shipping_address_id' => ['bail', 'required', 'int'],
'product_id'=>['bail', 'required', 'int', 'min:0'],
'num'=>['bail', 'required', 'int', 'min:1'],
], [], [
'product_id' => '商品',
'num' => '数量',
'shipping_address_id' => '收货地址',
]);
$product = DealerProduct::online()->findOrFail($input['product_id']);
try {
DB::beginTransaction();
$order = $orderService->quickCreateOrder($request->user(), $product, $input['num'], $input['shipping_address_id']);
DB::commit();
} catch (BizException $e) {
DB::rollBack();
throw $e;
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('下单失败,请稍后再试');
}
return OrderResource::make($order);
}
/**
* 确认订单
*
* @param Request $request
* @param OrderService $orderService
*/
public function checkOrder(Request $request, OrderService $orderService)
{
$input = $request->validate([
'shopping_cart' => ['bail', 'required', 'array'],
], [], [
'shopping_cart'=>'购物车商品',
]);
$user = $request->user();
$shoppingCartItems = $user->dealerShoppingCartItems()->findMany($input['shopping_cart']);
$shoppingCartItems->load('product');
$totalQty = $shoppingCartItems->sum('quantity');
$data = [];
$totalAmount = 0;
foreach ($shoppingCartItems as $item) {
$dealerPrice = $orderService->getSalePrice($user, $item->product, $totalQty);
$data[] = [
'id' => $item->id,
'name' => $item->name,
'cover' => $item->cover,
'sell_price' => $item->sell_price,
'dealer_price' => $dealerPrice,
'quantity' => $item->quantity,
];
$totalAmount += $dealerPrice;
}
return response()->json(['data'=>$data, 'to_lvl'=>$orderService->willBecome($user, $totalAmount)]);
}
/**
* 新下单接口
*/
public function newStore(Request $request, OrderService $orderService)
{
$isQuick = $request->filled('product');
$rules = $isQuick ? [
'product.id' => ['bail', 'required', 'int'],
'product.quantity' => ['bail', 'required', 'int', 'min:1'],
'shipping_address_id' => ['bail', 'required', 'int'],
] : [
'shopping_cart' => ['bail', 'required', 'array'],
'shipping_address_id' => ['bail', 'required', 'int'],
];
$input = $request->validate($rules, [], [
'product.id' => '商品',
'product.quantity' => '数量',
'shopping_cart' => '购物车商品',
'shipping_address_id' => '收货地址',
]);
try {
DB::beginTransaction();
if ($isQuick) {
$product = DealerProduct::online()->findOrFail($input['product']['id']);
$order = $orderService->quickCreateOrder($request->user(), $product, $input['product']['quantity'], $input['shipping_address_id']);
} else {
$order = $orderService->cartCreateOrder($request->user(), $input['shopping_cart'], $input['shipping_address_id']);
}
DB::commit();
} catch (BizException $e) {
DB::rollBack();
throw $e;
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('下单失败,请稍后再试');
}
return OrderResource::make($order);
}
public function show($id, Request $request)
{
$order = DealerOrder::findOrFail($id);
$userId = $request->user()->id;
//既不是采购人,也不是发货人
if (!$order->canCurd($userId)) {
throw new BizException('订单未找到');
}
$refuseLog = $order->isPendinged() ? $order->refuseLogs()->latest('id')->first() : null;
$data = OrderResource::make($order)->toArray($request);
$data['refuse_reason'] = $refuseLog?->reason;
$data['to_lvl'] = (new OrderService())->willBecome($request->user(), $order->total_amount);
return response()->json($data);
}
/**
* 计算订单价格
*
* @return void
*/
public function totalAmount(Request $request, OrderService $orderService)
{
$input = $request->validate([
'product_id'=>['bail', 'required', 'int', 'min:0'],
'num'=>['bail', 'required', 'int', 'min:1'],
]);
$product = DealerProduct::online()->findOrFail($input['product_id']);
$user = $request->user();
$totalAmount = $orderService->totalAmount($user, $product, $input['num']);
return response()->json([
'total_amount'=> $totalAmount,
'to_lvl'=>$orderService->willBecome($user, $totalAmount),
]);
}
/**
* 确认接单
*
* @param [type] $id
* @param Request $request
* @return void
*/
public function confirmOrder($id, Request $request, OrderService $orderService)
{
$order = DealerOrder::findOrFail($id);
$userId = $request->user()->id;
//不是发货人
if (!$order->isConsignor($userId)) {
throw new BizException('订单未找到');
}
$orderService->confirmOrder($order);
return response()->noContent();
}
/**
* 确认打款
*
* @return void
*/
public function payOrder($id, Request $request, OrderService $orderService)
{
$input = $request->validate([
'pay_image' => ['bail', 'string'],
'pay_way' => ['bail', 'string'],
'pay_password' => ['bail', 'required_if:pay_way,wallet'],
'products'=> ['array'],
], [
'pay_password.required_if' => '支付密码 不能为空。',
], [
'pay_image' => '打款凭证',
'pay_way' => '支付方式',
'pay_password' => '支付密码',
]);
$payWay = PayWay::tryFrom($input['pay_way'] ?? 'offline');
if (! in_array($payWay, [PayWay::Offline, PayWay::Wallet, PayWay::WxpayH5, PayWay::WxpayJsApi])) {
throw new BizException('支付方式 非法');
}
$user = $request->user();
$order = $user->dealerOrders()->findOrFail($id);
switch ($payWay) {
case PayWay::Wallet:
if (! $user->wallet?->verifyPassword($input['pay_password'])) {
throw new PayPasswordIncorrectException();
}
break;
case PayWay::WxpayH5:
case PayWay::WxpayJsApi:
if ($order->consignor !== null) {
throw new BizException('订单不是签约订单');
}
break;
}
try {
DB::beginTransaction();
//签约单-处理云库存
if ($order->consignor === null) {
//处理云库存设置如果没有设置则默认云仓库为0。
$products = $input['products'] ?? [];
if ($products) {
$num = 0;
foreach ($order->products as $product) {
//更新云库存
if (isset($products[$product->id]) && ($product->qty + $product->deposit_qty) >= $products[$product->id]) {
DealerOrderProduct::where('id', $product->id)->update([
'qty' => $products[$product->id],
'deposit_qty' =>($product->qty + $product->deposit_qty) - $products[$product->id],
]);
$num += $products[$product->id];
}
}
if ($num < 20) {
throw new BizException('首次发货最少20盒');
}
}
}
$data = $orderService->pay($order, $payWay, $input['pay_image'] ?? null);
DB::commit();
} catch (Throwable $e) {
DB::rollBack();
report($e);
if (! $e instanceof BizException) {
$e = new BizException('操作失败,请刷新后再试');
}
throw $e;
}
return response()->json($data);
}
/**
* 确认收款
*
* @return void
*/
public function paidOrder($id, Request $request, OrderService $orderService)
{
$order = DealerOrder::findOrFail($id);
$userId = $request->user()->id;
//不是发货人
if (!$order->isConsignor($userId)) {
throw new BizException('订单未找到');
}
try {
DB::beginTransaction();
$orderService->paidOrder($order);//确认收款
//3-14号取消确认收款后自动发货
// $orderService->shippingOrder($order);//确认发货
DB::commit();
} catch (QueryException $e) {
DB::rollBack();
if (strpos($e->getMessage(), 'Numeric value out of range') !== false) {
$e = new BizException('当前可发货库存不足');
}
throw $e;
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('操作失败,请刷新后再试');
}
return response()->noContent();
}
/**
* 确认发货
*
* @param [type] $id
* @param Request $request
* @param OrderService $orderService
* @return void
*/
public function shippingOrder($id, Request $request, OrderService $orderService)
{
$order = DealerOrder::findOrFail($id);
$user = $request->user();
//不是发货人
if (!$order->isConsignor($user->id)) {
throw new BizException('订单未找到');
}
$deliveryBill = null;
try {
DB::beginTransaction();
//如果发货人是签约经销商, 则可以使用云仓库发货
if ($user->dealer->lvl?->value >= DealerLvl::Contracted->value) {
$deliveryBill = $orderService->shippingOrderByDeposit($order);
if ($deliveryBill) {
$order->refresh();
//扣除本地库存
$orderService->orderOutQty($order);
} else {
$orderService->shippingOrder($order);//确认发货
}
} else {
$orderService->shippingOrder($order);//确认发货
}
DB::commit();
} catch (BizException $e) {
DB::rollBack();
$e = new BizException($e->getMessage());
throw $e;
} catch (QueryException $e) {
DB::rollBack();
if (strpos($e->getMessage(), 'Numeric value out of range') !== false) {
$e = new BizException('当前可发货库存不足');
}
throw $e;
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('操作失败,请刷新后再试');
}
return response()->json([
'delivery_bill_id'=>$deliveryBill?->id,
]);
}
/**
* 确认收货
*
* @return void
*/
public function shippingedOrder($id, Request $request, OrderService $orderService)
{
$order = DealerOrder::findOrFail($id);
$user = $request->user();
//不是收货人
if (!$order->isUser($user->id)) {
throw new BizException('订单未找到');
}
try {
DB::beginTransaction();
$orderService->shippingedOrder($order);
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('操作失败,请刷新后再试');
}
return response()->noContent();
}
/**
* 取消订单
*
* @param [type] $id
* @param Request $request
* @return void
*/
public function cancelOrder($id, Request $request, OrderService $orderService)
{
$order = DealerOrder::findOrFail($id);
$userId = $request->user()->id;
if (!$order->isUser($userId)) {
throw new BizException('订单未找到');
}
try {
DB::beginTransaction();
$orderService->cancelOrder($order);
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('操作失败,请刷新后再试');
}
return response()->noContent();
}
/**
* 放弃接单/转让订单
*
* @param [type] $id
* @param Request $request
* @param OrderService $orderService
* @return void
*/
public function transferOrder($id, Request $request, OrderService $orderService)
{
$order = DealerOrder::findOrFail($id);
$userId = $request->user()->id;
//不是发货人
if (!$order->isConsignor($userId)) {
throw new BizException('订单未找到');
}
if (!$order->isPending()) {
throw new BizException('订单状态异常,请刷新后再试');
}
try {
DB::beginTransaction();
$orderService->updateOrderConsignor($order);
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('操作失败,请刷新后再试');
}
return response()->noContent();
}
}