diff --git a/app/Http/Controllers/Api/ArcoController.php b/app/Http/Controllers/Api/ArcoController.php index cda82ff..8fc0bf0 100644 --- a/app/Http/Controllers/Api/ArcoController.php +++ b/app/Http/Controllers/Api/ArcoController.php @@ -4,6 +4,7 @@ use App\Http\Controllers\Controller; use App\Models\Arco; +use App\Services\VehicleService; use Illuminate\Http\Request; use Notsoweb\ApiResponse\Enums\ApiResponse; @@ -12,6 +13,9 @@ */ class ArcoController extends Controller { + public function __construct( + private VehicleService $vehicleService + ) {} /** * Listar todos los arcos * GET /api/arcos @@ -159,4 +163,60 @@ public function toggleEstado(int $id) 'arco' => $arco ]); } + + /** + * Listar detecciones del día de un arco específico + * GET /api/arcos/{id}/detecciones/dia + */ + public function deteccionesDelDia(Request $request, int $id) + { + $arco = Arco::find($id); + + if (!$arco) { + return ApiResponse::NOT_FOUND->response([ + 'success' => false, + 'message' => 'Arco no encontrado' + ]); + } + + $fecha = $request->input('fecha'); // Formato: Y-m-d (opcional) + + if ($fecha && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $fecha)) { + return ApiResponse::BAD_REQUEST->response([ + 'success' => false, + 'message' => 'Formato de fecha inválido. Use YYYY-MM-DD' + ]); + } + + try { + $detecciones = $this->vehicleService->listarDeteccionesDelDiaPorArco($id, $fecha); + + // Filtrar solo VIN, placa y antena + $deteccionesFiltradas = array_map(function($deteccion) { + return [ + 'vin' => $deteccion['vin'] ?? null, + 'placa' => $deteccion['placa'] ?? null, + 'antena' => $deteccion['antena'] ?? null, + ]; + }, $detecciones); + + return ApiResponse::OK->response([ + 'success' => true, + 'arco' => [ + 'id' => $arco->id, + 'nombre' => $arco->nombre, + 'ubicacion' => $arco->ubicacion, + ], + 'fecha' => $fecha ?? now()->format('Y-m-d'), + 'total' => count($deteccionesFiltradas), + 'detecciones' => $deteccionesFiltradas + ]); + } catch (\Exception $e) { + return ApiResponse::INTERNAL_ERROR->response([ + 'success' => false, + 'message' => 'Error al obtener detecciones del arco', + 'error' => $e->getMessage() + ]); + } + } } diff --git a/app/Http/Controllers/Api/VehicleController.php b/app/Http/Controllers/Api/VehicleController.php index 5310b29..04eaded 100644 --- a/app/Http/Controllers/Api/VehicleController.php +++ b/app/Http/Controllers/Api/VehicleController.php @@ -397,7 +397,7 @@ public function buscarPorTag(Request $request) $resultado = $this->vehicleService->procesarDeteccion( $validated['fast_id'], $arco->ip_address, - $validated['timestamp'] ?? null + $validated['antena'] ?? null ); if (!$resultado['success']) { diff --git a/app/Models/Detection.php b/app/Models/Detection.php index 7bd9fab..84e7aa0 100644 --- a/app/Models/Detection.php +++ b/app/Models/Detection.php @@ -18,6 +18,7 @@ class Detection extends Model protected $fillable = [ 'arco_id', + 'antena', 'fast_id', 'vin', 'placa', diff --git a/app/Services/VehicleService.php b/app/Services/VehicleService.php index 2946dbe..a7c2829 100644 --- a/app/Services/VehicleService.php +++ b/app/Services/VehicleService.php @@ -17,7 +17,7 @@ public function __construct( /** * Procesar detección de vehículo por fast_id */ - public function procesarDeteccion(string $fastId, string $arcoIp): array + public function procesarDeteccion(string $fastId, string $arcoIp, ?string $antena = null): array { $key = "vehiculo:robado:{$fastId}"; @@ -31,13 +31,13 @@ public function procesarDeteccion(string $fastId, string $arcoIp): array if ($enRedis) { // Ya está marcado como robado, verificar si sigue así $resultado = $this->verificarVehiculoRobado($fastId, json_decode($enRedis, true)); - $this->registrarDeteccion($fastId, $resultado, $arcoId); + $this->registrarDeteccion($fastId, $resultado, $arcoId, $antena); return $resultado; } // No está en Redis, consultar servicios $resultado = $this->consultarNuevoVehiculo($fastId); - $this->registrarDeteccion($fastId, $resultado, $arcoId); + $this->registrarDeteccion($fastId, $resultado, $arcoId, $antena); return $resultado; } @@ -141,6 +141,22 @@ public function obtenerEstadisticasDelDia(?string $fecha = null): array ]; } + /** + * Listar detecciones del día de un arco específico + */ + public function listarDeteccionesDelDiaPorArco(int $arcoId, ?string $fecha = null): array + { + $todasDetecciones = $this->listarDeteccionesDelDia($fecha); + + // Filtrar solo las detecciones de este arco + $deteccionesArco = collect($todasDetecciones) + ->where('arco_id', $arcoId) + ->values() + ->all(); + + return $deteccionesArco; + } + /** * Consultar nuevo vehículo (no está en Redis de robados) */ @@ -213,7 +229,7 @@ private function actualizarDeteccionRedis(string $fastId, array $datosActuales) /** * Registrar detección en MySQL y Redis (detecciones del día) */ - private function registrarDeteccion(string $fastId, array $resultado, ?int $arcoId = null) + private function registrarDeteccion(string $fastId, array $resultado, ?int $arcoId = null, ?string $antena = null) { if (!$resultado['success'] || !isset($resultado['vehiculo'])) { return; @@ -224,6 +240,7 @@ private function registrarDeteccion(string $fastId, array $resultado, ?int $arco // Registrar en MySQL Detection::create([ 'arco_id' => $arcoId, + 'antena' => $antena, 'fast_id' => $fastId, 'vin' => $vehiculo['vin'] ?? null, 'placa' => $vehiculo['placa'] ?? null, @@ -234,7 +251,7 @@ private function registrarDeteccion(string $fastId, array $resultado, ?int $arco ]); // Registrar en Redis (detecciones del día) - $this->registrarDeteccionDelDia($fastId, $vehiculo, $arcoId, $resultado); + $this->registrarDeteccionDelDia($fastId, $vehiculo, $arcoId, $resultado, $antena); } /** @@ -242,7 +259,7 @@ private function registrarDeteccion(string $fastId, array $resultado, ?int $arco * Formato de key: deteccion:dia:YYYY-MM-DD:{fastId}:{timestamp} * Expira automáticamente a las 23:59:59 del día */ - private function registrarDeteccionDelDia(string $fastId, array $vehiculo, ?int $arcoId, array $resultado) + private function registrarDeteccionDelDia(string $fastId, array $vehiculo, ?int $arcoId, array $resultado, ?string $antena = null) { $fecha = now()->format('Y-m-d'); $timestamp = now()->timestamp; @@ -256,6 +273,7 @@ private function registrarDeteccionDelDia(string $fastId, array $vehiculo, ?int 'modelo' => $vehiculo['modelo'] ?? null, 'color' => $vehiculo['color'] ?? null, 'arco_id' => $arcoId, + 'antena' => $antena, 'estado' => $resultado['estado'] ?? 'LIBRE', 'tiene_reporte_robo' => $resultado['tiene_reporte_robo'] ?? false, 'fecha_deteccion' => now()->toIso8601String(), diff --git a/database/migrations/2026_01_08_140352_add_antena_to_detections_table.php b/database/migrations/2026_01_08_140352_add_antena_to_detections_table.php new file mode 100644 index 0000000..5413e2c --- /dev/null +++ b/database/migrations/2026_01_08_140352_add_antena_to_detections_table.php @@ -0,0 +1,28 @@ +string('antena')->nullable()->after('arco_id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('detections', function (Blueprint $table) { + $table->dropColumn('antena'); + }); + } +}; diff --git a/database/seeders/ArcoSeeder.php b/database/seeders/ArcoSeeder.php new file mode 100644 index 0000000..dd71e60 --- /dev/null +++ b/database/seeders/ArcoSeeder.php @@ -0,0 +1,37 @@ + + * + * @version 1.0.0 + */ +class ArcoSeeder extends Seeder +{ + /** + * Ejecutar sembrado de base de datos + */ + public function run(): void + { + $arco = Arco::create([ + 'nombre' => 'Arco', + 'ip_address' => '10.30.204.125', + 'ubicacion' => 'Ubicación del arco', + 'antena_1' => 'FRONTERA - VILLAHERMOSA', + 'antena_2' => 'VILLAHERMOSA - FRONTERA', + ]); + + // Obtener el token desencriptado + $plainToken = $arco->obtenerTokenDesencriptado(); + + $this->command->getOutput()->writeln("\n Token del arco => {$plainToken}\n"); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 31ba273..1f1cc23 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -7,9 +7,9 @@ /** * Seeder Producción - * + * * @author Moisés Cortés C. - * + * * @version 1.0.0 */ class DatabaseSeeder extends Seeder @@ -22,5 +22,6 @@ public function run(): void $this->call(RoleSeeder::class); $this->call(UserSeeder::class); $this->call(SettingSeeder::class); + $this->call(ArcoSeeder::class); } } diff --git a/database/seeders/DevSeeder.php b/database/seeders/DevSeeder.php index 270ea3b..4b2e190 100644 --- a/database/seeders/DevSeeder.php +++ b/database/seeders/DevSeeder.php @@ -22,5 +22,6 @@ public function run(): void $this->call(RoleSeeder::class); $this->call(UserSeeder::class); $this->call(SettingSeeder::class); + $this->call(ArcoSeeder::class); } } diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php index d6716c5..e352574 100644 --- a/database/seeders/UserSeeder.php +++ b/database/seeders/UserSeeder.php @@ -9,9 +9,9 @@ /** * Usuarios predeterminados del sistema - * + * * @author Moisés Cortés C. - * + * * @version 1.0.0 */ class UserSeeder extends Seeder @@ -21,34 +21,25 @@ class UserSeeder extends Seeder */ public function run(): void { - $developer = UserSecureSupport::create('developer@notsoweb.com'); + $developer = UserSecureSupport::create('developer@golsystems.com'); User::create([ - 'name' => 'Developer', - 'paternal' => 'Notsoweb', - 'maternal' => 'Software', + 'name' => 'admin', + 'paternal' => 'golsystems', + 'maternal' => 'desarrollo', 'email' => $developer->email, 'password' => $developer->hash, ])->assignRole(__('developer')); - $admin = UserSecureSupport::create('admin@notsoweb.com'); + $admin = UserSecureSupport::create('admin@golsystems.com'); User::create([ 'name' => 'Admin', - 'paternal' => 'Notsoweb', - 'maternal' => 'Software', + 'paternal' => 'Golsystems', + 'maternal' => 'Desarrollo', 'email' => $admin->email, 'password' => $admin->hash, ])->assignRole(__('admin')); - $demo = UserSecureSupport::create('demo@notsoweb.com'); - - User::create([ - 'name' => 'Demo', - 'paternal' => 'Notsoweb', - 'maternal' => 'Software', - 'email' => $demo->email, - 'password' => $demo->hash, - ]); } } diff --git a/routes/api.php b/routes/api.php index 007b742..845959c 100644 --- a/routes/api.php +++ b/routes/api.php @@ -39,6 +39,7 @@ // Rutas de Arcos RFID Route::resource('/arcos', ArcoController::class); Route::patch('/arcos/{id}/toggle-estado', [ArcoController::class, 'toggleEstado']); + Route::get('/arcos/{id}/detecciones/dia', [ArcoController::class, 'deteccionesDelDia']); }); /** Rutas públicas */