user()->orders() ->with('products') ->filter($request->all()) ->latest('id') ->simplePaginate($perPage); return OrderResourceCollection::make($orders); } /** * 创建订单 * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\JsonResponse */ public function store(Request $request) { $validated = $request->validate(array_merge([ 'shipping_address_id' => ['bail', 'nullable', 'int'], 'coupon_id' => ['bail', 'nullable', 'int'], 'note' => ['bail', 'nullable', 'string', 'max:255'], ], match (true) { $request->filled('order_pre') => [ 'order_pre' => ['bail','required', 'int'], ], $request->filled('product') => [ 'product.sku_id' => ['bail', 'required', 'int'], 'product.quantity' => ['bail', 'required', 'int', 'min:1'], ], default => [ 'shopping_cart' => ['bail', 'required', 'array'], ] }), [], [ 'product.sku_id' => '商品', 'product.quantity' => '数量', 'shopping_cart' => '购物车商品', 'shipping_address_id' => '收货地址', 'coupon_id' => '优惠券', 'note' => '订单备注', ]); $user = $request->user(); try { $order = DB::transaction(function () use ($user, $validated, $request) { $orderService = new OrderService(); return match (true) { $request->filled('order_pre') => $orderService->createOrderByPre($user, OrderPre::findOrFail($request->input('order_pre')), $request->input('coupon_id'), $request->input('note')), $request->filled('product') => $orderService->createQuickOrder( $user, $validated['product']['sku_id'], $validated['product']['quantity'], $validated['shipping_address_id'] ?? null, $validated['coupon_id'] ?? null, $validated['note'] ?? null, ), default => $orderService->createShoppingCartOrder( $user, $validated['shopping_cart'], $validated['shipping_address_id'] ?? null, $validated['coupon_id'] ?? null, $validated['note'] ?? null, ), }; }); } catch (QueryException $e) { if (strpos($e->getMessage(), 'Numeric value out of range') !== false) { $e = new BizException('商品库存不足'); } throw $e; } OrderPaid::dispatchIf($order->isPaid(), $order); return OrderResource::make($order); } /** * 查看订单 * * @param int $id * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\JsonResponse */ public function show($id, Request $request) { $order = $request->user()->orders()->findOrFail($id); $order->load('products'); $order->load('lastPackage'); return OrderResource::make($order); } /** * 确认收货/完成订单 * * @param int $id * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\JsonResponse */ public function confirm($id, Request $request) { $user = $request->user(); $clientApp = $request->header('client-app', Device::UNIAPP); $clientVersion = $request->header('client-version'); DB::transaction(function () use ($id, $user, $clientApp, $clientVersion) { $order = $user->orders()->lockForUpdate()->findOrFail($id); // 订单是否可结算 $isSettlable = false; if ($clientApp === Device::UNIAPP && version_compare($clientVersion, '1.3.4', '>=')) { $isSettlable = true; } (new OrderService())->confirm($order, $isSettlable); }); return response()->noContent(); } /** * 取消订单 * * @param int $id * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\JsonResponse */ public function cancel($id, Request $request) { $user = $request->user(); DB::transaction(function () use ($id, $user) { $order = $user->orders()->lockForUpdate()->findOrFail($id); (new OrderService())->cancel($order); }); return response()->noContent(); } /** * 支付订单 * * @param int $id * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\JsonResponse */ public function pay($id, Request $request) { $input = $request->validate([ 'pay_way' => ['bail', 'required'], ]); if (is_null($payway = PayWay::tryFrom($input['pay_way']))) { throw new BizException('支付方式 非法'); } $user = $request->user(); return DB::transaction(function () use ($id, $user, $payway) { $order = $user->orders()->findOrFail($id); return (new OrderService())->pay($order, $payway); }); } /** * 订单包裹列表 */ public function orderPackages($id, Request $request) { $order = $request->user()->orders()->findOrFail($id); return OrderPackageResource::collection($order->packages()->where('is_failed', false)->orderBy('updated_at', 'desc')->get()); } /** * 物流包裹的明细 * * @return void */ public function shippingInfo($id, Request $request) { $package = $request->user()->orderPackages()->where('is_failed', false)->findOrFail($id); return response()->json(array_merge(OrderPackageResource::make($package)->resolve(), [ 'shipping_info'=> KuaidiLog::where(['number'=>$package->shipping_number, 'code'=>$package->shipping_code])->first()?->info, ])); } }