diff --git a/app/Http/Controllers/Admin/ParkingElectronicMapController.php b/app/Http/Controllers/Admin/ParkingElectronicMapController.php new file mode 100644 index 0000000..a4c5ea8 --- /dev/null +++ b/app/Http/Controllers/Admin/ParkingElectronicMapController.php @@ -0,0 +1,132 @@ +service = $service; + } + + /** + * 查询楼层 + * @return JsonResponse + */ + public function floorList(): JsonResponse + { + try { + $data = [ + 'floor_list' => AdminFloorService::getSelectList() + ]; + return $this->responseService->success($data); + } catch (Exception $e) { + $m_prefix = __('exception.exception_handler.resource'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + } + + /** + * 查询车位号码 + * @param $id + * @return JsonResponse + */ + public function getParkingSpaceList($id): JsonResponse + { + try { + $this->saveValidator(['floor_id' => $id]); + $list = ParkingSpaceService::getSelectList($id); + $data = [ + 'parking_space_list' => $list + ]; + return $this->responseService->success($data); + } catch (Exception $e) { + $m_prefix = __('exception.exception_handler.resource'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + } + + /** + * @param array $data + * @param int $is_save + * @return void + * @throws ValidationException + */ + protected function saveValidator(array $data, int $is_save = 0): void + { + $rules = [ + 'floor_id' => 'required|numeric', + ]; + $messages = [ + 'floor_id.required' => __('validation.map.f_empty'), + 'floor_id.numeric' => __('validation.map.f_number') + ]; + if ($is_save) { + $rules['parking_space_id'] = 'required|numeric'; + $messages['parking_space_id.required'] = __('validation.map.p_empty'); + $messages['parking_space_id.numeric'] = __('validation.map.p_number'); + } + $validator = Validator::make($data, $rules, $messages); + + if ($validator->fails()) { + throw new ValidationException($validator); + } + } + + public function save(Request $request): JsonResponse + { + try { + $data = $request->all(); + $this->saveValidator($data, 1); + $this->service->saveModel($data); + return $this->responseService->success([], __('admin.save_succeeded')); + } catch (Exception $e) { + $m_prefix = __('admin.save_failed'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + + } + + public function index(Request $request): JsonResponse + { + try { + $data = $request->all(); + $this->saveValidator($data); + $list = $this->service->getList($data); + return $this->responseService->success($list); + } catch (Exception $e) { + $m_prefix = __('exception.exception_handler.resource'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + } +} diff --git a/app/Models/ParkingElectronicMap.php b/app/Models/ParkingElectronicMap.php new file mode 100644 index 0000000..e156eb0 --- /dev/null +++ b/app/Models/ParkingElectronicMap.php @@ -0,0 +1,27 @@ +whereNull('deleted_at')->select($column) + ->get()->toArray(); + foreach ($list as &$item) { + $item['pic_url'] = env('app_url') . $item['pic_url']; + } + return $list; + } } diff --git a/app/Services/ParkingElectronicMapService.php b/app/Services/ParkingElectronicMapService.php new file mode 100644 index 0000000..7bb58c2 --- /dev/null +++ b/app/Services/ParkingElectronicMapService.php @@ -0,0 +1,72 @@ + $floor_id, + 'space_id' => $space_id + ]; + $res = ParkingElectronicMap::query()->where($where)->get()->toArray(); + $saveData['width'] = $data['width'] ?? '0'; + $saveData['height'] = $data['height'] ?? '0'; + $saveData['coordinate_x'] = $data['coordinate_x'] ?? ''; + $saveData['coordinate_y'] = $data['coordinate_y'] ?? ''; + if ($res) { + $saveData['update_at'] = get_datetime(); + $model = ParkingElectronicMap::query()->findOrFail($res[0]['id']); + $oldValues = $model->toArray(); + $model->update($saveData); + $this->logService->logUpdated($model, $oldValues, 'map.save'); + } else { + $saveData['create_at'] = get_datetime(); + $model = ParkingElectronicMap::query()->create($saveData); + $this->logService->logCreated($model, 'map.save'); + } + } + + public function getList($params): array + { + $floor_id = $params['floor_id']; + $where = [ + 'floor_id' => $floor_id + ]; + if (isset($params['parking_space_id']) + && !empty($params['parking_space_id']) + ) { + $where['space_id'] = $params['parking_space_id']; + } + $columns = [ + 'id', + 'floor_id', + 'space_id', + 'width', + 'height', + 'coordinate_x', + 'coordinate_y' + ]; + $list = ParkingElectronicMap::query()->where($where)->select($columns) + ->get()->toArray(); + foreach ($list as &$item) { + $item['floor_name'] = AdminFloor::query()->where('id', $item['floor_id']) + ->value('name'); + $item['parking_space_number'] = ParkingSpace::query()->where( + 'id', + $item['space_id'] + )->value('number'); + unset($item['floor_id'], $item['space_id']); + } + return $list; + } +} diff --git a/app/Services/ParkingSpaceService.php b/app/Services/ParkingSpaceService.php index bf2570f..ff486c2 100644 --- a/app/Services/ParkingSpaceService.php +++ b/app/Services/ParkingSpaceService.php @@ -147,4 +147,13 @@ class ParkingSpaceService extends BaseService throw $e; } } + + // 获取车位列表 + public static function getSelectList($floor_id): array + { + $columns = ['id as parking_space_id', 'number as parking_space_number']; + return ParkingSpace::query()->where('floor_id', $floor_id)->select( + $columns + )->get()->toArray(); + } } diff --git a/database/migrations/2026_04_23_143449_create_parking_electronic_map_table.php b/database/migrations/2026_04_23_143449_create_parking_electronic_map_table.php new file mode 100644 index 0000000..cd81389 --- /dev/null +++ b/database/migrations/2026_04_23_143449_create_parking_electronic_map_table.php @@ -0,0 +1,33 @@ +id(); + $table->integer('floor_id')->comment('楼层id'); + $table->integer('space_id')->default('')->comment('车位号码'); + $table->string('width', 20)->default('')->comment('宽'); + $table->string('height', 20)->default('')->comment('高'); + $table->string('coordinate_x', 20)->default('')->comment('坐标X'); + $table->string('coordinate_y', 20)->default('')->comment('坐标y'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('parking_electronic_map'); + } +}; diff --git a/resources/lang/en/admin.php b/resources/lang/en/admin.php index 5217e19..ad32c5c 100644 --- a/resources/lang/en/admin.php +++ b/resources/lang/en/admin.php @@ -52,6 +52,7 @@ return [ 'delete_failed' => 'Delete failed !', 'update_succeeded' => 'Update succeeded !', 'save_succeeded' => 'Save succeeded !', + 'save_failed' => 'Save failed !', 'refresh_succeeded' => 'Refresh succeeded !', 'login_successful' => 'Login successful', 'logout_successful' => 'Logout successful', diff --git a/resources/lang/zh-CN/admin.php b/resources/lang/zh-CN/admin.php index 2da0d43..28678cd 100644 --- a/resources/lang/zh-CN/admin.php +++ b/resources/lang/zh-CN/admin.php @@ -52,6 +52,7 @@ return [ 'delete_failed' => '删除失败 !', 'update_succeeded' => '更新成功 !', 'save_succeeded' => '保存成功 !', + 'save_failed' => '失败成功 !', 'refresh_succeeded' => '刷新成功 !', 'login_successful' => '登录成功 !', 'logout_successful' => '登出成功 !', diff --git a/resources/lang/zh-CN/log.php b/resources/lang/zh-CN/log.php index 0def177..11f9327 100644 --- a/resources/lang/zh-CN/log.php +++ b/resources/lang/zh-CN/log.php @@ -51,5 +51,8 @@ return [ 'create' => '创建VIP名单', 'update' => '更新VIP名单', 'delete' => '删除VIP名单' + ], + 'map' => [ + 'save' => '绘制电子地图保存' ] ]; diff --git a/resources/lang/zh-CN/validation.php b/resources/lang/zh-CN/validation.php index e6fa13d..2d18bf1 100644 --- a/resources/lang/zh-CN/validation.php +++ b/resources/lang/zh-CN/validation.php @@ -76,5 +76,11 @@ return [ 'attr_id_numeric' => '车位属性数据必须是数字', 'ids_empty' => '车位数据不能为空', 'ids_array' => '车位数据必须是数组', + ], + 'map' => [ + 'f_empty' => '楼层编号不能为空', + 'f_number' => '楼层编号必须是数字', + 'p_empty' => '车位编号必须是数字', + 'p_number' => '车位编号必须是数字' ] ]; diff --git a/resources/lang/zh-TW/admin.php b/resources/lang/zh-TW/admin.php index ffcd271..1905e0b 100644 --- a/resources/lang/zh-TW/admin.php +++ b/resources/lang/zh-TW/admin.php @@ -52,6 +52,7 @@ return [ 'delete_failed' => '刪除失敗!', 'update_succeeded' => '更新成功!', 'save_succeeded' => '儲存成功!', + 'save_failed' => '儲存失敗!', 'refresh_succeeded' => '成功重新整理!', 'login_successful' => '成功登入!', 'logout_successful' => '成功登出!', diff --git a/routes/admin/api.php b/routes/admin/api.php index 7c3b759..08b1b93 100644 --- a/routes/admin/api.php +++ b/routes/admin/api.php @@ -7,6 +7,7 @@ use App\Http\Controllers\Admin\IndexController; use App\Http\Controllers\Admin\VipAccessRecordController; use App\Http\Controllers\Admin\VipListController; use App\Http\Controllers\Admin\OperationLogController; +use App\Http\Controllers\Admin\ParkingElectronicMapController; use App\Http\Controllers\Admin\ParkingLicensePlateController; use App\Http\Controllers\Admin\ParkingReservationController; use App\Http\Controllers\Admin\ParkingSpaceController; @@ -66,6 +67,11 @@ Route::group(['prefix' => 'admin'], function () { Route::put('/spaceAttr/{id}', [ParkingSpaceAttributesController::class, 'update']); Route::delete('/spaceAttr/{id}', [ParkingSpaceAttributesController::class, 'destroy']); Route::get('/spaceAttr/rule', [ParkingSpaceAttributesController::class, 'rule']); + // 绘制电子地图 + Route::get('/map/index', [ParkingElectronicMapController::class, 'index']); + Route::get('/map/floorList', [ParkingElectronicMapController::class, 'floorList']); + Route::get('/map/parkingSpaceList/{id}', [ParkingElectronicMapController::class, 'getParkingSpaceList']); + Route::post('/map/save', [ParkingElectronicMapController::class, 'save']); // VIP名单 Route::get('/vipList', [VipListController::class, 'index']);