OrderController.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Mead
  5. * Date: 2019/8/19
  6. * Time: 2:11 PM
  7. */
  8. namespace App\Http\Controllers\V1;
  9. use App\Handlers\Activities\CouponActivityHandler;
  10. use App\Handlers\Activities\RidingCardActivityHandler;
  11. use App\Handlers\BikeControl;
  12. use App\Handlers\BikeHandler;
  13. use App\Handlers\BikeStatusInfoSyncHandler;
  14. use App\Http\Requests\BikeCloseOrderRequest;
  15. use App\Http\Requests\OrderBikePositionRequest;
  16. use App\Http\Requests\OrderPayRequest;
  17. use App\Http\Requests\OrderPayShowRequest;
  18. use App\Http\Requests\RelayOrderAutoCloseRequest;
  19. use App\Http\Requests\RetryBikeRequest;
  20. use App\Models\AreaSetting;
  21. use App\Models\Bike;
  22. use App\Models\CardRidingUserBags;
  23. use App\Models\CouponsUserBag;
  24. use App\Models\LocationLogMongodb;
  25. use App\Models\Order;
  26. use App\Models\OrderBikeOperate;
  27. use App\Models\WalletLog;
  28. use App\Repositories\AreaRepository;
  29. use App\Repositories\AreaSettingRepository;
  30. use App\Repositories\BikeRepository;
  31. use App\Repositories\CardRidingUserBagsRepository;
  32. use App\Repositories\LocationLogRepository;
  33. use App\Repositories\OrderBikeOperateRepository;
  34. use App\Repositories\OrderRepository;
  35. use App\Transformers\OrderPayTransformer;
  36. use App\Transformers\OrderTransformer;
  37. use Carbon\Carbon;
  38. use Dingo\Api\Http\Request;
  39. use EasyWeChat\Kernel\Exceptions\HttpException;
  40. use Illuminate\Support\Facades\Cache;
  41. use Illuminate\Support\Facades\DB;
  42. use function EasyWeChat\Kernel\Support\generate_sign;
  43. /**
  44. * 临时订单管理
  45. * Class OrderController
  46. * @package App\Http\Controllers\V1
  47. */
  48. class OrderController extends BaseController
  49. {
  50. /**
  51. * 订单列表
  52. * @param Request $request
  53. * @param Order $order
  54. * @return \Dingo\Api\Http\Response|void
  55. * User: Mead
  56. */
  57. public function index(Request $request, Order $order)
  58. {
  59. try {
  60. $query = $order->query();
  61. if ($year = $request->get('year', date('Y'))) {
  62. $query->whereYear('created_at', $year);
  63. }
  64. if ($month = $request->get('month', date('m'))) {
  65. $query->whereMonth('created_at', $month);
  66. }
  67. $orders = $query->where('user_id', $this->user->id)->orderBy('id', 'desc')->paginate();
  68. $orders->appends($request->only(['year', 'month']))->withPath(config('app.url') . '/api/orders');
  69. return $this->response->paginator($orders, OrderTransformer::class);
  70. } catch (\Exception $exception) {
  71. return $this->errorException($exception->getMessage());
  72. }
  73. }
  74. /**
  75. * 支付页面
  76. * @param OrderPayShowRequest $request
  77. * @param OrderRepository $orderRepository
  78. * @return mixed
  79. * User: Mead
  80. */
  81. public function payShow(OrderPayShowRequest $request, OrderRepository $orderRepository, LocationLogRepository $locationLogRepository, AreaSettingRepository $areaSettingRepository, CouponActivityHandler $couponActivityHandler, CardRidingUserBagsRepository $cardRidingUserBagsRepository, RidingCardActivityHandler $ridingCardActivityHandler, OrderBikeOperateRepository $orderBikeOperateRepository)
  82. {
  83. try {
  84. $order_no = $request->get('order_no');
  85. $is_first = $request->get('is_first') ?? false;
  86. $couponUserBagsId = $request->get('coupon_user_bags_id') ?? '';
  87. $order = $orderRepository->byNoAndUserId($order_no, $this->user->id);
  88. // 骑行卡优惠
  89. $ridingCardActivityHandler->main($order);
  90. // 判断车是否在停车的区域
  91. if ($areaSettingRepository->byAreaIdGetIsWholeAreaHuanche($order->area_id) === AreaSetting::WHOLE_AREA_HUANCHE_NO) {
  92. //检查车是否在停车位置
  93. if (((int)$order->is_admin_settle_order === Order::IS_ADMIN_SETTLE_ORDER_USER) && ($order->dispatch_money > 0) && (int)$order->status === Order::STATUS_CLOSE_BIKE) {
  94. $location = [];
  95. $is_in_time = (Carbon::now()->diffInSeconds(Carbon::parse($order->end_use_bike_time)) < 15);
  96. if ($is_in_time) {
  97. $location = $locationLogRepository->byBikeNoGetLastLocation($order->bike_no);
  98. } else {
  99. $location = $locationLogRepository->byOrderIdGetLastLocation($order->id);
  100. }
  101. // 判断是否在停车点
  102. if (!is_null($location['lat']) && ($location['lat'] > 0)) {
  103. $BikeHandler = new BikeHandler();
  104. $is_huanche = $BikeHandler->byLocationCheckIsInStopParking($location['lat'], $location['lng'], $order->area_id);
  105. if (!$is_huanche['status']) {
  106. // 不在还车点
  107. $setting = $areaSettingRepository->byAreaId($order->area_id);
  108. $dispatch_money = $BikeHandler->byDistanceGetDistanceMoney($is_huanche['distance'], $setting);
  109. $order->dispatch_money = $dispatch_money;
  110. } else {
  111. $order->dispatch_money = 0;
  112. }
  113. $order->order_money = bcadd($order->time_money, $order->dispatch_money, 2);
  114. //计算优惠金额
  115. $order->order_money = bcsub($order->order_money, $order->preferential_money, 2);
  116. $order->pay_money = $order->order_money;
  117. }
  118. $is_in_parking = Bike::IN_PARKING_YES;
  119. if ($order->dispatch_money > 0) {
  120. $is_in_parking = Bike::IN_PARKING_NO;
  121. }
  122. if ($is_in_time) {
  123. Bike::where('id', $order->bike_id)->update([
  124. 'is_in_parking' => $is_in_parking
  125. ]);
  126. }
  127. }
  128. }
  129. if (bccomp($order->order_money, 0) === 0) {
  130. $order->status = Order::STATUS_COMPLETE_ORDER;
  131. if ($order->use_bike_time_length === 0) {
  132. $order->status = Order::STATUS_CLOSE_ORDER;
  133. }
  134. }
  135. $order->save();
  136. if ($is_first) {
  137. // 首次
  138. $data = $couponActivityHandler->isCouponsByOrder($order);
  139. if (empty($data['dataYes'])) {
  140. $userCoupons = [];
  141. } else {
  142. // 取最大优惠
  143. $userCoupons = $data['dataYes'][0];
  144. }
  145. } else {
  146. $userCoupons = $couponActivityHandler->getCouponsByOrderAndId($order, $couponUserBagsId);
  147. }
  148. $ridingCard = $cardRidingUserBagsRepository->isExist($this->user->id);
  149. // 能否选择优惠券
  150. $couponData = $couponActivityHandler->isCouponsByOrder($order);
  151. if (count($couponData['dataYes']) + count($couponData['dataNo']) > 0) {
  152. $is_coupon = true;
  153. } else {
  154. $is_coupon = false;
  155. }
  156. // 检查用户余额是否够
  157. $is_user_wallet = true;
  158. if (empty($userCoupons)) {
  159. if ($order->pay_money > $this->user->wallet_money) {
  160. // 余额不够
  161. $is_user_wallet = false;
  162. }
  163. } elseif ($userCoupons['order_wait_pay_money'] > $this->user->wallet_money) {
  164. // 余额不够
  165. $is_user_wallet = false;
  166. }
  167. // 检查是否系统自动锁车
  168. $is_system_off_lock = $orderBikeOperateRepository->checkLowPowerOffLock($order->id);
  169. return $this->response->array([
  170. 'order' => $order->append(['use_bike_time_length_text', 'pause_bike_time_length_text', 'use_bike_distance_length_text', 'end_use_bike_time_timestamp', 'preferential_type_name'])->toArray(),
  171. 'orders' => [
  172. 'id' => $order->id,
  173. 'no' => $order->no,
  174. 'bike_no' => $order->bike_no,
  175. 'use_bike_time_length_text' => $order->use_bike_time_length_text,
  176. 'use_bike_distance_length_text' => $order->use_bike_distance_length_text,
  177. 'end_use_bike_time_timestamp' => $order->end_use_bike_time_timestamp,
  178. 'pay_status' => $order->pay_status,
  179. 'pay_money' => $order->pay_money,
  180. 'time_money' => $order->time_money, // 时长费
  181. 'dispatch_money' => $order->dispatch_money, // 调度费
  182. 'distance_money' => $order->distance_money, // 里程费用
  183. 'order_money' => bcadd(bcadd($order->time_money, $order->distance_money, 2), $order->dispatch_money, 2),// 加调度费的总金额
  184. 'order_total_money' => bcadd($order->time_money, $order->distance_money, 2), // 不加调度费的总金额
  185. 'order_wait_pay_money' => empty($userCoupons) ? $order->order_money : $userCoupons['order_wait_pay_money'], // 总待支付
  186. 'total_preferential_money' => empty($userCoupons) ? $order->preferential_money : $userCoupons['total_preferential_money'], // 总优惠
  187. ],
  188. 'wallet_pay_status' => $is_user_wallet,
  189. 'wallet_money' => $this->user->wallet_money,
  190. 'user_coupon' => [
  191. 'is_coupon' => $is_coupon,
  192. 'coupon_preferential_money' => empty($userCoupons) ? '0.00' : $userCoupons['coupon_preferential_money'], // 优惠券优惠的金额
  193. 'coupon_user_bags_id' => empty($userCoupons) ? 0 : $userCoupons['id'],
  194. ],
  195. 'user_card' => [
  196. 'is_card' => empty($ridingCard) ? false : true,
  197. 'card' => $ridingCard,
  198. 'card_preferential_money' => $order->preferential_money, // 没支付之前优惠金额就是 骑行卡优惠的金额
  199. ],
  200. 'system_off_lock' => [
  201. 'is_system_off_lock' => empty($is_system_off_lock) ? false : true,
  202. 'system_off_lock_text' => empty($is_system_off_lock) ? '' : $is_system_off_lock->name . ',敬请谅解,如有疑问请致电客服'
  203. ],
  204. ]);
  205. } catch (\Exception $exception) {
  206. return $this->errorException($exception->getMessage() . $exception->getLine());
  207. }
  208. }
  209. /**
  210. * 订单详情页
  211. * @param OrderPayShowRequest $request
  212. * @param OrderRepository $orderRepository
  213. * @return \Dingo\Api\Http\Response
  214. * User: Mead
  215. */
  216. public function show(OrderPayShowRequest $request, OrderRepository $orderRepository)
  217. {
  218. try {
  219. $order_no = $request->get('order_no');
  220. $order = $orderRepository->byNoAndUserId($order_no, $this->user->id);
  221. if (!$order) return $this->errorNoValidation('找不到该订单');
  222. return $this->response->item($order, new OrderPayTransformer());
  223. } catch (\Exception $exception) {
  224. return $this->errorException($exception->getMessage());
  225. }
  226. }
  227. /**
  228. * 订单支付
  229. * @param OrderPayRequest $request
  230. * @param OrderRepository $orderRepository
  231. * User: Mead
  232. */
  233. public function pay(OrderPayRequest $request, OrderRepository $orderRepository, CouponActivityHandler $couponActivityHandler, RidingCardActivityHandler $ridingCardActivityHandler)
  234. {
  235. try {
  236. $pay_type = $request->get('pay_type');
  237. $order_no = $request->get('order_no');
  238. $couponUserBagsId = $request->get('coupon_user_bags_id') ?? '';
  239. $order = $orderRepository->byNo($order_no);
  240. if (!$order) return $this->errorBadRequest('订单不存在');
  241. if ((int)$order->pay_status === Order::PAY_STATUS_OK) return $this->errorNoValidation('订单已支付');
  242. if (in_array($order->status, [Order::STATUS_PAUSE_BIKE, Order::STATUS_RIDE_BIKE])) return $this->errorNoValidation('订单状态可能出在骑行中,请先锁车');
  243. $user = $this->user;
  244. if ($order->user_id !== $user->id) return $this->errorNoValidation('非法操作');
  245. $user_id = $user['id'];
  246. $cache_key = "PAY_ORDER_{$user_id}";
  247. if (Cache::has($cache_key)) {
  248. return $this->errorNoValidation('您提交的太频繁了,请一会再提交!');
  249. }
  250. Cache::put($cache_key, 1, Carbon::now()->addSeconds(5));
  251. // 骑行卡优惠
  252. $ridingCardActivityHandler->main($order);
  253. // 优惠券优惠
  254. $couponActivityHandler->main($order, $couponUserBagsId);
  255. $order->save();
  256. $response = '';
  257. switch ($pay_type) {
  258. case Order::PAY_TYPE_ACCOUNT:
  259. //余额支付
  260. if ($order->order_money > $this->user->wallet_money) {
  261. // 余额不够
  262. return $this->errorNoValidation('用户余额不够');
  263. }
  264. DB::transaction(function () use ($order, $user, $couponUserBagsId) {
  265. //添加钱包记录
  266. WalletLog::log(WalletLog::OPERATE_TYPE_SUB, $order->order_money, $user->id, WalletLog::TYPE_SUB_WALLET_BIKE_ORDER, $order->area_id, $order->id, Order::class);
  267. //修改订单记录
  268. $order->pay_status = Order::PAY_STATUS_OK;
  269. $order->pay_time = now();
  270. $order->pay_type = Order::PAY_TYPE_ACCOUNT;
  271. $order->pay_money = $order->order_money;
  272. $order->status = Order::STATUS_COMPLETE_ORDER;
  273. if ($order->is_coupon == Order::COUPON_OK) {
  274. CouponsUserBag::useCoupon($order->id, $couponUserBagsId);
  275. // 更新订单得优惠金额
  276. $order->coupon_user_bags_id = $couponUserBagsId;
  277. $order->preferential_money = bcsub(bcadd($order->time_money, $order->dispatch_money, 2), $order->pay_money, 2);
  278. // 更新优惠券优惠金额
  279. $order->coupon_preferential_money = bcsub($order->preferential_money, $order->card_preferential_money, 2);
  280. }
  281. $order->save();
  282. });
  283. $response = [
  284. 'pay_order_status' => true
  285. ];
  286. break;
  287. case Order::PAY_TYPE_WECHAT:
  288. //微信支付
  289. $payment = app('wechat.payment'); // 微信支付
  290. $username = $user->truename;
  291. $auth = $user->auth;
  292. $result = $payment->order->unify([
  293. 'body' => "[{$username}]支付订单",
  294. 'out_trade_no' => $order->no,
  295. 'trade_type' => 'JSAPI', // 必须为JSAPI
  296. 'openid' => $auth['credential'], // 这里的openid为付款人的openid
  297. 'total_fee' => wechat_fee($order->order_money), // 总价
  298. 'attach' => Order::NO_TAG
  299. ]);
  300. if ($result['return_code'] === 'FAIL') return $this->errorNoValidation('下单失败');
  301. // 如果成功生成统一下单的订单,那么进行二次签名
  302. if ($result['result_code'] === 'FAIL') {
  303. //判断是否重复下单
  304. if ($result['err_code'] === 'INVALID_REQUEST') {
  305. $order->no = Order::makeNo();
  306. $order->save();
  307. $result = $payment->order->unify([
  308. 'body' => "[{$username}]支付订单",
  309. 'out_trade_no' => $order->no,
  310. 'trade_type' => 'JSAPI', // 必须为JSAPI
  311. 'openid' => $auth['credential'], // 这里的openid为付款人的openid
  312. 'total_fee' => wechat_fee($order->order_money), // 总价
  313. 'attach' => Order::NO_TAG
  314. ]);
  315. } else {
  316. return $this->errorNoValidation('下单失败');
  317. }
  318. }
  319. // 二次签名的参数必须与下面相同
  320. $params = [
  321. 'appId' => $auth['identifier'],
  322. 'timeStamp' => time(),
  323. 'nonceStr' => $result['nonce_str'],
  324. 'package' => 'prepay_id=' . $result['prepay_id'],
  325. 'signType' => 'MD5',
  326. ];
  327. // config('wechat.payment.default.key')为商户的key
  328. $params['paySign'] = generate_sign($params, config('wechat.payment.default.key'));
  329. $response = $params;
  330. $response['order_no'] = $order->no;
  331. break;
  332. default:
  333. return $this->errorBadRequest('支付类型不对');
  334. break;
  335. }
  336. return $this->response->array($response);
  337. } catch (\Exception $exception) {
  338. return $this->errorException($exception->getMessage());
  339. }
  340. }
  341. /**
  342. * 重试开车
  343. * @param Request $request
  344. * @param OrderRepository $orderRepository
  345. * @param BikeRepository $bikeRepository
  346. * User: Mead
  347. */
  348. public function retryOpenLock(RetryBikeRequest $request, OrderRepository $orderRepository, BikeRepository $bikeRepository)
  349. {
  350. try {
  351. $order_no = $request->get('order_no');
  352. $bike_no = $request->get('bike_no');
  353. $order = $orderRepository->checkUserIsRetryOpenLock($order_no, $bike_no, $this->user->id);
  354. if (!$order) return $this->errorNoValidation('没有此订单');
  355. $second = Carbon::now()->diffInSeconds(Carbon::parse($order->start_use_bike_time));
  356. if ($second > 60) {
  357. return $this->errorNoValidation('暂不能操作开车');
  358. }
  359. $box_no = $bikeRepository->byIdGetBoxNo($order->bike_id);
  360. if (!$box_no) return $this->errorNoValidation('找不到该车');
  361. BikeControl::openLock($box_no);
  362. return $this->response->array([
  363. 'status' => 1
  364. ]);
  365. } catch (\Exception $exception) {
  366. return $this->errorNoValidation($exception->getMessage());
  367. }
  368. }
  369. /**
  370. * 重试锁车
  371. * @param Request $request
  372. * @param OrderRepository $orderRepository
  373. * @param BikeRepository $bikeRepository
  374. * User: Mead
  375. */
  376. public function retryCloseLock(RetryBikeRequest $request, OrderRepository $orderRepository, BikeRepository $bikeRepository)
  377. {
  378. try {
  379. $order_no = $request->get('order_no');
  380. $bike_no = $request->get('bike_no');
  381. $order = $orderRepository->checkUserIsRetryOpenLock($order_no, $bike_no, $this->user->id);
  382. if (!$order) return $this->errorNoValidation('没有此订单');
  383. $second = Carbon::now()->diffInSeconds(Carbon::parse($order->end_use_bike_time));
  384. if ($second > 60) {
  385. return $this->errorNoValidation('暂不能操作关车');
  386. }
  387. $box_no = $bikeRepository->byIdGetNoRidingBoxNo($order->bike_id);
  388. if (!$box_no) return $this->errorNoValidation('找不到该车,或咱不能操作该车');
  389. BikeControl::closeLock($box_no);
  390. return $this->response->array([
  391. 'status' => 1
  392. ]);
  393. } catch (\Exception $exception) {
  394. return $this->errorNoValidation($exception->getMessage());
  395. }
  396. }
  397. /**
  398. * 临时停车时寻铃
  399. * @param Request $request
  400. * @param OrderRepository $orderRepository
  401. * @param BikeRepository $bikeRepository
  402. * User: Mead
  403. */
  404. public function retryBellLock(RetryBikeRequest $request, OrderRepository $orderRepository, BikeRepository $bikeRepository)
  405. {
  406. try {
  407. $order_no = $request->get('order_no');
  408. $bike_no = $request->get('bike_no');
  409. $order = $orderRepository->checkUserIsRetryOpenLock($order_no, $bike_no, $this->user->id);
  410. if (!$order) return $this->errorNoValidation('没有此订单');
  411. $box_no = $bikeRepository->byNoGetBoxNO($bike_no);
  412. $re = BikeControl::bellBike($box_no);
  413. return $this->response->array([
  414. 'is_ok' => $re
  415. ]);
  416. } catch (\Exception $exception) {
  417. return $this->errorNoValidation($exception->getMessage());
  418. }
  419. }
  420. /**
  421. * 系统自动关闭订单(replay端接口)
  422. * User: Mead
  423. */
  424. public function autoCloseOrder(RelayOrderAutoCloseRequest $request, OrderRepository $orderRepository, BikeRepository $bikeRepository, LocationLogRepository $locationLogRepository, AreaSettingRepository $areaSettingRepository)
  425. {
  426. try {
  427. $bike_no = $request->get('bike_no');
  428. $box_no = $request->get('box_no');
  429. $type = $request->get('type');
  430. $key = $request->get('key');
  431. if ($key !== config('auth.api_token')) {
  432. return $this->error('key不对');
  433. }
  434. $is_bike = $bikeRepository->byBoxNoAndBikeNoCheckRide($box_no, $bike_no);
  435. if (!$is_bike) {
  436. return $this->error('找不到该车');
  437. }
  438. $order = $orderRepository->byBikeNoGetRideOrder($bike_no);
  439. if (!$order) {
  440. return $this->error('找不到合适的订单');
  441. }
  442. //获取车的最后位置
  443. $location = $locationLogRepository->byBikeNoGetLastLocation($order->bike_no);
  444. // 更新车的信息
  445. $bikeModel = $bikeRepository->byIdGetModel($order->bike_id);
  446. $bikeModel->is_riding = Bike::RIDING_NO;
  447. $bikeModel->last_use_bike_end_time = date('Y-m-d H:i:s');
  448. $bikeModel->save();
  449. (new BikeStatusInfoSyncHandler())->toBikeWaitRideStatus($bike_no, $location['lng'], $location['lat']);
  450. // 判断是否经常这样操作(未做)
  451. BikeControl::closeLock($box_no);
  452. // 记录日志信息
  453. OrderBikeOperate::log($order->id, OrderBikeOperate::TYPE_CLONE_BIKE, $order->bike_id, $order->user_id, $location['lat'], $location['lng'], OrderBikeOperate::IS_ADMIN_SYSTEM, "[系统自动:{$type}]");
  454. // 保存轨迹信息
  455. $setting = $areaSettingRepository->byAreaId($order->area_id);
  456. // 是否处于临时停车的状态
  457. if ((int)$order->status === Order::STATUS_PAUSE_BIKE) {
  458. $order->pause_bike_time_length += Carbon::now()->diffInMinutes(Carbon::parse($order->pause_bike_time));
  459. }
  460. $order->status = Order::STATUS_CLOSE_BIKE;
  461. $order->end_use_bike_time = now();
  462. $order->end_use_bike_location = [
  463. 'latitude' => $location['lat'],
  464. 'longitude' => $location['lng'],
  465. ];
  466. $second = Carbon::now()->diffInSeconds(Carbon::parse($order->start_use_bike_time));
  467. //计算用车时间
  468. $order->use_bike_time_length = ceil($second / 60);
  469. // 计算价格
  470. $time_money = $setting->per_money * ceil($order->use_bike_time_length / $setting->per_minute);
  471. if ($time_money < 0) {
  472. $time_money = 0;
  473. }
  474. //计算骑行距离
  475. $order->use_bike_distance_length = bcdiv($location['mileage'], 1000, 2);
  476. // 判断车是否在停车的区域
  477. $order->dispatch_money = 0;
  478. if ($areaSettingRepository->byAreaIdGetIsWholeAreaHuanche($order->area_id) === AreaSetting::WHOLE_AREA_HUANCHE_NO) {
  479. $BikeHandler = new BikeHandler();
  480. $is_huanche = $BikeHandler->byLocationCheckIsInStopParking($location['lat'], $location['lng'], $order->area_id);
  481. $bikeModel->is_in_parking = Bike::IN_PARKING_YES;
  482. if (!$is_huanche['status']) {
  483. // 不在还车点
  484. $dispatch_money = $BikeHandler->byDistanceGetDistanceMoney($is_huanche['distance'], $setting);
  485. $order->dispatch_money = $dispatch_money;
  486. $bikeModel->is_in_parking = Bike::IN_PARKING_NO;
  487. }
  488. } else {
  489. //全区域内可停
  490. $bikeModel->is_in_parking = Bike::IN_PARKING_YES;
  491. }
  492. $order->time_money = $time_money;
  493. $order->pause_money = 0;
  494. $order->preferential_money = 0;
  495. $order->order_money = bcadd($time_money, $order->dispatch_money, 2);
  496. $order->pay_money = $order->order_money;
  497. $order->pay_type = Order::PAY_STATUS_NO;
  498. $order->is_admin_settle_order = Order::IS_ADMIN_SETTLE_ORDER_SYSTEM;
  499. $order->save();
  500. $bikeModel->save();
  501. BikeControl::closeLock($box_no);
  502. return $this->success();
  503. } catch (HttpException $exception) {
  504. return $this->error($exception->getMessage());
  505. }
  506. }
  507. /**
  508. * 骑行订单车辆位置 orderBikePosition
  509. *
  510. * @param OrderBikePositionRequest $request
  511. * @return void
  512. * @author Fx
  513. *
  514. */
  515. public function orderBikePosition(OrderBikePositionRequest $request)
  516. {
  517. try {
  518. $bike_no = $request->get('bike_no');
  519. $position = LocationLogMongodb::getNewestLocationByBikeNo($bike_no);
  520. // Log::info($position);
  521. return $this->response->array($position);
  522. } catch (\Exception $exception) {
  523. return $this->errorException($exception->getMessage());
  524. }
  525. }
  526. /**
  527. *
  528. * Author: Mead
  529. */
  530. public function expectOrderMoney(BikeCloseOrderRequest $request, BikeRepository $bikeRepository, OrderRepository $orderRepository, AreaSettingRepository $areaSettingRepository, LocationLogRepository $locationLogRepository)
  531. {
  532. $bike_no = $request->get('bike_no');
  533. $order_no = $request->get('order_no');
  534. $lat = $request->get('lat');
  535. $lng = $request->get('lng');
  536. try {
  537. $order = $orderRepository->byNo($order_no);
  538. if (!$order) return $this->errorBadRequest('非法请求');
  539. $second = Carbon::now()->diffInSeconds(Carbon::parse($order->start_use_bike_time));
  540. if ($second < AreaSetting::CLOSE_BIKE_TIME) {
  541. //小于60秒直接锁车
  542. return [
  543. 'dispatch_money' => 0,
  544. 'time_money' => 0,
  545. 'total_money' => 0
  546. ];
  547. }
  548. $user_id = $this->user['id'];
  549. $cache_key = "EXPECT_ORDER_MONEY_{$user_id}";
  550. if (Cache::has($cache_key)) {
  551. return $this->errorNoValidation('您提交的太频繁了,请一会再提交!');
  552. }
  553. Cache::put($cache_key, 1, Carbon::now()->addSeconds(3));
  554. $box_no = $bikeRepository->byNoGetBoxNO($order->bike_no);
  555. BikeControl::nowBikeLocation($box_no);
  556. $setting = $areaSettingRepository->byAreaId($order->area_id);
  557. $location = $locationLogRepository->byBikeNoGetLastLocation($order->bike_no);
  558. if ($location['lat'] <= 0) {
  559. $location['lat'] = $lat;
  560. $location['lng'] = $lng;
  561. }
  562. //计算用车时间
  563. $use_bike_time_length = ceil($second / 60);
  564. // 计算价格
  565. $time_money = floatval($setting->per_money * ceil($use_bike_time_length / $setting->per_minute));
  566. if ($time_money < 0) {
  567. $time_money = 0;
  568. }
  569. //计算骑行距离
  570. // $use_bike_distance_length = bcdiv($location['mileage'], 1000, 2);
  571. // $distance_money = 0;
  572. $BikeHandler = new BikeHandler();
  573. //判断是否全区域内可停
  574. if ($areaSettingRepository->byAreaIdGetIsWholeAreaHuanche($order->area_id) === AreaSetting::WHOLE_AREA_HUANCHE_OK) {
  575. return [
  576. 'dispatch_money' => 0,
  577. 'time_money' => $time_money,
  578. 'total_money' => $time_money
  579. ];
  580. }
  581. // 判断是否在停车点
  582. $is_huanche = $BikeHandler->byLocationCheckIsInStopParking($location['lat'], $location['lng'], $order->area_id);
  583. if (!$is_huanche['status']) {
  584. BikeControl::nowBikeLocation($box_no);
  585. // 不在还车点
  586. $dispatch_money = $BikeHandler->byDistanceGetDistanceMoney($is_huanche['distance'], $setting);
  587. return [
  588. 'dispatch_money' => $dispatch_money,
  589. 'time_money' => $time_money,
  590. 'total_money' => floatval(bcadd($dispatch_money, $time_money, 2))
  591. ];
  592. }
  593. return [
  594. 'dispatch_money' => 0,
  595. 'time_money' => $time_money,
  596. 'total_money' => $time_money
  597. ];
  598. } catch (HttpException $exception) {
  599. return $this->errorNoValidation($exception->getMessage());
  600. }
  601. }
  602. }