id; $orders = OrderRent::query(); $status = $request->get('status') ?? ''; if (empty($status)) { $orders = $orders->where('status', '!=', OrderRent::STATUS_CLOSE_ORDER); } $orders = $orders ->filter($filter) ->orderByDesc('id') ->orderBy('status'); if (!Admin::isAdministrator()) { $area_ids = AdminUser::getAreaIdsByAdminId($admin_id); if (count($area_ids) !== 0) { $orders = $orders->whereIn('area_id', $area_ids); } else { $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->first('area_id'); $area_id = $area_id->area_id ?? 0; $orders = $orders->where('area_id', $area_id); } } $orders = $request->get('all') ? $orders->get() : $orders->paginate(); return $this->ok(OrderRentResource::collection($orders)); } /** * restful API update put * * */ public function update(OrderRentRequest $request, OrderRent $order) { $inputs = $request->validated(); $order->update($inputs); return $this->ok(); } // 订单轨迹 订单列表 public function orderRentLocationsearch(Request $request, OrderRentFilter $filter) { $admin_id = Admin::user()->id; $orders = OrderRent::query(); $status = $request->get('status') ?? ''; if (empty($status)) { $orders = $orders->where('status', '!=', OrderRent::STATUS_CLOSE_ORDER); } $orders = $orders ->filter($filter) ->orderByDesc('id') ->orderBy('status'); if (!Admin::isAdministrator()) { $area_ids = AdminUser::getAreaIdsByAdminId($admin_id); if (count($area_ids) !== 0) { $orders = $orders->whereIn('area_id', $area_ids); } else { $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->first('area_id'); $area_id = $area_id->area_id ?? 0; $orders = $orders->where('area_id', $area_id); } } $orders = $orders->limit(100)->get(); return $this->ok(OrderRentResource::collection($orders)); } /** * 订单状态 订单操作状态 * * @return array order_status 订单状态 * @return array order_orerate_status 订单操作状态 * * */ public function orderRentStatus() { $orderStatus = []; foreach (OrderRent::$statusMaps as $k => $v) { $arr = []; $arr['id'] = $k; $arr['name'] = $v; $orderStatus[] = $arr; } $data['order_status'] = $orderStatus; $orderOperateStatus = []; foreach (OrderRentBikeOperate::$typeMaps as $k => $v) { $arr1 = []; $arr1['id'] = $k; $arr1['name'] = $v; $orderOperateStatus[] = $arr1; } $data['order_operate_status'] = $orderOperateStatus; return $this->ok($data); } /** * 订单操作自行车详情 * * @param $order_id 订单id * * @return object 订单详情 * */ public function orderRentBikeOperate(Request $request) { $order_id = $request->get('order_id'); if (empty($order_id)) return $this->error('参数错误'); $data = OrderRentBikeOperate::query() ->where('order_id', $order_id) ->select(['created_at', 'name']) ->get(); $data2 = OrderRent::find($order_id)->walletLogs->toArray(); $data3 = RentOrder::find($order_id)->walletLogs->toArray(); return $this->ok(['orderRentBikeOperate' => $data, 'walletLogs' => array_merge($data2, $data3)]); } /** * 订单轨迹 * */ public function orderRentLocation(Request $request) { $order_id = $request->get('order_id') ?? ''; if (empty($order_id)) return $this->error('参数错误'); $orderLocations = []; $locationsTimes = []; try { $locationsLog = LocationsLog::query()->where('order_id', (int)$order_id)->where('is_rent', LocationsLog::RENT_YES)->whereBetween('latitude', [3, 53])->whereBetween('longitude', [73, 136])->orderBy('created_at', 'asc')->get(); } catch (\Exception $exception) { Log::error($exception->getMessage()); } if (!empty($locationsLog)) { foreach ($locationsLog as $vv) { $orderLocations[] = [$vv->longitude, $vv->latitude]; $locationsTimes[] = Carbon::parse($vv->created_at)->format('Y-m-d H:i:s'); } } $data = [ 'orderLocations' => $orderLocations, 'locationsTimes' => $locationsTimes, ]; return $this->ok($data); } /** * 修改订单为待支付 * */ public function changeOrderRentStatus(Request $request) { $order_id = $request->get('order_id'); if (empty($order_id)) return $this->error('参数错误'); $closeOrderBool = OrderRentHandler::closeOrderRent($order_id); if (!$closeOrderBool) return $this->error('操作失败,请联系管理员'); $order = OrderRent::find($order_id); $user = User::find($order->user_id); if (!empty($order)) { Notification::send($user, new OrderNoPayNotification($user, $order)); } return $this->ok('关锁成功'); } /** * 结算订单 * * * */ public function settlementOrderRent(Request $request) { $order_id = $request->get('order_id'); if (empty($order_id)) return $this->error('参数错误'); $ridding_money = $request->get('ridding_money') ?? 0; //骑行费 $rent_money = $request->get('rent_money') ?? 0; //租金 $dispatch_money = $request->get('dispatch_money') ?? 0; //调度费 $pay_money = $request->get('pay_money') ?? 0; $order = OrderRent::query()->find($order_id); if (empty($order)) return $this->error('找不到订单信息'); $user_id = $order->user_id; $area_id = $order->area_id; if ($order->status == OrderRent::STATUS_CLOSE_RENT_BIKE) { //1.判断用户钱包余额是否大于支付金额 $user = User::query()->find($user_id); if (empty($user)) return $this->error('出现错误,请联系管理员'); $wallet_money = $user->wallet_money; $result = bcsub($wallet_money, $pay_money, 2); $order->pay_type = OrderRent::PAY_TYPE_ACCOUNT; if ($result < 0) { try { DB::beginTransaction(); // 修改调度费 各种费用 $order->dispatch_money = (float)$dispatch_money; $order->time_money = (float)$ridding_money; $order->rent_money = (float)$rent_money; $order->pay_money = bcadd(bcadd($dispatch_money, $ridding_money, 2), $rent_money, 2); $order->total_money = $order->pay_money; $order->order_total_money = $order->pay_money; $order->save(); //4.给订单车辆操作表添加一条新纪录 $orderRentBikeOperate = new OrderRentBikeOperate(); $orderRentBikeOperate->name = OrderRentBikeOperate::$typeMaps[OrderRentBikeOperate::TYPE_ADMIN_SETTLRMENT] . '修改租用超时费为' . $ridding_money . ',租金为' . $rent_money . ',调度费为' . $dispatch_money; $orderRentBikeOperate->type = OrderRentBikeOperate::TYPE_ADMIN_SETTLRMENT; $orderRentBikeOperate->bike_id = $order->bike_id; $orderRentBikeOperate->order_id = $order_id; $orderRentBikeOperate->user_id = $order->user_id; $orderRentBikeOperate->save(); $user = User::find($order->user_id); if (!empty($order)) { Notification::send($user, new OrderNoPayNotification($user, $order)); } DB::commit(); } catch (\Exception $e) { DB::rollBack(); Log::info($e->getMessage()); return $this->error('操作失败请联系管理员'); } return $this->error('调度费已调整,用户钱包余额不足,无法后台结算'); } // 只有状态为待支付才能后台操作结算 DB::beginTransaction(); try { // 2.更新用户余额 $user->wallet_money = $result; $res1 = $user->save(); if (!$res1) { DB::rollBack(); Log::error('更新用户余额失败'); return $this->error('操作失败请联系管理员'); } // 3.插入钱包消费记录 $wallet_log = new WalletLog(); $wallet_log->name = WalletLog::$typeMaps[WalletLog::TYPE_ADMIN_SUB_BIKE_ORDER]; $wallet_log->type = WalletLog::TYPE_ADMIN_SUB_BIKE_ORDER; $wallet_log->operate_type = WalletLog::OPERATE_TYPE_SUB; $wallet_log->money = (float)bcadd(bcadd($dispatch_money, $ridding_money, 2), $rent_money, 2); $wallet_log->user_id = $user_id; $wallet_log->area_id = $area_id; $wallet_log->log_id = $order_id; $wallet_log->log_type = RentOrder::class; $res2 = $wallet_log->save(); if (!$res2) { DB::rollBack(); Log::error('消费记录插入失败'); return $this->error('操作失败请联系管理员'); } // 3.更新订单 $order->dispatch_money = (float)$dispatch_money; $order->time_money = (float)$ridding_money; $order->rent_money = (float)$rent_money; $order->pay_money = bcadd(bcadd($dispatch_money, $ridding_money, 2), $order->rent_money, 2); $order->total_money = $order->pay_money; $order->order_total_money = $order->pay_money; $order->status = OrderRent::STATUS_COMPLETE_ORDER; // 更新订单状态为已完成 $order->pay_status = OrderRent::PAY_STATUS_OK; //订单为已支付 $order->pay_type = OrderRent::PAY_TYPE_ACCOUNT; // 余额支付 $order->is_admin_settle_order = OrderRent::ADMIN_SETTLE_ORDER_ADMIN; $order->end_use_bike_time = Carbon::now(); $res3 = $order->save(); if (!$res3) { DB::rollBack(); Log::error('更新订单失败'); return $this->error('操作失败请联系管理员'); } //4.给订单车辆操作表添加一条新纪录 $orderRentBikeOperate = new OrderRentBikeOperate(); $orderRentBikeOperate->name = OrderRentBikeOperate::$typeMaps[OrderRentBikeOperate::TYPE_ADMIN_SETTLRMENT] . '修改租用超时费为' . $ridding_money . ',租金为' . $rent_money . ',调度费为' . $dispatch_money; $orderRentBikeOperate->type = OrderRentBikeOperate::TYPE_ADMIN_SETTLRMENT; $orderRentBikeOperate->bike_id = $order->bike_id; $orderRentBikeOperate->order_id = $order_id; $orderRentBikeOperate->user_id = $order->user_id; $res4 = $orderRentBikeOperate->save(); if (!$res4) { DB::rollBack(); Log::error('订单车辆操作插入失败'); return $this->error('操作失败请联系管理员'); } DB::commit(); } catch (\Exception $e) { DB::rollBack(); Log::info($e->getMessage()); return $this->error('操作失败请联系管理员'); } return $this->ok($res3); } else { return $this->error('车辆处于租车中,请刷新后重试'); } } /** * 日租订单返还 * * 返还时修改的 rent_money time_money dispatch_money total_money order_total_money * * */ public function orderRentReturnMoney(Request $request) { $order_id = $request->get('order_id'); $return_type = $request->get('return_type') ?? ''; if ($return_type !== 'wallet' && $return_type !== 'wechat') return $this->error('返还类型错误'); if (empty($order_id) || empty($return_type)) return $this->error('参数错误'); $return_ridding_money = $request->get('ridding_money') ?? 0; $return_dispatch_money = $request->get('dispatch_money') ?? 0; $return_base_rent_money = $request->get('base_rent_money') ?? 0; if ($return_ridding_money == 0 && $return_dispatch_money == 0 && $return_base_rent_money == 0) { return $this->error('返还金额为0,请填写返还金额'); } $order = OrderRent::query()->find($order_id); if (empty($order)) return $this->error('找不到该订单,请联系管理员'); if ($order->is_refund_money == OrderRent::REFUND_MONEY_OK) { return $this->error('此订单已返还过了 '); } // 大于24 * 5小时 不能返还 $order_create_time = Carbon::now()->diffInHours($order->updated_at); if (abs($order_create_time) > 24 * 5) { return $this->error('返还已过期,不能进行返还操作'); } $user_id = $order->user_id; $area_id = $order->area_id; $dispatch_money = $order->dispatch_money; //订单调度费 $rent_money = $order->rent_money;//基础租金 $time_money = $order->time_money;// 超时费 $total_money = $order->total_money; //订单骑行费(不带基础租金) $pay_money = $order->pay_money; //订单实际二次支付费用 $order_total_money = $order->order_total_money; //订单总收入 if (bcsub($dispatch_money, $return_dispatch_money, 2) < 0) { return $this->error('返还调度费不能大于' . $dispatch_money); } if (bcsub($rent_money, $return_base_rent_money, 2) < 0) { return $this->error('返还基础租金不能大于' . $rent_money); } if (bcsub($time_money, $return_ridding_money, 2) < 0) { return $this->error('返还骑行费不能大于' . $total_money - $dispatch_money); } $return_money = bcadd(bcadd($return_dispatch_money, $return_ridding_money, 2), $return_base_rent_money, 2); if (bcsub($order_total_money, $return_money, 2) < 0) { return $this->error('返还金额不能大于' . $pay_money); } DB::beginTransaction(); try { $old_pay_money = $order->pay_money; //1.更新订单 $order->dispatch_money = bcsub($dispatch_money, $return_dispatch_money, 2); $order->rent_money = bcsub($rent_money, $return_base_rent_money, 2); $order->time_money = bcsub($time_money, $return_ridding_money, 2); $order->total_money = bcsub($total_money, $return_money, 2); $order->order_total_money = bcsub($order_total_money, $return_money, 2); $order->pay_money = $order->total_money; $order->is_refund_money = OrderRent::REFUND_MONEY_OK; $res1 = $order->save(); if (!$res1) { DB::rollBack(); Log::error('更新订单失败'); return $this->error('操作失败请联系管理员'); } if ($return_type === 'wallet') { $return_type_name = '退平台钱包'; //2.插入钱包记录 $wallet_log = new WalletLog(); $wallet_log->name = WalletLog::$typeMaps[WalletLog::TYPE_ADMIN_ADD_TO_WALLET]; $wallet_log->type = WalletLog::TYPE_ADMIN_ADD_TO_WALLET; $wallet_log->operate_type = WalletLog::OPERATE_TYPE_ADD; $wallet_log->money = (float)$return_money; $wallet_log->user_id = $user_id; $wallet_log->area_id = $area_id; $wallet_log->log_id = $order_id; $wallet_log->log_type = RentOrder::class; $res2 = $wallet_log->save(); if (!$res2) { DB::rollBack(); Log::error('插入钱包记录失败'); return $this->error('操作失败请联系管理员'); } //3.更新用户余额 $user = User::query()->find($user_id); $wallet_money = $user->wallet_money; $user->wallet_money = bcadd($wallet_money, $return_money, 2); $res3 = $user->save(); if (!$res3) { DB::rollBack(); Log::error('更新用户余额失败'); return $this->error('操作失败请联系管理员'); } $user = User::find($order->user_id); // 返还通知 Notification::send($user, new OrderRefundNotification($user, $order, $return_money, $return_type_name)); DB::commit(); } else if ($return_type === 'wechat') { $return_type_name = '原路退回'; //退微信 if ($order->pay_type == OrderRent::PAY_TYPE_ACCOUNT) { DB::rollBack(); return $this->error('此订单为余额支付 '); } //插入钱包记录 增加 $wallet_log_add = new WalletLog(); $wallet_log_add->name = WalletLog::$typeMaps[WalletLog::TYPE_ADD_WECHAT_PAY_ORDER_MONEY]; $wallet_log_add->type = WalletLog::TYPE_ADD_WECHAT_PAY_ORDER_MONEY; $wallet_log_add->operate_type = WalletLog::OPERATE_TYPE_ADD; $wallet_log_add->money = (float)$return_money; $wallet_log_add->user_id = $user_id; $wallet_log_add->area_id = $area_id; $wallet_log_add->log_id = $order_id; $wallet_log_add->log_type = RentOrder::class; $wallet_log_add->save(); //3.插入钱包记录 减少 $wallet_log = new WalletLog(); $wallet_log->name = WalletLog::$typeMaps[WalletLog::TYPE_SUB_ORDER_MONEY_PAY_WECHAT]; $wallet_log->type = WalletLog::TYPE_SUB_ORDER_MONEY_PAY_WECHAT; $wallet_log->operate_type = WalletLog::OPERATE_TYPE_SUB; $wallet_log->money = -(float)$return_money; $wallet_log->user_id = $user_id; $wallet_log->area_id = $area_id; $wallet_log->log_id = $order_id; $wallet_log->status = WalletLog::STATUS_PAUSE; $wallet_log->log_type = RentOrder::class; $res2 = $wallet_log->save(); if (!$res2) { DB::rollBack(); Log::error('插入钱包记录失败'); return $this->error('操作失败请联系管理员'); } //退微信 $payment = app('wechat.payment'); // 微信支付 $refund_no = $order->no; $result = $payment->refund->byOutTradeNumber($order->no, $refund_no, wechat_fee($old_pay_money), wechat_fee($return_money), [ // 可在此处传入其他参数,详细参数见微信支付文档 'refund_desc' => '退订单支付费用', ]); if ($result['return_code'] === 'SUCCESS') { $user = User::find($order->user_id); // 返还通知 Notification::send($user, new OrderRefundNotification($user, $order, $return_money, $return_type_name)); DB::commit(); return $this->ok('退还成功'); } else { Log::error('微信退款接口失败'); DB::rollBack(); return $this->error('退还失败,请联系管理员'); } } else { DB::rollBack(); return $this->error('返还类型错误'); } } catch (\Exception $e) { DB::rollBack(); Log::info($e->getMessage()); return $this->error('操作失败请联系管理员'); } return $this->ok($res3); } /* * 订单位置详情 * @params 订单id * @return mongo中最后一个位置 根据订单查Mongo中最后一个位置 * */ public function orderRentDetailPosition(Request $request) { $order_id = $request->get('order_id') ?? ''; if (empty($order_id)) return $this->error('参数错误'); $order = OrderRent::find($order_id); $orderPosition = LocationsLog::query()->where('order_id', $order_id)->where('is_rent', LocationsLog::RENT_YES) ->whereBetween('latitude', [3, 53])->whereBetween('longitude', [73, 136])->orderByDesc('created_at')->first(); $bike_no = $order->bike_no; $bikePositioin = LocationsLog::getNewestLocationByBikeNo($bike_no); $end_use_bike_location = json_decode($order->end_use_bike_location); $data = [ 'orderPosition' => [$orderPosition->longitude ?? $end_use_bike_location->longitude, $orderPosition->latitude ?? $end_use_bike_location->latitude], 'bikePosition' => [$bikePositioin['lng'] ?? 0, $bikePositioin['lat'] ?? 0] ]; return $this->ok($data); } /** * 订单回溯到骑行状态 * */ public function changeRentOrderRiding(Request $request) { $order_id = $request->get('order_id'); if (empty($order_id)) return $this->error('参数错误'); $order = OrderRent::find($order_id); if (empty($order)) return $this->error('找不到该订单'); $order_end_time = Carbon::now()->diffInHours($order->end_use_bike_time); if ($order->status == OrderRent::STATUS_CLOSE_RENT_BIKE && $order_end_time < 2) { // 2小时内可回溯 try { DB::beginTransaction(); $bike = Bike::find($order->bike_id); $bike->is_riding = Bike::RIDING_YES; $bike->is_rent = Bike::RENT_YES; $bike->save(); $order->status = OrderRent::STATUS_RENT_BIKE; $order->save(); $orderBikeOperate = new OrderRentBikeOperate(); $orderBikeOperate->name = OrderRentBikeOperate::$typeMaps[OrderRentBikeOperate::TYPE_ADMIN_ORDER_BACK]; $orderBikeOperate->type = OrderRentBikeOperate::TYPE_ADMIN_ORDER_BACK; $orderBikeOperate->bike_id = $order->bike_id; $orderBikeOperate->order_id = $order_id; $orderBikeOperate->user_id = $order->user_id; $orderBikeOperate->is_admin = OrderRentBikeOperate::IS_ADMIN_YES; $orderBikeOperate->save(); DB::commit(); (new BikeStatusInfoSyncHandler())->toBikeRideStatus(BikeStatusInfoSyncHandler::ROLE_USER, $order->bike_no, [ 'id' => $order_id, 'area_id' => $order->area_id, 'bike_id' => $order->bike_id, 'is_rent' => 1, ]); (new BikeStatusInfoSyncHandler())->toBikeRentWaitRideStatus($bike->bike_no); return $this->ok('操作成功'); } catch (\Exception $e) { Log::error($e->getMessage()); return $this->error('操作失败,请联系管理员'); } } else { return $this->error('时间过长不可回溯'); } } }