diff --git a/app/Http/Controllers/Admin/ParkingSpaceAttributesController.php b/app/Http/Controllers/Admin/ParkingSpaceAttributesController.php new file mode 100644 index 0000000..c67d7b5 --- /dev/null +++ b/app/Http/Controllers/Admin/ParkingSpaceAttributesController.php @@ -0,0 +1,210 @@ +responseService = $responseService; + $this->SpaceAttributesService = $SpaceAttributesService; + } + + /** + * Display a listing of the resource. + */ + public function index(Request $request): JsonResponse + { + try { + $query = ParkingSpaceAttributes::query(); + + // 分页 + $page = $request->input('page', 1); + $perPage = $request->input('per_page', 10); + + $total = $query->count(); + $items = $query->latest()->forPage($page, $perPage)->get(); + + return $this->responseService->success([ + 'items' => $items, + 'total' => $total, + 'page' => $page, + 'per_page' => $perPage, + 'last_page' => ceil($total / $perPage), + ]); + } catch (Exception $e) { + $m_prefix = __('exception.exception_handler.resource'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + } + + /** + * @param Request $request + * @return JsonResponse + * @throws ValidationException + */ + public function store(Request $request): JsonResponse + { + try { + $this->saveValidator($request->all()); + $this->SpaceAttributesService->createModel($request->all()); + + return $this->responseService->success( + null, + __('admin.save_succeeded') + ); + } catch (ValidationException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.space_attributes.create_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @param array $data + * @param int $id + * @return void + * @throws ValidationException + */ + public function saveValidator(array $data, int $id = 0): void + { + $rules = [ + 'attributes' => 'required', + 'import_diagram' => 'required' + ]; + $messages = [ + 'attributes.required' => __( + 'validation.space_attributes.a_empty' + ), + 'import_diagram.required' => __( + 'validation.space_attributes.i_empty' + ) + ]; + if ($id) { + $this->validateId($id, ParkingSpaceAttributes::class); + } + $validator = Validator::make($data, $rules, $messages); + + if ($validator->fails()) { + throw new ValidationException($validator); + } + } + + /** + * @param string $id + * @return JsonResponse + */ + public function edit(string $id): JsonResponse + { + try { + $this->validateId($id, ParkingSpaceAttributes::class); + $data = ParkingSpaceAttributes::query() + ->where('id', $id) + ->get() + ->toArray(); + return $this->responseService->success($data); + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.get_data_failed') . ':' . $e->getMessage() + ); + } + } + + /** + * @param Request $request + * @param string $id + * @return JsonResponse + * @throws ValidationException + */ + public function update(Request $request, string $id): JsonResponse + { + try { + $this->saveValidator($request->all(), $id); + $this->SpaceAttributesService->updateModel($request->all(), $id); + return $this->responseService->success( + null, + __('admin.update_succeeded') + ); + } catch (ValidationException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.space_attributes.update_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @param string $id + * @return JsonResponse + * @throws ValidationException + */ + public function destroy(string $id): JsonResponse + { + try { + $this->validateId($id, ParkingSpaceAttributes::class); + $this->SpaceAttributesService->deleteModel($id); + return $this->responseService->success( + null, + __('admin.delete_succeeded') + ); + } catch (ValidationException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.space_attributes.destroy_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @return JsonResponse + * @throws InvalidArgumentException + */ + public function rule(): JsonResponse + { + try { + return $this->responseService->success( + $this->methodShow('parking_space_attributes') + ); + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.get_data_failed') . ':' . $e->getMessage() + ); + } + } +} diff --git a/app/Models/ParkingSpaceAttributes.php b/app/Models/ParkingSpaceAttributes.php new file mode 100644 index 0000000..89557e0 --- /dev/null +++ b/app/Models/ParkingSpaceAttributes.php @@ -0,0 +1,20 @@ +logService = $logService; + } + + /** + * 创建车位属性 + * @param array $data + * @return Model|Builder + * @throws Exception + */ + public function createModel(array $data): Model|Builder + { + try { + DB::beginTransaction(); + + if (ParkingSpaceAttributes::query()->where( + 'attributes', + $data['attributes'] + )->exists() + ) { + throw new Exception( + __('service.space_attributes.attributes_exists') + ); + } + + $model = ParkingSpaceAttributes::query()->create([ + 'attributes' => $data['attributes'], + 'import_diagram' => $data['import_diagram'], + 'created_at' => get_datetime() + ]); + + $this->logService->logCreated($model, '创建车位属性'); + + DB::commit(); + return $model; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + + /** + * @param array $data + * @param int $id + * @return Model|Builder + * @throws Exception + */ + public function updateModel(array $data, int $id): Model|Builder + { + try { + DB::beginTransaction(); + + // 验证 + $existsWhere = [ + ['attributes', '=', $data['attributes']], + ['id', '<>', $id] + ]; + if ( + ParkingSpaceAttributes::query()->where($existsWhere)->exists() + ) { + throw new Exception( + __('service.space_attributes.attributes_exists') + ); + } + + // 更新 + $model = ParkingSpaceAttributes::query()->findOrFail($id); + $oldValues = $model->toArray(); + + $model->update([ + 'attributes' => $data['attributes'], + 'import_diagram' => $data['import_diagram'], + 'updated_at' => get_datetime() + ]); + + $this->logService->logUpdated($model, $oldValues, '更新车位属性'); + + DB::commit(); + return $model; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + /** + * @param $id + * @return bool + * @throws Exception + */ + public function deleteModel($id): bool + { + try { + DB::beginTransaction(); + + $model = ParkingSpaceAttributes::query()->findOrFail($id); + + $this->logService->logDeleted($model, '删除车位属性'); + + $model->delete(); + + DB::commit(); + return true; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } +} diff --git a/database/migrations/2026_03_05_144951_create_parking_space_attributes_table.php b/database/migrations/2026_03_05_144951_create_parking_space_attributes_table.php new file mode 100644 index 0000000..1d9d784 --- /dev/null +++ b/database/migrations/2026_03_05_144951_create_parking_space_attributes_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('attributes', 50)->unique()->comment('车位属性'); + $table->string('import_diagram', 255)->comment('汇入图示'); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('parking_space_attributes'); + } +}; diff --git a/routes/admin/api.php b/routes/admin/api.php index e76758c..5632eba 100644 --- a/routes/admin/api.php +++ b/routes/admin/api.php @@ -6,6 +6,7 @@ use App\Http\Controllers\Admin\FloorController; use App\Http\Controllers\Admin\IndexController; use App\Http\Controllers\Admin\VipListController; use App\Http\Controllers\Admin\OperationLogController; +use App\Http\Controllers\Admin\ParkingSpaceAttributesController; use App\Http\Controllers\Admin\RolesController; use App\Http\Controllers\Admin\TranslationController; use App\Http\Controllers\Admin\UploadController; @@ -27,6 +28,10 @@ Route::group(['prefix' => 'admin'], function () { // 首页 Route::get('/index', [IndexController::class, 'index']); Route::get('/menu', [IndexController::class, 'menu']); + // 车位属性管理 + Route::apiResource('parkingSpaceAttributes', ParkingSpaceAttributesController::class); + Route::get('/parking_space_attributes/rule', [ParkingSpaceAttributesController::class, 'rule']); + // VIP名单 Route::apiResource('listVip', VipListController::class); Route::post('listVip-import', [VipListController::class, 'import']);