123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600 |
- <?php
- namespace App\Http\Controllers\Admin;
- use App\Filters\OrderRentFilter;
- use App\Handlers\BikeControl;
- use App\Handlers\BikeStatusInfoSyncHandler;
- use App\Handlers\OrderRentHandler;
- use App\Http\Requests\OrderRentRequest;
- use App\Http\Resources\OrderRentResource;
- use App\Models\AdminUser;
- use App\Models\AdminUserArea;
- use App\Models\Area;
- use App\Models\Bike;
- use App\Models\LocationsLog;
- use App\Models\OrderRent;
- use App\Models\OrderRentBikeOperate;
- use App\Models\RentOrder;
- use App\Models\User;
- use App\Models\WalletLog;
- use App\Notifications\OrderNoPayNotification;
- use App\Notifications\OrderRefundNotification;
- use App\Utils\Admin;
- use Carbon\Carbon;
- use Illuminate\Http\Request;
- use App\Http\Controllers\Controller;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Support\Facades\Notification;
- class OrderRentController extends Controller
- {
- //
- public function index(OrderRentFilter $filter, Request $request)
- {
- $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 = $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('时间过长不可回溯');
- }
- }
- }
|