123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847 |
- <?php
- namespace App\Http\Controllers\Admin;
- use App\Handlers\Aes128Handler;
- use App\Handlers\BikeControl;
- use App\Handlers\BikeStatusInfoSyncHandler;
- use App\Http\Requests\RemarkRequest;
- use App\Http\Requests\BikeRequest;
- use App\Http\Resources\BikeResource;
- use App\Http\Resources\OrderRentResource;
- use App\Http\Resources\OrderResource;
- use App\Imports\BikesImport;
- use App\Models\AdminUser;
- use App\Models\AdminUserArea;
- use App\Models\Area;
- use App\Models\Bike;
- use App\Models\BoxBinding;
- use App\Models\LocationsLog;
- use App\Models\Order;
- use App\Models\OrderRent;
- use App\Utils\Admin;
- use App\Filters\BikeFilter;
- use App\Utils\GaodeMaps;
- use Carbon\Carbon;
- use Illuminate\Http\Request;
- use App\Http\Controllers\Controller;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- use Intervention\Image\Facades\Image;
- use Maatwebsite\Excel\Facades\Excel;
- use SimpleSoftwareIO\QrCode\Facades\QrCode;
- /**
- * Class BikeController
- * @package App\Http\Controllers\Admin
- */
- class BikeController extends Controller
- {
- /**
- * index
- *
- * @param Request $request
- * @param BikeFilter $filter
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function index(Request $request, BikeFilter $filter)
- {
- //
- $admin_id = Admin::user()->id;
- $bike = Bike::query()->filter($filter)->orderByDesc('id');
- if (!Admin::isAdministrator()) {
- $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
- $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->pluck('area_id')->toArray();
- if (count($area_ids) !== 0) {
- $area_idss = array_merge($area_ids, $area_id);
- $bike = $bike->where(function ($q) use ($area_idss) {
- $q->whereIn('put_area_id', $area_idss);
- });
- } else {
- $bike = $bike->where(function ($q) use ($area_id) {
- $q->whereIn('put_area_id', $area_id);
- });
- }
- }
- $bike = $request->get('all') ? $bike->get() : $bike->paginate();
- return $this->ok(BikeResource::collection($bike));
- }
- /**
- * maps 渲染地图车
- *
- * @param Request $request
- * @param BikeFilter $filter
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function maps(Request $request, BikeFilter $filter)
- {
- //
- $admin_id = Admin::user()->id;
- $bike = Bike::query()->filter($filter)->orderByDesc('id');
- if (!Admin::isAdministrator()) {
- $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
- if (count($area_ids) !== 0) {
- $bike = $bike->whereIn('put_area_id', $area_ids)->orWhere('put_area_id', 0);
- } else {
- $area = AdminUserArea::query()->where('admin_id', $admin_id)->first();
- $area_id = $area->area_id ?? 0;
- $bike = $bike->where('put_area_id', $area_id)->orWhere('put_area_id', 0);
- }
- }
- $bike = $bike->get();
- $data = [];
- foreach ($bike as $v) {
- // 此样式和前端海量点style数据相对应
- $style = 1;// 样式1 未使用 正常
- if ($v->is_low_battery_power == Bike::BATTERY_POWER_LOW) {
- $style = 0; // 样式0 低电量
- } elseif ($v->is_riding == Bike::RIDING_YES) {
- $style = 2; // 样式2 骑行中
- }
- if (app()->redis->hexists(BikeStatusInfoSyncHandler::REDIS_RIDE_BIKE_WORKER_ORDERS_TAG, $v->bike_no)) {
- $style = 3; // 样式3 运维骑行中
- };
- $data[] = [
- 'lnglat' => $v->last_location ? [json_decode($v->last_location)->lng, json_decode($v->last_location)->lat] : [116.397546, 39.909153],
- 'name' => $v->bike_no,
- 'id' => $v->id,
- 'style' => $style
- ];
- }
- return $this->ok($data);
- }
- /**
- * Show the form for creating a new resource.
- *
- * @return \Illuminate\Http\Response
- */
- public function create()
- {
- //
- }
- /**
- * store 添加车辆
- *
- * @param BikeRequest $request
- * @param Bike $bike
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function store(BikeRequest $request, Bike $bike)
- {
- //
- $inputs = $request->validated();
- $inputs['put_time'] = date('Y-m-d H:i:s', strtotime($inputs['put_time']));
- $box_no = $inputs['box_no'];
- $box = BoxBinding::query()->where('box_no', $box_no)->first();
- if (empty($box)) return $this->error('找不到此设备信息,请联系管理员');
- if ($box->is_binding == BoxBinding::BINDING_YES) return $this->error('此设备已经绑定过');
- // 蓝牙信息'TBIT_WA205-7HBLE';
- $blu_key = config('systemConfig.blu_key');
- try {
- $blu_ase_key = Aes128Handler::genKey($blu_key, $box_no);
- } catch (\Exception $e) {
- return $this->error($e->getMessage());
- }
- $inputs['blu_key'] = $blu_key;
- $inputs['blu_ase_key'] = $blu_ase_key;
- try {
- DB::beginTransaction();
- $bike->create($inputs);
- $box->is_binding = BoxBinding::BINDING_YES;
- $box->save();
- DB::commit();
- return $this->ok(BikeResource::make($bike));
- } catch (\Exception $e) {
- DB::rollBack();
- Log::error($e->getMessage());
- return $this->error('添加失败,请联系管理员');
- }
- }
- /**
- * Display the specified resource.
- *
- * @param int $id
- * @return \Illuminate\Http\Response
- */
- public function show($id)
- {
- //
- }
- /**
- * Show the form for editing the specified resource.
- *
- * @param int $id
- * @return \Illuminate\Http\Response
- */
- public function edit(Bike $bike)
- {
- return $this->ok(BikeResource::make($bike));
- //
- }
- /**
- * update 更新车辆
- *
- * @param BikeRequest $request
- * @param Bike $bike
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function update(BikeRequest $request, Bike $bike)
- {
- //
- $inputs = $request->validated();
- $inputs['put_time'] = date('Y-m-d H:i:s', strtotime($inputs['put_time']));
- // 更新redis
- if ((int)$inputs['put_status'] === 0) {
- (new BikeStatusInfoSyncHandler())->toBikeOffLineStatus($bike->bike_no);
- } elseif ((int)$inputs['put_status'] === 1) {
- $lastLocation = LocationsLog::getNewestLocationByBikeNo($bike->bike_no);
- (new BikeStatusInfoSyncHandler())->toBikeOnLineStatus($bike->bike_no, $lastLocation['lng'] ?? 0, $lastLocation['lat'] ?? 0);
- }
- if ($bike->box_no != $inputs['box_no']) {
- $box_no = $inputs['box_no'];
- $box = BoxBinding::query()->where('box_no', $box_no)->first();
- if (empty($box)) return $this->error('找不到此设备信息,请联系管理员');
- if ($box->is_binding == BoxBinding::BINDING_YES) return $this->error('此设备已经绑定过');
- // 蓝牙信息'TBIT_WA205-7HBLE';
- $blu_key = config('systemConfig.blu_key');
- try {
- $blu_ase_key = Aes128Handler::genKey($blu_key, $box_no);
- } catch (\Exception $e) {
- return $this->error($e->getMessage());
- }
- $inputs['blu_key'] = $blu_key;
- $inputs['blu_ase_key'] = $blu_ase_key;
- try {
- DB::beginTransaction();
- $bike->update($inputs);
- $box->is_binding = BoxBinding::BINDING_YES;
- $box->save();
- DB::commit();
- return $this->ok(BikeResource::make($bike));
- } catch (\Exception $e) {
- DB::rollBack();
- Log::error($e->getMessage());
- return $this->error('添加失败,请联系管理员');
- }
- }
- $bike->update($inputs);
- return $this->ok(BikeResource::make($bike));
- }
- public function updateRemark(RemarkRequest $request, $id)
- {
- //
- $bike = Bike::find($id);
- $inputs = $request->validated();
- // Log::info($id);
- $bike->update($inputs);
- return $this->ok(BikeResource::make($bike));
- }
- /**
- * Remove the specified resource from storage.
- *
- * @param int $id
- * @return \Illuminate\Http\Response
- */
- public function destroy(Bike $bike)
- {
- //
- $bike->delete();
- return $this->noContent();
- }
- /**
- * bikesUpdate 批量投放更新
- *
- * @param Request $request
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function bikesUpdate(Request $request)
- {
- $ids = $request->get('ids');
- $bike_nos = $request->get('bike_nos');
- $updated = $request->get('updated');
- //参数校验
- if (empty($ids)) return $this->error('请选择车辆');
- if (empty($updated['put_time'])) return $this->error('参数错误');
- if (empty($updated['put_area_id'])) return $this->error('参数错误');
- if ($updated['put_status'] != '0' && $updated['put_status'] != '1') return $this->error('参数错误');
- $updates['put_time'] = date('Y-m-d H:i:s', strtotime($updated['put_time']));
- $updates['put_area_id'] = $updated['put_area_id'];
- $updates['put_status'] = $updated['put_status'];
- $bool = Bike::query()->whereIn('id', $ids)->update($updates);
- // Log::info($bool);
- if ($bool) {
- // 更新redis
- if (!empty($bike_nos)) {
- if ($updated['put_status'] == 0) {
- foreach ($bike_nos as $v) {
- (new BikeStatusInfoSyncHandler())->toBikeOffLineStatus($v);
- }
- } elseif ($updated['put_status'] == 1) {
- foreach ($bike_nos as $v) {
- $lastLocation = LocationsLog::getNewestLocationByBikeNo($v);
- (new BikeStatusInfoSyncHandler())->toBikeOnLineStatus($v, $lastLocation['lng'] ?? 0, $lastLocation['lat'] ?? 0);
- }
- }
- }
- return $this->ok('操作成功');
- } else {
- return $this->error('操作失败');
- }
- }
- /**
- * import 导入excle
- *
- * @param Request $request
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function import(Request $request)
- {
- try {
- Excel::import(new BikesImport, $request->file('bikes'));
- return $this->ok('导入成功');
- } catch (\Exception $e) {
- Log::error($e->getMessage());
- return $this->error('导入失败');
- }
- }
- /**
- * download 下载模板
- *
- * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
- * @author Fx
- *
- */
- public function download()
- {
- return response()->download(public_path('example_bike.xlsx'));
- }
- /**
- * QrCode 返回单个车辆二维码
- *
- * @param Request $request
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function QrCode(Request $request)
- {
- $bike_no = $request->get('bike_no') ?? '';
- if (empty($bike_no)) return $this->error('参数错误');
- $filename = storage_path('app/public/qcode/') . $bike_no . 'appcode.png';
- if (!file_exists($filename)) {
- $filename = $this->wechatQrCode($bike_no);
- $path = config('app.url') . '/storage/qcode/' . $filename;
- return $this->ok($path);
- }
- $path = config('app.url') . '/storage/qcode/' . $bike_no . 'appcode.png';
- return $this->ok($path);
- }
- /**
- * qrCodesDownload 批量下载二维码
- *
- * @param Request $request
- * @return \Illuminate\Http\JsonResponse|\Symfony\Component\HttpFoundation\BinaryFileResponse
- * @author Fx
- *
- */
- public function qrCodesDownload(Request $request)
- {
- $bike_nos = $request->get('bike_nos') ?? '';
- if (empty($bike_nos)) return $this->error('参数错误');
- $files = [];
- foreach ($bike_nos as $v) {
- $file = storage_path('app/public/qcode/') . $v . 'appcode.png';
- if (!file_exists($file)) {
- $filename = $this->wechatQrCode($v);
- $files[$filename] = $file;
- } else {
- $filename = $v . 'appcode.png';
- $files[$filename] = $file;
- }
- }
- $zip_file = 'invoices.zip';
- $zip = new \ZipArchive();
- $zip->open($zip_file, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
- $path = storage_path('invoices');
- // 这里边全是真实全绝对路径 不需要跳过目录
- foreach ($files as $name => $file) {
- // 我们要跳过所有子目录
- // if (!$file->isDir()) {
- // $filePath = $file->getRealPath();
- //
- // // 用 substr/strlen 获取文件扩展名
- // $relativePath = 'invoices/' . substr($filePath, strlen($path) + 1);
- //
- // $zip->addFile($filePath, $relativePath);
- // }
- //$file 为真实文件路径 $name为文件名 如果不写$name生成的压缩文件 将会包含目录
- $zip->addFile($file, $name);
- }
- $zip->close();
- return response()->download($zip_file);
- }
- /**
- * analysisPosition 解析车辆位置
- *
- * @param Request $request
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function analysisPosition(Request $request)
- {
- $bike_id = $request->get('bike_id');
- $bike = Bike::find($bike_id);
- if (empty($bike)) return $this->ok(['position' => '']);
- $last_location = $bike->last_location;
- $lngLat = $last_location ? [json_decode($last_location)->lng, json_decode($last_location)->lat] : [116.397546, 39.909153];
- $position = GaodeMaps::getAddress($lngLat);
- //最近订单 取最
- $order = Order::query()->where('bike_id', $bike->id)->orderByDesc('id')->with('users')->first();
- $orderRent = OrderRent::query()->where('bike_id', $bike->id)->orderByDesc('id')->with('users')->first();
- $data2 = [];
- $data1 = [];
- if (!empty($order) && !empty($orderRent)) {
- if ($orderRent->start_use_bike_time > $order->start_use_bike_time) {
- // $user = User::query()->find($v->user_id);
- $data1['bike_no'] = $orderRent->bike_no;
- $data1['username'] = $orderRent->users->nickname ?? '';
- $data1['truename'] = $orderRent->users->truename ?? '';
- $data1['mobile'] = $orderRent->users->mobile ?? '';
- $data1['order_status'] = OrderRent::$statusMaps[$orderRent->status];
- $data1['start_use_bike_time'] = $orderRent->start_use_bike_time;
- $data1['end_use_bike_time'] = $orderRent->end_use_bike_time;
- $data1['start_use_bike_time_app'] = date('m-d H:i', strtotime($orderRent->start_use_bike_time));
- $data1['end_use_bike_time_app'] = $orderRent->end_use_bike_time ? date('m-d H:i', strtotime($orderRent->end_use_bike_time)) : '';
- } else {
- $data1['bike_no'] = $order->bike_no;
- $data1['username'] = $order->users->nickname ?? '';
- $data1['truename'] = $order->users->truename ?? '';
- $data1['mobile'] = $order->users->mobile ?? '';
- $data1['order_status'] = Order::$statusMaps[$order->status];
- $data1['start_use_bike_time'] = $order->start_use_bike_time;
- $data1['end_use_bike_time'] = $order->end_use_bike_time;
- $data1['start_use_bike_time_app'] = date('m-d H:i', strtotime($order->start_use_bike_time));
- $data1['end_use_bike_time_app'] = $order->end_use_bike_time ? date('m-d H:i', strtotime($order->end_use_bike_time)) : '';
- }
- $data2[] = $data1;
- } else if (!empty($order)) {
- $data1['bike_no'] = $order->bike_no;
- $data1['username'] = $order->users->nickname ?? '';
- $data1['truename'] = $order->users->truename ?? '';
- $data1['mobile'] = $order->users->mobile ?? '';
- $data1['order_status'] = Order::$statusMaps[$order->status];
- $data1['start_use_bike_time'] = $order->start_use_bike_time;
- $data1['end_use_bike_time'] = $order->end_use_bike_time;
- $data1['start_use_bike_time_app'] = date('m-d H:i', strtotime($order->start_use_bike_time));
- $data1['end_use_bike_time_app'] = $order->end_use_bike_time ? date('m-d H:i', strtotime($order->end_use_bike_time)) : '';
- $data2[] = $data1;
- } else if (!empty($orderRent)) {
- $data1['bike_no'] = $orderRent->bike_no;
- $data1['username'] = $orderRent->users->nickname ?? '';
- $data1['truename'] = $orderRent->users->truename ?? '';
- $data1['mobile'] = $orderRent->users->mobile ?? '';
- $data1['order_status'] = OrderRent::$statusMaps[$orderRent->status];
- $data1['start_use_bike_time'] = $orderRent->start_use_bike_time;
- $data1['end_use_bike_time'] = $orderRent->end_use_bike_time;
- $data1['start_use_bike_time_app'] = date('m-d H:i', strtotime($orderRent->start_use_bike_time));
- $data1['end_use_bike_time_app'] = $orderRent->end_use_bike_time ? date('m-d H:i', strtotime($orderRent->end_use_bike_time)) : '';
- $data2[] = $data1;
- }
- $workInfo = [];
- if (app()->redis->hexists(BikeStatusInfoSyncHandler::REDIS_RIDE_BIKE_WORKER_ORDERS_TAG, $bike->bike_no)) {
- $work_id = app()->redis->hget(BikeStatusInfoSyncHandler::REDIS_RIDE_BIKE_WORKER_ORDERS_TAG, $bike->bike_no);
- $work = AdminUser::find($work_id);
- $workInfo = [
- 'name' => $work->name,
- 'phone' => $work->phone,
- ];
- }
- return $this->ok(['position' => $position, 'bike' => BikeResource::make($bike), 'lately_order' => $data1, 'workInfo' => $workInfo]);
- }
- /**
- * wechatQrCode 本地插件生成二维码
- *
- * @param $bike_no
- * @return string
- * @author Fx
- *
- */
- private function wechatQrCode($bike_no)
- {
- $filename = $bike_no . 'appcode.png';
- QrCode::format('png')->size(600)->generate(config('wechat.code_url') . $bike_no, storage_path('app/public/qcode/') . $filename);
- $file = storage_path('app/public/qcode/') . $filename;
- // 修改指定图片的大小
- $img = Image::canvas(700, 700, '#fff');
- $img->insert($file, 'top-left', 50, 20);
- $fontPath = public_path('fonts/msyhbd.ttc');
- $img->text($bike_no, 350, 610, function ($font) use ($fontPath) {
- $font->file($fontPath);
- $font->size(60);
- $font->color('#000');
- $font->align('center');
- $font->valign('top');
- });
- // 将处理后的图片重新保存到其他路径
- $img->save($file);
- return $filename;
- }
- /**
- * statistics 简要统计信息
- *
- * @param BikeFilter $filter
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function statistics(BikeFilter $filter)
- {
- $riding_yes_num = Bike::query()->filter($filter)->where('is_riding', Bike::RIDING_YES); //使用中的数量
- $riding_no_num = Bike::query()->filter($filter)->where('is_riding', Bike::RIDING_NO); //未使用的数量
- $low_power_num = Bike::query()->filter($filter)->where('is_low_battery_power', Bike::BATTERY_POWER_LOW); //低电量的数量
- $admin_id = Admin::user()->id;
- if (!Admin::isAdministrator()) {
- $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
- if (count($area_ids) !== 0) {
- $riding_yes_num = $riding_yes_num->whereIn('put_area_id', $area_ids);
- $riding_no_num = $riding_no_num->whereIn('put_area_id', $area_ids);
- $low_power_num = $low_power_num->whereIn('put_area_id', $area_ids);
- } else {
- $area = AdminUserArea::query()->where('admin_id', $admin_id)->first();
- $area_id = $area->area_id ?? 0;
- $riding_yes_num = $riding_yes_num->where('put_area_id', $area_id);
- $riding_no_num = $riding_no_num->where('put_area_id', $area_id);
- $low_power_num = $low_power_num->where('put_area_id', $area_id);
- }
- }
- $riding_yes_num = $riding_yes_num->count('id');
- $riding_no_num = $riding_no_num->count('id');
- $low_power_num = $low_power_num->count('id');
- $worker_riding_num = app()->redis->hkeys(BikeStatusInfoSyncHandler::REDIS_RIDE_BIKE_WORKER_ORDERS_TAG);
- $data = [
- 'riding_yes_num' => $riding_yes_num,
- 'riding_no_num' => $riding_no_num,
- 'low_power_num' => $low_power_num,
- 'worker_riding_num' => Bike::query()->filter($filter)->whereIn('bike_no', $worker_riding_num)->count('id')
- ];
- return $this->ok($data);
- }
- /**
- * getTrajectory 车辆轨迹 普通订单
- *
- * @param Request $request
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function getTrajectory(Request $request)
- {
- $bike_no = $request->get('bike_no') ?? '';
- $time_between = $request->get('time_between') ?? [];
- if (empty($bike_no) || empty($time_between)) return $this->error('参数错误');
- $locationLog = LocationsLog::where('bike_no', $bike_no)
- ->where('created_at', '>=', Carbon::parse($time_between[0])->toDateTimeString())
- ->where('created_at', '<=', Carbon::parse($time_between[1])->toDateTimeString())
- ->where('is_rent', LocationsLog::RENT_NO)
- ->whereBetween('latitude', [3, 53])->whereBetween('longitude', [73, 136])->orderBy('created_at', 'asc')
- ->get(['longitude', 'latitude', 'created_at']);
- $order = Order::where('bike_no', $bike_no)
- ->where('created_at', '>=', Carbon::parse($time_between[0])->toDateTimeString())
- ->where('created_at', '<=', Carbon::parse($time_between[1])->toDateTimeString())
- ->get(['end_use_bike_location', 'start_use_bike_location', 'created_at']);
- $orders = Order::where('bike_no', $bike_no)
- ->where('created_at', '>=', Carbon::parse($time_between[0])->toDateTimeString())
- ->where('created_at', '<=', Carbon::parse($time_between[1])->toDateTimeString())
- ->get();
- $data = [];
- $dataTime = [];
- $marks = [];
- if (empty($locationLog)) return $this->ok($data);
- if (empty($order)) return $this->ok($data);
- foreach ($order as $v) {
- $marks[] = [json_decode($v->start_use_bike_location)->longitude, json_decode($v->start_use_bike_location)->latitude];
- $marks[] = [json_decode($v->end_use_bike_location)->longitude, json_decode($v->end_use_bike_location)->latitude];
- }
- foreach ($locationLog as $v) {
- $data[] = [$v->longitude, $v->latitude];
- $dataTime[] = date('Y-m-d H:i:s', strtotime($v->created_at));
- }
- if (empty($data)) return $this->ok($data);
- $res = [
- 'locations' => $data,
- 'locations_time' => $dataTime,
- 'marks' => $marks,
- 'start_location' => $data[0],
- 'end_location' => end($data),
- 'orders' => OrderResource::collection($orders)
- ];
- return $this->ok($res);
- }
- /**
- * getOrderRentTrajectory 车辆轨迹 日租订单
- *
- * @param Request $request
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function getOrderRentTrajectory(Request $request)
- {
- $bike_no = $request->get('bike_no') ?? '';
- $time_between = $request->get('time_between') ?? [];
- if (empty($bike_no) || empty($time_between)) return $this->error('参数错误');
- $locationLog = LocationsLog::where('bike_no', $bike_no)
- ->where('created_at', '>=', Carbon::parse($time_between[0])->toDateTimeString())
- ->where('created_at', '<=', Carbon::parse($time_between[1])->toDateTimeString())
- ->where('is_rent', LocationsLog::RENT_YES)
- ->whereBetween('latitude', [3, 53])->whereBetween('longitude', [73, 136])->orderBy('created_at', 'asc')
- ->get(['longitude', 'latitude', 'created_at']);
- $order = OrderRent::where('bike_no', $bike_no)
- ->where('status', '!=', OrderRent::STATUS_WAIT_PAY_RENT_MONEY)
- ->where('created_at', '>=', Carbon::parse($time_between[0])->toDateTimeString())
- ->where('created_at', '<=', Carbon::parse($time_between[1])->toDateTimeString())
- ->get(['end_use_bike_location', 'start_use_bike_location', 'created_at']);
- $orders = OrderRent::where('bike_no', $bike_no)
- ->where('status', '!=', OrderRent::STATUS_WAIT_PAY_RENT_MONEY)
- ->where('created_at', '>=', Carbon::parse($time_between[0])->toDateTimeString())
- ->where('created_at', '<=', Carbon::parse($time_between[1])->toDateTimeString())
- ->get();
- $data = [];
- $dataTime = [];
- $marks = [];
- if (empty($locationLog)) return $this->ok($data);
- if (empty($order)) return $this->ok($data);
- foreach ($order as $v) {
- $marks[] = [json_decode($v->start_use_bike_location)->longitude, json_decode($v->start_use_bike_location)->latitude];
- $marks[] = [json_decode($v->end_use_bike_location)->longitude, json_decode($v->end_use_bike_location)->latitude];
- }
- foreach ($locationLog as $v) {
- $data[] = [$v->longitude, $v->latitude];
- $dataTime[] = date('Y-m-d H:i:s', strtotime($v->created_at));
- }
- if (empty($data)) return $this->ok($data);
- $res = [
- 'locations' => $data,
- 'locations_time' => $dataTime,
- 'marks' => $marks,
- 'start_location' => $data[0],
- 'end_location' => end($data),
- 'orders' => OrderRentResource::collection($orders)
- ];
- return $this->ok($res);
- }
- /**
- * mulBikesContro 车辆批量操作
- *
- * @param Request $request
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function mulBikesContro(Request $request)
- {
- $admin_id = Admin::user()->id;
- $bikeIds = $request->get('bikeIds') ?? [];
- $type = $request->get('type') ?? '';
- if (empty($bikeIds) || empty($type)) return $this->error('参数错误');
- try {
- $bikes = Bike::query()->whereIn('id', $bikeIds)->get(['id', 'box_no', 'bike_no', 'last_location', 'put_status']);
- if (count($bikes) == 0) return $this->error('找不到车辆相关信息,请检查参数');
- switch ($type) {
- case 'bell': //寻铃
- foreach ($bikes as $v) {
- if (!empty($v->box_no)) {
- BikeControl::bellBike($v->box_no);
- }
- }
- break;
- case 'openLock': // 开锁
- foreach ($bikes as $v) {
- if (!empty($v->box_no)) {
- BikeControl::openLock($v->box_no);
- (new BikeStatusInfoSyncHandler())->toBikeRideStatus(BikeStatusInfoSyncHandler::ROLE_SERVER, $v->bike_no, ['id' => $admin_id, 'area_id' => $v->put_area_id, 'bike_id' => $v->id]);
- }
- }
- break;
- case 'closeLock': // 关电车锁
- foreach ($bikes as $v) {
- if (!empty($v->box_no)) {
- BikeControl::openLock($v->box_no);
- $location = json_decode($v->last_location);
- // 此处取mysql得位置信息
- (new BikeStatusInfoSyncHandler())->toBikeWaitRideStatus($v->bike_no, $location->lng, $location->lat, $v->put_status);
- }
- }
- break;
- case 'openBatteryLock': //开电池锁
- foreach ($bikes as $v) {
- if (!empty($v->box_no)) {
- BikeControl::openBatteryLock($v->box_no);
- }
- }
- break;
- case 'rebootBox': //重启中控
- foreach ($bikes as $v) {
- if (!empty($v->box_no)) {
- BikeControl::rebootBox($v->box_no);
- }
- }
- break;
- case 'nowBikeLocation': //立即定位
- foreach ($bikes as $v) {
- if (!empty($v->box_no)) {
- BikeControl::nowBikeLocation($v->box_no);
- }
- }
- break;
- case 'nowBikeBatteryMSG': //立即上传电池信息
- foreach ($bikes as $v) {
- if (!empty($v->box_no)) {
- BikeControl::nowBikeBatteryMSG($v->box_no);
- }
- }
- break;
- case 'outLoseElectric': //失能
- foreach ($bikes as $v) {
- if (!empty($v->box_no)) {
- BikeControl::outAreaLoseElectric($v->box_no);
- }
- }
- break;
- case 'outGetElectric': //获能
- foreach ($bikes as $v) {
- if (!empty($v->box_no)) {
- BikeControl::outAreaGetElectric($v->box_no);
- }
- }
- break;
- case 'repair': //恢复正常
- foreach ($bikes as $v) {
- if (!empty($v->id)) {
- $update = [
- 'is_low_battery_power' => Bike::BATTERY_POWER_OK, // 电量正常
- 'is_link' => Bike::LINK_OFFLINE, // 离线
- 'is_in_parking' => Bike::IN_PARKING_YES, // 在停车区
- 'is_trouble' => Bike::TROUBLE_NO, // 无故障
- 'battery_power' => 0, // 电量设为0
- ];
- Bike::where('id', $v->id)->update($update);
- }
- }
- break;
- default :
- return $this->error('参数错误');
- }
- return $this->ok('操作成功');
- } catch (\Exception $e) {
- Log::error($e->getMessage());
- return $this->error('出现错误,请联系管理员');
- }
- }
- /**
- * bikeStatusValueLabel 返回车辆状态码
- *
- * @return \Illuminate\Http\JsonResponse
- * @author Fx
- *
- */
- public function bikeStatusValueLabel()
- {
- $bikeStateMaps = Bike::$bikeStatesMaps;
- $bikeStates = [];
- foreach ($bikeStateMaps as $k => $v) {
- $bikeStates[] = ['id' => $k, 'name' => $v];
- }
- return $this->ok($bikeStates);
- }
- }
|