user(); $query = $user->orders()->with(['goods', 'merchant'])->filter($request->all()); $list = $query->sort()->paginate($request->input('per_page')); return $this->json(OrderResource::collection($list)); } public function total() { $user = auth('api')->user(); $query = $user->orders(); $maps = [ 'unpay' => OrderStatus::None, 'paid' => OrderStatus::Paid, 'send_full' => OrderStatus::SendFull, 'receive' => OrderStatus::Receive ]; $data = []; foreach($maps as $key => $status) { $data[$key] = $query->clone()->filter(['status' => $status->value])->count(); } return $this->json($data); } public function sure(Request $request) { $request->validate([ 'scene' => ['required', new Enum(OrderScene::class)], 'goods' => [Rule::requiredIf(!$request->filled('cart_id')), 'array'], 'cart_id' => ['array'], 'merchant_id' => [Rule::requiredIf($request->input('scene') === OrderScene::Merchant->value)], ]); $user = auth('api')->user(); $service = OrderStore::init()->user($user)->scene($request->input('scene')); if ($request->filled('merchant_id')) { $merchant = Merchant::findOrFail($request->input('merchant_id')); if (!$merchant->enable()) { throw new OrderException('店铺不可用'); } $service->merchant($merchant); } $goods = $request->input('goods'); if ($request->filled('cart_id')) { $goods = $this->formatCartGoods($user->carts()->whereIn('id', $request->input('cart_id'))->get()); } $service->goods($goods); // 收货地址 $address = null; if ($request->filled('address_id')) { $address = $user->addresses()->find($request->input('address_id')); if (!$address) { return $this->error('收货地址不存在'); } } if (!$address) { $address = $user->addresses()->orderBy('is_default', 'desc')->orderBy('created_at', 'desc')->first(); } $service->ship(ShipWay::Express->value, $this->formatAddress($address)); // 计算最大积分抵扣 $maxScore = floatval($service->orderGoodsList->sum('score_max_amount')); $score = $request->input('score'); $userScore = floatval($user->profit); if (!$score) { $score = $userScore > $maxScore ? $maxScore : $userScore; } $service->score($score); $goodsList = $service->orderGoodsList; $dataList = collect(); foreach($goodsList->groupBy('merchant_id') as $id => $list) { $dataList->push([ 'merchant' => $id ? Merchant::select('id', 'name')->find($id) : ['id' => null, 'name' => '自营店铺'], 'list' => $list ]); } // 付款金额 $payMoney = $service->getPayMoney(); return $this->json([ 'address' => $address ? UserAddressResource::make($address) : null, 'list' => $dataList, 'score' => [ 'has' => $userScore, 'use' => $score, 'max' => $maxScore, 'bonus' => $service->getUserBonus($payMoney), ], 'price' => [ 'goods' => floatval($goodsList->sum('price')), 'ship' => $service->ship['money'], 'coupon' => 0, 'vip' => $service->vip['money'], 'score' => $service->score['money'], 'total' => $payMoney, ] ]); } public function store(Request $request) { $user = auth('api')->user(); $request->validate([ 'scene' => ['required', new Enum(OrderScene::class)] ]); $scene = $request->input('scene'); $store = OrderStore::init()->scene($scene)->user($user)->remarks($request->input('remarks')); // 自营商城下单 if ($scene === OrderScene::Online->value) { $request->validate([ 'goods' => [Rule::requiredIf(!$request->filled('cart_id')), 'array'], 'cart_id' => ['array'], 'address' => [Rule::requiredIf(!$request->filled('address_id')), 'array'], ]); $goods = $request->input('goods'); if ($request->filled('cart_id')) { $goods = $this->formatCartGoods($user->carts()->whereIn('id', $request->input('cart_id'))->get()); } $store->goods($goods); $address = null; if ($request->filled('address_id')) { $address = $user->addresses()->find($request->input('address_id')); if (!$address) { return $this->error('收货地址不存在'); } } if (!$address) { $address = $request->input('address'); } $store->ship(ShipWay::Express->value, $this->formatAddress($address)); $store->score($request->input('score', 0)); } // 店铺下单 else if ($scene === OrderScene::Merchant->value) { $request->validate([ 'goods' => [Rule::requiredIf(!$request->filled('cart_id')), 'array'], 'cart_id' => ['array'], 'merchant_id' => 'required', ]); $merchant = Merchant::findOrFail($request->input('merchant_id')); if (!$merchant->enable()) { throw new OrderException('店铺不可用'); } $store->merchant($merchant); $goods = $request->input('goods'); if ($request->filled('cart_id')) { $goods = $this->formatCartGoods($user->carts()->whereIn('id', $request->input('cart_id'))->get()); } $store->goods($goods); $store->ship(ShipWay::Pick->value); // 验证店铺返现余额是否足够 $payMoney = $store->getPayMoney(); $ratio = $merchant->profit_ratio / 100; $userProfit = round($payMoney * $ratio, 2, PHP_ROUND_HALF_DOWN); $merchantUser = $merchant->user; if ($merchantUser->profit < $userProfit) { throw new OrderException('店铺返现账户余额不足'); } } // 扫码付款 else if ($scene === OrderScene::Scan->value) { $request->validate([ 'money' => 'required', 'merchant_id' => 'required', ]); $merchant = Merchant::findOrFail($request->input('merchant_id')); if (!$merchant->enable()) { throw new OrderException('店铺不可用'); } $store->merchant($merchant); $store->money($request->input('money')); } else { return $this->error('未知下单场景'); } try { DB::beginTransaction(); $order = $store->create(); // 删除购物车商品 if ($request->filled('cart_id')) { $user->carts()->whereIn('id', $request->input('cart_id'))->delete(); } $result = OrderResource::make($order); if ($request->filled('pay_way')) { $result = []; $payData = OrderService::make()->pay($order, $request->input('pay_way')); $result['order'] = OrderResource::make($order); $result['payment'] = $payData; } DB::commit(); return $this->json($result); } catch (\Exception $e) { return $this->error($e->getMessage()); } } public function show($id) { $user = auth('api')->user(); $order = $user->orders()->with(['goods'])->findOrFail($id); return $this->json(OrderResource::make($order)); } public function pay($id, Request $request) { $request->validate([ 'pay_way' => ['required', new Enum(PayWay::class)] ]); $user = auth('api')->user(); $order = $user->orders()->findOrFail($id); try { DB::beginTransaction(); $result = OrderService::make()->pay($order, PayWay::WxMini->value); DB::commit(); return $this->json($result); } catch (\Exception $e) { return $this->error($e->getMessage()); } } public function cancel($id, Request $request) { $user = auth('api')->user(); $order = $user->orders()->findOrFail($id); try { DB::beginTransaction(); OrderService::make()->cancel($order); $order->options()->create([ 'user_type' => get_class($user), 'user_id' => $user->id, 'description' => '用户取消订单', 'attribute' => [ 'is_closed' => 1 ] ]); DB::commit(); return $this->success('订单成功取消'); } catch (\Exception $e) { return $this->error($e->getMessage()); } } public function receive($id) { $user = auth('api')->user(); $order = $user->orders()->findOrFail($id); try { DB::beginTransaction(); OrderService::make()->receive($order); $order->options()->create([ 'user_type' => get_class($user), 'user_id' => $user->id, 'description' => '用户 确认收货', 'attribute' => [ 'is_closed' => 1 ] ]); DB::commit(); return $this->success('收货成功'); } catch (\Exception $e) { return $this->error($e->getMessage()); } } public function destroy($id) { $user = auth('api')->user(); $order = $user->orders()->findOrFail($id); try { DB::beginTransaction(); OrderService::make()->delete($order); DB::commit(); return $this->success('删除成功'); } catch (\Exception $e) { return $this->error($e->getMessage()); } } public function ships($id) { $user = auth('api')->user(); $order = $user->orders()->findOrFail($id); $list = $order->ships()->with(['goods'])->sort()->get(); return $this->json(OrderShipResouce::collection($list)); } public function logistics(Request $request) { $request->validate([ 'order_id' => 'required', 'ship_id' => 'required', ]); $user = auth('api')->user(); $order = $user->orders()->findOrFail($request->input('order_id')); $ship = $order->ships()->findOrFail($request->input('ship_id')); return $this->success(); } protected function formatCartGoods($carts) { $goods = []; foreach($carts as $item) { array_push($goods, [ 'id' => $item->goods_id, 'amount' => $item->amount, 'spec' => $item->spec, 'part' => $item->part, ]); } return $goods; } protected function formatAddress($userAddress) { $address = []; if ($userAddress instanceof UserAddress) { $address = [ 'name' => $userAddress->contact_name, 'phone' => $userAddress->phone, 'region' => [$userAddress->province?->name, $userAddress->city?->name, $userAddress->area?->name], 'zone' => [$userAddress->province_id, $userAddress->city_id, $userAddress->area_id], 'address' => $userAddress->address, 'address_id' => $userAddress->id ]; } else if (is_array($userAddress)) { $address = $userAddress; $region = data_get($address, 'region'); if (!$region || count($region) === 0) { throw new OrderException('收货地址格式不正确'); } $area = Zone::where('name', $region[2])->where('type', 'area')->firstOrFail(); $city = Zone::findOrFail($area->parent_id); $address['zone'] = [$city->parent_id, $area->parent_id, $area->id]; } return $address; } }