get('lat'); $lng = $request->get('lng'); try { // 查找最近车的bike_no $options = ['WITHDIST' => true, 'SORT' => 'ASC', 'WITHCOORD' => true]; $redis = Redis::connection(); $nearby_bikes = $redis->georadius(Bike::REDIS_BIKE_LOCATION_TAG, $lng, $lat, 1, 'km', $options); $bikes = []; if (count($nearby_bikes)) { $bikes = array_map(function ($val) { return [ 'bike_no' => $val[0], 'distance' => $val[1], 'latitude' => $val[2][1], 'longitude' => $val[2][0], 'iconPath' => 'http://resource.weilaigo.l4j.cn/bluebike.png', 'width' => 24, 'height' => 28, 'zIndex' => 1111, 'id' => $val[0] ]; }, $nearby_bikes); $options = ['SORT' => 'ASC', 'COUNT' => 1]; $redis = Redis::connection(); $area_ids = $redis->georadius(Area::REDIS_AREAS_LOCATION_TAG, $lng, $lat, 30, 'km', $options); if (count($area_ids) === 1) { $area_id = $area_ids[0]; $bike_nos = array_column($bikes, 'bike_no'); $batteryPower = (new AreaSettingRepository(new AreaSetting()))->byAreaIdGetBatteryPower($area_id); if ($batteryPower) { $b_nos = Bike::whereIn('bike_no', $bike_nos)->where('battery_power', '<=', $batteryPower)->pluck('bike_no'); if (count($bike_nos)) { foreach ($b_nos as $b_no) { $key = array_search($b_no, $bike_nos); unset($bikes[$key]); } // foreach ($bikes as $key => $bike) { // if (in_array($bike['bike_no'], $b_nos->toArray())) { // unset($bikes[$key]); // } // } } } $bikes = array_values($bikes); } } return $this->response->array($bikes); } catch (\Exception $exception) { $this->errorException($exception->getMessage()); } } /** * 获取单个车的信息 * @param $bike_no * @param BikeRepository $bikeRepository * @return mixed * User: Mead */ public function show($bike_no, BikeRepository $bikeRepository) { try { $bike = $bikeRepository->byBikeNo($bike_no); return $this->response->item($bike, BikeTransformer::class); } catch (\Exception $exception) { $this->errorException('获取单车数据异常'); } } /** * 响铃 * @param BikeNoRequest $request * @return mixed * User: Mead */ public function findBike($bike_no, BikeRepository $bikeRepository) { try { if (!$bikeRepository->byNoIsBikeCanRide($bike_no)) { return $this->errorNoValidation('车找不到或车暂停使用'); } $box_no = $bikeRepository->byNoGetBoxNO($bike_no); // $re = BikeControl::bellBike($box_no); $re = (new BaseBikeControl($box_no))::bellBike(); return $this->response->array([ 'is_ok' => $re ]); } catch (\Exception $exception) { return $this->errorException($exception->getMessage()); } } /** * 用车订单(开车) * User: Mead */ public function openLock(BikeOpenStoreOrderRequest $request, OrderRepository $orderRepository, BikeRepository $bikeRepository, RentOrderRepository $rentOrderRepository, AreaSettingRepository $areaSettingRepository, PunishmentOrderRepository $punishmentOrderRepository, AreaRepository $areaRepository, UserRepository $userRepository) { $bike_no = $request->get('bike_no'); $bike_id = $bikeRepository->byBikeNoGetId($bike_no); $area_id = $request->get('area_id'); $lat = $request->get('lat'); $lng = $request->get('lng'); $cache_key = "RIDE_ORDER_{$bike_no}"; if (Cache::has($cache_key)) { return $this->errorNoValidation('您提交的太频繁了,请一会再提交!'); } Cache::put($cache_key, 1, Carbon::now()->addSeconds(5)); if (!$bike_id) { return $this->errorNoValidation('非法请求'); } // if (time() >= strtotime("2024-06-06 23:00:00")) { // return $this->errorNoValidation('服务升级,临时暂停,请谅解!'); // } // if (time() > strtotime('2022-06-08 00:00:00')) { // return $this->errorNoValidation('服务升级,暂停服务,请谅解!'); // } $setting = $areaSettingRepository->byAreaId($area_id); $user = $this->user; // 判断区域是否需要缴纳押金 if ($setting['is_deposit'] == AreaSetting::DEPOSIT_OK) { // 判断用户押金,授权,认证,手机号状态是否正常 if ((int)$user->is_deposit === User::DEPOSIT_NO) { return $this->errorNoValidation('请您先交纳押金'); } } // if ((int)$user->deposit_type === User::DEPOSIT_CARD && (int)$user->is_deposit === User::DEPOSIT_OK) { // // 押金类型为免押金卡 判断是否过期 // if (!$userRepository->isDepositCardExpired($user->id)) { // return $this->errorNoValidation('免押金卡已到期,请您先交纳押金'); // } // } // 判断用户押金,授权,认证,手机号状态是否正常 if ((int)$user->is_bind_mobile === User::BIND_MOBILE_NO) { return $this->errorNoValidation('请先绑定您的手机号'); } if ((int)$user->is_card_certified === User::CARD_NO) { return $this->errorNoValidation('请您先完善实名认证'); } if ((int)$user->is_match_ride_age === User::RIDE_BIKE_AGE_NO) { return $this->errorNoValidation('未成年人禁止骑车'); } // $area = $areaRepository->byIdGetModelRedis($area_id); // if ($area) { // return $this->errorNoValidation('暂无运营区域!'); // } $punish = $punishmentOrderRepository->checkNoPayModel($user->id); if (!$punish) return $this->errorNoValidation('您有罚单未支付,请先处理'); if ($setting['is_advance_recharge'] && $user->wallet_money <= 0) { return $this->errorNoValidation('余额不足,请先充值'); } // 判断用户是否有为支付的订单 if ($orderRepository->byUserIdCheckIsExistRideOrder($user->id)) { return $this->errorNoValidation('您有未完成的订单,请先处理'); } if ($setting['is_open_day_rent'] && $rentOrderRepository->byUserIdCheckIsExistNoPayOrder($user->id)) { return $this->errorNoValidation('您有未支付的租车订单,请先处理'); } // 判断车的状态是正常 if (!$bikeRepository->isBikeCanRide($bike_id)) { return $this->errorNoValidation('该车暂不能用'); } // 判断用户是否在车的距离范围内 $bike = $bikeRepository->byIdGetModel($bike_id); if ($bike->put_area_id == 38) { if ($setting['is_advance_recharge'] && $user->wallet_money < 20) { return $this->errorNoValidation('余额不能低于30,请先充值'); } } // if ($bike->put_area_id == 23) { // $wi = date('w'); // if (!in_array($wi, [0, 6])) { // $h = date('H'); // $i = date('i'); // if ($h < 17 || ($h >= 23 && $i > 30)) { // return $this->errorNoValidation('服务时间:15:00~11:30[工作日];周六周日全天。'); // } // } // } // 临时增加使用车权限 // if($bike->put_area_id == 11){ // $redis = Redis::connection(); // // if(!$redis->sismember(CacheMap::FREE_MEMBERS,$user->mobile)) return $this->errorNoValidation('暂无权限使用该车'); // } //以车的区域为主 if ($bike->put_area_id !== $area_id) { $area_id = $bike->put_area_id; $setting = $areaSettingRepository->byAreaId($area_id); if ($setting['is_advance_recharge'] && $user->wallet_money <= 0) { return $this->errorNoValidation('余额不足,请先充值'); } if ($setting['is_open_day_rent'] && $rentOrderRepository->byUserIdCheckIsExistNoPayOrder($user->id)) { return $this->errorNoValidation('您有未支付的租车订单,请先处理'); } } // $options = ['SORT' => 'ASC']; // $redis = Redis::connection(); // $nearby_bikes = $redis->georadius(Bike::REDIS_BIKE_LOCATION_TAG, $lng, $lat, 1, 'km', $options); // if (!in_array($bike->bike_no, $nearby_bikes)) { // return $this->errorNoValidation('小主,咱俩有点远!'); // } $box_no = $bikeRepository->byNoGetBoxNO($bike_no); try { $order = DB::transaction(function () use ($bikeRepository, $user, $bike_no, $bike_id, $area_id, $lat, $lng, $box_no) { $users = User::find($user['id']); // 创建订单 $data = [ 'user_id' => $user['id'], 'no' => Order::makeNo(), 'bike_no' => $bike_no, 'bike_id' => $bike_id, 'area_id' => $area_id, 'phone_detail' => $users->userPhoneDetail->detail ?? '', 'start_use_bike_time' => now(), 'start_use_bike_location' => [ 'latitude' => $lat, 'longitude' => $lng, ], 'status' => Order::STATUS_RIDE_BIKE ]; $order = Order::create($data); // 开锁 // BikeControl::openLock($box_no); (new BaseBikeControl($box_no))::openLock(); // 记录日志信息 OrderBikeOperate::log($order->id, OrderBikeOperate::TYPE_OPEN_BIKE, $bike_id, $user->id, $lat, $lng); // 更新车的信息(真在骑行中) $bikeRepository->byIdUpdateRideOk($bike_id); // 更新orders redis (new BikeStatusInfoSyncHandler())->toBikeRideStatus(BikeStatusInfoSyncHandler::ROLE_USER, $bike_no, [ 'id' => $order->id, 'bike_id' => $order->bike_id, 'area_id' => $order->area_id ]); return $order; }); // BikeControl::openLock($box_no); (new BaseBikeControl($box_no))::openLock(); if (!$user->register_area_id) { $user->register_area_id = $area_id; $user->save(); } } catch (\Exception $exception) { return $this->errorNoValidation($exception->getMessage()); } return $this->response->item($order, OrderTransformer::class); } /** * 结束订单 * User: Mead */ public function closeLock(BikeCloseOrderRequest $request, OrderRepository $orderRepository, AreaSettingRepository $areaSettingRepository, BikeRepository $bikeRepository, LocationLogRepository $locationLogRepository) { try { $bike_no = $request->get('bike_no'); $order_no = $request->get('order_no'); $lat = $request->get('lat'); $lng = $request->get('lng'); $order = $orderRepository->byNoGetRideOrder($order_no); if (!$order) { return $this->errorNoValidation('订单不存在或订单已结算'); } $user_id = optional($this->user)->id; $cache_key = "RIDE_CLOSE_ORDER_{$user_id}"; if (Cache::has($cache_key)) { return $this->errorNoValidation('您提交的太频繁了,请一会再提交!'); } Cache::put($cache_key, 1, Carbon::now()->addSeconds(3)); // 30秒内关车,关闭订单 $second = Carbon::now()->diffInSeconds(Carbon::parse($order->start_use_bike_time)); if ($second < AreaSetting::CLOSE_BIKE_TIME) { // 检查用户是否恶意临时关锁 if ($orderRepository->checkUserMoreCloseOrder($this->user->id)) { return $this->errorNoValidation('您今天太频繁操作车辆'); } } $box_no = $bikeRepository->byNoGetBoxNO($order->bike_no); //获取车的最后位置 $location = $locationLogRepository->byBikeNoGetLastLocation($order->bike_no); //运动中不能锁车 if ($location['speed']) { // BikeControl::nowBikeLocation($box_no); (new BaseBikeControl($box_no))::nowBikeLocation(); // return $this->errorNoValidation('运动中不能关锁', 450); } // 更新车的信息 $bikeModel = $bikeRepository->byIdGetModel($order->bike_id); $bikeModel->is_riding = Bike::RIDING_NO; $bikeModel->last_use_bike_end_time = date('Y-m-d H:i:s'); // 删除redis订单 if ($location['lat'] <= 0) { $location['lat'] = $lat; $location['lng'] = $lng; } // 删除临时停车key $key = sprintf(CacheMap::BIKE_TEM_WAIT, $bike_no); app()->redis->del($key); // 判断是否经常这样操作(未做) if ($second <= AreaSetting::CLOSE_BIKE_TIME) { // BikeControl::closeLock($box_no); (new BaseBikeControl($box_no))::closeLock(); // 记录日志信息 OrderBikeOperate::log($order->id, OrderBikeOperate::TYPE_CLONE_BIKE, $order->bike_id, $this->user->id, $lat, $lng); // 关闭订单 $order->status = Order::STATUS_CLOSE_ORDER; $order->end_use_bike_time = now(); $order->end_use_bike_location = [ 'latitude' => $lat, 'longitude' => $lng, ]; $order->save(); $bikeModel->save(); //更新redis状态 (new BikeStatusInfoSyncHandler())->toBikeWaitRideStatus($bike_no, $location['lng'], $location['lat']); // 记录临时关锁 return $this->response->item($order, OrderTransformer::class); } else { // BikeControl::closeLock($box_no); // 记录日志信息 OrderBikeOperate::log($order->id, OrderBikeOperate::TYPE_CLONE_BIKE, $order->bike_id, $this->user->id, $lat, $lng); } // 保存轨迹信息 // 结束订单 $setting = $areaSettingRepository->byAreaId($order->area_id); // 是否处于临时停车的状态 if ((int)$order->status === Order::STATUS_PAUSE_BIKE) { $order->pause_bike_time_length += Carbon::now()->diffInMinutes(Carbon::parse($order->pause_bike_time)); } $order->status = Order::STATUS_CLOSE_BIKE; $order->end_use_bike_time = now(); $order->end_use_bike_location = [ 'latitude' => $lat, 'longitude' => $lng, ]; //计算用车时间 $order->use_bike_time_length = ceil($second / 60); // 计算价格 if (bccomp($setting->starting_price_time, $order->use_bike_time_length) >= 0) { // 起步价时间内只收起步价 $time_money = $setting->starting_price; } else { $time_money = $setting->per_money * ceil(bcsub($order->use_bike_time_length, $setting->starting_price_time) / $setting->per_minute); $time_money = bcadd($time_money, $setting->starting_price, 2); } // $time_money = $setting->per_money * ceil($order->use_bike_time_length / $setting->per_minute); // 计算是否在免费分钟内 if ($setting->is_minute_free == AreaSetting::FREE_MINUTE_OK && $setting->many_minute_free >= $order->use_bike_time_length) { if ($setting->minute_free_times == 0) { $time_money = 0; if ($order->preferential_type == 0) { $order->preferential_type = arr2str([Order::PREFERENTIAL_FREE_MINUTE], '-'); } else { $arr = str2arr($order->preferential_type, '-'); $order->preferential_type = arr2str(array_merge($arr, [Order::PREFERENTIAL_FREE_MINUTE]), '-'); } } else { $key = sprintf(CacheMap::FREE_MINUTE_USER_ID, $order->user_id); app()->redis->sadd($key, $order->id); app()->redis->expireat($key, Carbon::tomorrow()->timestamp); if (app()->redis->scard($key) <= $setting->minute_free_times) { $time_money = 0; if ($order->preferential_type == 0) { $order->preferential_type = arr2str([Order::PREFERENTIAL_FREE_MINUTE], '-'); } else { $arr = str2arr($order->preferential_type, '-'); $order->preferential_type = arr2str(array_merge($arr, [Order::PREFERENTIAL_FREE_MINUTE]), '-'); } } } } if ($time_money < 0) { $time_money = 0; } if ($time_money > 59) { $time_money = 59; } //计算骑行距离 $order->use_bike_distance_length = bcdiv($location['mileage'], 1000, 2); // 根据起始点计算 // $order->use_bike_distance_length = getDistance($order->start_use_bike_location['longitude'], $order->start_use_bike_location['latitude'], $order->end_use_bike_location['longitude'], $order->end_use_bike_location['latitude']); // 判断车是否在停车的区域 $order->dispatch_money = 0; $BikeHandler = new BikeHandler(); $dispatch_money = 0; if ((int)$areaSettingRepository->byAreaIdGetIsWholeAreaHuanche($order->area_id) === AreaSetting::WHOLE_AREA_HUANCHE_NO) { $is_huanche = $BikeHandler->byLocationCheckIsInStopParking($location['lat'], $location['lng'], $order->area_id, $lat, $lng); $bikeModel->is_in_parking = Bike::IN_PARKING_YES; if (!$is_huanche['status']) { // 不在还车点 不能还车 临时增加。。。。。。。 // if ($setting->is_parking == AreaSetting::PARKING_OK) return $this->errorNoValidation('不在还车点,不能关锁'); // 不在还车点 $dispatch_money = $BikeHandler->byDistanceGetDistanceMoney($is_huanche['distance'], $setting); $order->dispatch_money = $dispatch_money; $bikeModel->is_in_parking = Bike::IN_PARKING_NO; } } else { //全区域内可停 $bikeModel->is_in_parking = Bike::IN_PARKING_YES; //检查是否在禁停区 $is_ban_stop_bike = $BikeHandler->byLocationCheckIsInBanStopParking($location['lat'], $location['lng'], $order->area_id, $lat, $lng); if ($is_ban_stop_bike) { return $this->errorNoValidation('禁停区域内禁止停车!'); // // 在禁停区 收取调度费 // $is_huanche = $BikeHandler->byLocationCheckIsInStopParking($location['lat'], $location['lng'], $order->area_id, $lat, $lng); // // $dispatch_money = $BikeHandler->byDistanceGetDistanceMoney($is_huanche['distance'], $setting); // $order->dispatch_money = $dispatch_money; } } if (Cache::get('ORDER:expectOrderMoney:' . $order->id, false) && $dispatch_money > 0) { Log::error("*********ORDER:expectOrderMoney:************ no: {$order_no}, dispatch_money: {$dispatch_money}, "); $order->dispatch_money = 0; $bikeModel->is_in_parking = Bike::IN_PARKING_YES; } $order->time_money = $time_money; $order->pause_money = 0; $order->preferential_money = 0; $order->order_money = bcadd($time_money, $order->dispatch_money, 2); $order->pay_money = $order->order_money; $order->pay_type = Order::PAY_STATUS_NO; $order->total_money = bcadd($time_money, $order->dispatch_money, 2); $order->save(); $bikeModel->save(); //更新redis状态 (new BikeStatusInfoSyncHandler())->toBikeWaitRideStatus($bike_no, $location['lng'], $location['lat']); //关锁 // BikeControl::closeLock($box_no); (new BaseBikeControl($box_no))::closeLock(); // 记录日志信息 // OrderBikeOperate::log($order->id, OrderBikeOperate::TYPE_CLONE_BIKE, $order->bike_id, $this->user->id, $lat, $lng); return $this->response->item($order, OrderTransformer::class); } catch (HttpException $exception) { return $this->errorNoValidation($exception->getMessage(), $exception->getStatusCode()); } } /** * 临时关锁 * User: Mead */ public function temporaryCloseLock(BikeCloseOrderRequest $request, OrderRepository $orderRepository, BikeRepository $bikeRepository, LocationLogRepository $locationLogRepository) { $bike_no = $request->get('bike_no'); $order_no = $request->get('order_no'); $lat = $request->get('lat'); $lng = $request->get('lng'); try { $user = $this->user; $order = $orderRepository->byNoGetRideOrder($order_no); if (!$order) { return $this->errorBadRequest('请求非法'); } $user_id = $this->user->id; $cache_key = "ORDER_TEMPORARY_CLOSE_BIKE_{$user_id}"; if (Cache::has($cache_key)) { return $this->errorNoValidation('您提交的太频繁了,请一会再提交!'); } Cache::put($cache_key, 1, Carbon::now()->addSeconds(3)); //获取车的最后位置 $location = $locationLogRepository->byBikeNoGetLastLocation($order->bike_no, CacheMap::IS_OPEN_MONGODB_DUG); $box_no = $bikeRepository->byNoGetBoxNO($order->bike_no); // //运动中不能锁车 if ($location['speed']) { // BikeControl::nowBikeLocation($box_no); (new BaseBikeControl($box_no))::nowBikeLocation(); // return $this->errorNoValidation('运动中不能关锁', 450); } $order->status = Order::STATUS_PAUSE_BIKE; $order->pause_bike_time = now(); $order->save(); // 关锁 // BikeControl::temporaryCloseLock($box_no); (new BaseBikeControl($box_no))::temporaryCloseLock(); // 记录日志信息 OrderBikeOperate::log($order->id, OrderBikeOperate::TYPE_PAUSE_CLONE_BIKE, $order->bike_id, $user->id, $lat, $lng); //修改rides (new BikeStatusInfoSyncHandler())->toBikeTemporaryWaitRideStatus($bike_no); // 延迟分发一个临时停车超过30分 提醒队列 $key = sprintf(CacheMap::BIKE_TEM_WAIT, $bike_no); app()->redis->setex($key, CacheMap::BIKE_TEM_WAIT_TIME, Carbon::now()); $mobile = $user->mobile; $start_use_time = $order->start_use_bike_time; $this->dispatch(new SendSMSBikeTemporaryWaitOverThirtyJob($mobile, $bike_no, $start_use_time, $key, Carbon::now()->addMinutes(30))); $this->dispatch(new BikeTemporaryWaitOverThirtyAutoCloseOrderJob($mobile, $bike_no, $start_use_time, $key, Carbon::now()->addMinutes(60))); return $this->response->array([ 'is_close_lock' => true ]); } catch (HttpException $exception) { return $this->errorNoValidation($exception->getMessage(), $exception->getStatusCode()); } } /** * 临时开锁 * User: Mead */ public function temporaryOpenLock(BikeCloseOrderRequest $request, OrderRepository $orderRepository, BikeRepository $bikeRepository) { try { $bike_no = $request->get('bike_no'); $order_no = $request->get('order_no'); $lat = $request->get('lat'); $lng = $request->get('lng'); $user = $this->user; $order = $orderRepository->byNoGetRideOrder($order_no); if (!$order) { return $this->errorNoValidation('订单不存在或订单已结算'); } $user_id = $this->user->id; $cache_key = "ORDER_TEMPORARY_OPEN_BIKE_{$user_id}"; if (Cache::has($cache_key)) { return $this->errorNoValidation('您提交的太频繁了,请一会再提交!'); } Cache::put($cache_key, 1, Carbon::now()->addSeconds(3)); $order->status = Order::STATUS_RIDE_BIKE; $order->pause_bike_time_length += Carbon::now()->diffInMinutes(Carbon::parse($order->pause_bike_time)); $order->save(); // 开锁 $box_no = $bikeRepository->byNoGetBoxNO($bike_no); // BikeControl::temporaryOpnLock($box_no); (new BaseBikeControl($box_no))::temporaryOpnLock(); // 记录日志信息 OrderBikeOperate::log($order->id, OrderBikeOperate::TYPE_PAUSE_OPEN_BIKE, $order->bike_id, $user->id, $lat, $lng); (new BikeStatusInfoSyncHandler())->toBikeTemporaryRideStatus($bike_no); // 删除临时停车时得缓存key $key = sprintf(CacheMap::BIKE_TEM_WAIT, $bike_no); app()->redis->del($key); return $this->response->array([ 'is_open_lock' => true ]); } catch (HttpException $exception) { return $this->errorNoValidation($exception->getMessage(), $exception->getStatusCode()); } } /** * 判断是否在运营范围 * Author: Mead */ public function checkBikeIsRidingArea(BikeCloseOrderRequest $request, BikeRepository $bikeRepository, OrderRepository $orderRepository, AreaSettingRepository $areaSettingRepository, LocationLogRepository $locationLogRepository, AreaRepository $areaRepository) { $bike_no = $request->get('bike_no'); $order_no = $request->get('order_no'); $lat = $request->get('lat'); $lng = $request->get('lng'); try { $order = $orderRepository->byNo($order_no); if (!$order) return $this->errorBadRequest('非法请求'); $second = Carbon::now()->diffInSeconds(Carbon::parse($order->start_use_bike_time)); if ($second < AreaSetting::CLOSE_BIKE_TIME) { //小于60秒直接锁车 return [ 'is_close_order' => true, ]; } $user_id = $this->user['id']; $cache_key = "ORDER_CHECK_BIKE_IS_RIDINGAREA_{$user_id}"; if (Cache::has($cache_key)) { return $this->errorNoValidation('您提交的太频繁了,请一会再提交!'); } Cache::put($cache_key, 1, Carbon::now()->addSeconds(3)); $box_no = $bikeRepository->byNoGetBoxNO($order->bike_no); // BikeControl::nowBikeLocation($box_no); (new BaseBikeControl($box_no))::nowBikeLocation(); $location = $locationLogRepository->byBikeNoGetLastLocation($order->bike_no, CacheMap::IS_OPEN_MONGODB_DUG); if ($location['lat'] <= 0) { $location['lat'] = $lat; $location['lng'] = $lng; } $area = $areaRepository->byIdGetModelRedis($order->area_id); $setting = $areaSettingRepository->byAreaId($order->area_id); //检查是否有运营区域 if (!$area) { return $this->errorNoValidation('暂无运营区域!'); } //检查是否在骑行区域 $is_out_area = $this->isOutArea($location['lat'], $location['lng'], $area); if (!$is_out_area) { return $this->errorNoValidation('超出骑行区域,暂不能锁车'); } $BikeHandler = new BikeHandler(); //检查是否在禁停区 $is_ban_stop_bike = $BikeHandler->byLocationCheckIsInBanStopParking($location['lat'], $location['lng'], $order->area_id, $lat, $lng); if ($is_ban_stop_bike) { // 在禁停区收取调度费 $is_huanche = $BikeHandler->byLocationCheckIsInStopParking($location['lat'], $location['lng'], $order->area_id, $lat, $lng); $dispatch_money = $BikeHandler->byDistanceGetDistanceMoney($is_huanche['distance'], $setting); $order->dispatch_money = $dispatch_money; // return $this->errorNoValidation('禁停区域内禁止停车!'); } return [ 'is_close_order' => false, ]; } catch (HttpException $exception) { return $this->errorNoValidation($exception->getMessage()); } } /** * 检查是否在还车点 * @param BikeCloseOrderRequest $request * @param OrderRepository $orderRepository * @param ParkingRepository $parkingRepository * @param AreaSettingRepository $areaSettingRepository * User: Mead */ public function checkBikeIsInStopParking(BikeCloseOrderRequest $request, BikeRepository $bikeRepository, OrderRepository $orderRepository, AreaSettingRepository $areaSettingRepository, LocationLogRepository $locationLogRepository, AreaRepository $areaRepository) { $bike_no = $request->get('bike_no'); $order_no = $request->get('order_no'); $lat = $request->get('lat'); $lng = $request->get('lng'); try { $order = $orderRepository->byNo($order_no); if (!$order) return $this->errorBadRequest('非法请求'); $user_id = $this->user['id']; $cache_key = "ORDER_CHECK_BIKE_IS_PARK_{$user_id}"; if (Cache::has($cache_key)) { return $this->errorNoValidation('您提交的太频繁了,请一会再提交!'); } Cache::put($cache_key, 1, Carbon::now()->addSeconds(3)); $box_no = $bikeRepository->byNoGetBoxNO($order->bike_no); // BikeControl::nowBikeLocation($box_no); (new BaseBikeControl($box_no))::nowBikeLocation(); $setting = $areaSettingRepository->byAreaId($order->area_id); $location = $locationLogRepository->byBikeNoGetLastLocation($order->bike_no, CacheMap::IS_OPEN_MONGODB_DUG); if ($location['lat'] <= 0) { $location['lat'] = $lat; $location['lng'] = $lng; } // // 判断是否在运动中 // if ($location['speed']) { // return $this->errorNoValidation('运动中不能关锁', 450); // } $area = $areaRepository->byIdGetModelRedis($order->area_id); //检查是否有运营区域 if (!$area) { return $this->errorNoValidation('暂无运营区域!'); } //检查是否在骑行区域 $is_out_area = $this->isOutArea($location['lat'], $location['lng'], $area); if (!$is_out_area) { return $this->errorNoValidation('超出骑行区域,暂不能锁车'); } $BikeHandler = new BikeHandler(); //检查是否在禁停区 $is_ban_stop_bike = $BikeHandler->byLocationCheckIsInBanStopParking($location['lat'], $location['lng'], $order->area_id, $lat, $lng); if ($is_ban_stop_bike) { // return $this->errorNoValidation('禁停区域内禁止停车!'); // // 在禁停区 收取调度费 $is_huanche = $BikeHandler->byLocationCheckIsInStopParking($location['lat'], $location['lng'], $order->area_id, $lat, $lng); $dispatch_money = $BikeHandler->byDistanceGetDistanceMoney($is_huanche['distance'], $setting); return [ 'is_dispatch' => false, 'is_stop_bike' => false, 'dispatch_money' => $dispatch_money, ]; } //判断是否全区域内可停 if ($areaSettingRepository->byAreaIdGetIsWholeAreaHuanche($order->area_id) === AreaSetting::WHOLE_AREA_HUANCHE_OK) { return [ 'is_dispatch' => true, 'is_stop_bike' => true, 'dispatch_money' => 0, ]; } // 判断是否在停车点 $is_huanche = $BikeHandler->byLocationCheckIsInStopParking($location['lat'], $location['lng'], $order->area_id, $lat, $lng); if (!$is_huanche['status']) { // BikeControl::nowBikeLocation($box_no); (new BaseBikeControl($box_no))::nowBikeLocation(); // 不在还车点 if ($setting->is_parking == AreaSetting::PARKING_OK) return $this->errorNoValidation('不在还车点,不能关锁'); $dispatch_money = $BikeHandler->byDistanceGetDistanceMoney($is_huanche['distance'], $setting); return [ 'is_dispatch' => false, 'is_stop_bike' => false, 'dispatch_money' => $dispatch_money, ]; } return [ 'is_dispatch' => true, 'is_stop_bike' => true, 'dispatch_money' => 0, ]; } catch (HttpException $exception) { return $this->errorNoValidation($exception->getMessage()); } } /** * 判断是否在骑行区 * @param $lat * @param $lng * @param $box_no * User: Mead */ private function isOutArea($lat, $lng, $area) { try { $location = [ 'latitude' => $lat, 'longitude' => $lng, ]; $fences = $area['area_fence']; $centre = $area['area_centre']; $radius = $area['area_radius']; $area_fushe_fence = $area['area_fushe_fence']; // 判断是否在骑行区域 $ConvertHandler = (new ConvertHandler()); $is_out_area = $ConvertHandler->is_point_in_polygon($location, $fences); return $is_out_area; } catch (\Exception $exception) { return $this->errorNoValidation($exception->getMessage()); } // // 判断是否骑出辐射范围 // $is_out_area_nearby = true; // if (!$is_out_area) { // $is_out_area_nearby = $ConvertHandler->is_point_in_polygon($location, $area_fushe_fence); // } // // return [ // 'is_out_area' => $is_out_area, // 'is_out_area_nearby' => $is_out_area_nearby // ]; } }