add: endpoint detecciones
This commit is contained in:
parent
098e8c487d
commit
56a599603d
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Arco;
|
use App\Models\Arco;
|
||||||
|
use App\Services\VehicleService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Notsoweb\ApiResponse\Enums\ApiResponse;
|
use Notsoweb\ApiResponse\Enums\ApiResponse;
|
||||||
|
|
||||||
@ -12,6 +13,9 @@
|
|||||||
*/
|
*/
|
||||||
class ArcoController extends Controller
|
class ArcoController extends Controller
|
||||||
{
|
{
|
||||||
|
public function __construct(
|
||||||
|
private VehicleService $vehicleService
|
||||||
|
) {}
|
||||||
/**
|
/**
|
||||||
* Listar todos los arcos
|
* Listar todos los arcos
|
||||||
* GET /api/arcos
|
* GET /api/arcos
|
||||||
@ -159,4 +163,60 @@ public function toggleEstado(int $id)
|
|||||||
'arco' => $arco
|
'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()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -397,7 +397,7 @@ public function buscarPorTag(Request $request)
|
|||||||
$resultado = $this->vehicleService->procesarDeteccion(
|
$resultado = $this->vehicleService->procesarDeteccion(
|
||||||
$validated['fast_id'],
|
$validated['fast_id'],
|
||||||
$arco->ip_address,
|
$arco->ip_address,
|
||||||
$validated['timestamp'] ?? null
|
$validated['antena'] ?? null
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!$resultado['success']) {
|
if (!$resultado['success']) {
|
||||||
|
|||||||
@ -18,6 +18,7 @@ class Detection extends Model
|
|||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'arco_id',
|
'arco_id',
|
||||||
|
'antena',
|
||||||
'fast_id',
|
'fast_id',
|
||||||
'vin',
|
'vin',
|
||||||
'placa',
|
'placa',
|
||||||
|
|||||||
@ -17,7 +17,7 @@ public function __construct(
|
|||||||
/**
|
/**
|
||||||
* Procesar detección de vehículo por fast_id
|
* 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}";
|
$key = "vehiculo:robado:{$fastId}";
|
||||||
|
|
||||||
@ -31,13 +31,13 @@ public function procesarDeteccion(string $fastId, string $arcoIp): array
|
|||||||
if ($enRedis) {
|
if ($enRedis) {
|
||||||
// Ya está marcado como robado, verificar si sigue así
|
// Ya está marcado como robado, verificar si sigue así
|
||||||
$resultado = $this->verificarVehiculoRobado($fastId, json_decode($enRedis, true));
|
$resultado = $this->verificarVehiculoRobado($fastId, json_decode($enRedis, true));
|
||||||
$this->registrarDeteccion($fastId, $resultado, $arcoId);
|
$this->registrarDeteccion($fastId, $resultado, $arcoId, $antena);
|
||||||
return $resultado;
|
return $resultado;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No está en Redis, consultar servicios
|
// No está en Redis, consultar servicios
|
||||||
$resultado = $this->consultarNuevoVehiculo($fastId);
|
$resultado = $this->consultarNuevoVehiculo($fastId);
|
||||||
$this->registrarDeteccion($fastId, $resultado, $arcoId);
|
$this->registrarDeteccion($fastId, $resultado, $arcoId, $antena);
|
||||||
return $resultado;
|
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)
|
* 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)
|
* 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'])) {
|
if (!$resultado['success'] || !isset($resultado['vehiculo'])) {
|
||||||
return;
|
return;
|
||||||
@ -224,6 +240,7 @@ private function registrarDeteccion(string $fastId, array $resultado, ?int $arco
|
|||||||
// Registrar en MySQL
|
// Registrar en MySQL
|
||||||
Detection::create([
|
Detection::create([
|
||||||
'arco_id' => $arcoId,
|
'arco_id' => $arcoId,
|
||||||
|
'antena' => $antena,
|
||||||
'fast_id' => $fastId,
|
'fast_id' => $fastId,
|
||||||
'vin' => $vehiculo['vin'] ?? null,
|
'vin' => $vehiculo['vin'] ?? null,
|
||||||
'placa' => $vehiculo['placa'] ?? 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)
|
// 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}
|
* Formato de key: deteccion:dia:YYYY-MM-DD:{fastId}:{timestamp}
|
||||||
* Expira automáticamente a las 23:59:59 del día
|
* 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');
|
$fecha = now()->format('Y-m-d');
|
||||||
$timestamp = now()->timestamp;
|
$timestamp = now()->timestamp;
|
||||||
@ -256,6 +273,7 @@ private function registrarDeteccionDelDia(string $fastId, array $vehiculo, ?int
|
|||||||
'modelo' => $vehiculo['modelo'] ?? null,
|
'modelo' => $vehiculo['modelo'] ?? null,
|
||||||
'color' => $vehiculo['color'] ?? null,
|
'color' => $vehiculo['color'] ?? null,
|
||||||
'arco_id' => $arcoId,
|
'arco_id' => $arcoId,
|
||||||
|
'antena' => $antena,
|
||||||
'estado' => $resultado['estado'] ?? 'LIBRE',
|
'estado' => $resultado['estado'] ?? 'LIBRE',
|
||||||
'tiene_reporte_robo' => $resultado['tiene_reporte_robo'] ?? false,
|
'tiene_reporte_robo' => $resultado['tiene_reporte_robo'] ?? false,
|
||||||
'fecha_deteccion' => now()->toIso8601String(),
|
'fecha_deteccion' => now()->toIso8601String(),
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('detections', function (Blueprint $table) {
|
||||||
|
$table->string('antena')->nullable()->after('arco_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('detections', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('antena');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
37
database/seeders/ArcoSeeder.php
Normal file
37
database/seeders/ArcoSeeder.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php namespace Database\Seeders;
|
||||||
|
/**
|
||||||
|
* @copyright (c) 2025 Notsoweb Software (https://notsoweb.com) - All Rights Reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
use App\Models\Arco;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Notsoweb\LaravelCore\Supports\UserSecureSupport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Descripción
|
||||||
|
*
|
||||||
|
* @author Moisés Cortés C. <moises.cortes@notsoweb.com>
|
||||||
|
*
|
||||||
|
* @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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Seeder Producción
|
* Seeder Producción
|
||||||
*
|
*
|
||||||
* @author Moisés Cortés C. <moises.cortes@notsoweb.com>
|
* @author Moisés Cortés C. <moises.cortes@notsoweb.com>
|
||||||
*
|
*
|
||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
*/
|
*/
|
||||||
class DatabaseSeeder extends Seeder
|
class DatabaseSeeder extends Seeder
|
||||||
@ -22,5 +22,6 @@ public function run(): void
|
|||||||
$this->call(RoleSeeder::class);
|
$this->call(RoleSeeder::class);
|
||||||
$this->call(UserSeeder::class);
|
$this->call(UserSeeder::class);
|
||||||
$this->call(SettingSeeder::class);
|
$this->call(SettingSeeder::class);
|
||||||
|
$this->call(ArcoSeeder::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,5 +22,6 @@ public function run(): void
|
|||||||
$this->call(RoleSeeder::class);
|
$this->call(RoleSeeder::class);
|
||||||
$this->call(UserSeeder::class);
|
$this->call(UserSeeder::class);
|
||||||
$this->call(SettingSeeder::class);
|
$this->call(SettingSeeder::class);
|
||||||
|
$this->call(ArcoSeeder::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Usuarios predeterminados del sistema
|
* Usuarios predeterminados del sistema
|
||||||
*
|
*
|
||||||
* @author Moisés Cortés C. <moises.cortes@notsoweb.com>
|
* @author Moisés Cortés C. <moises.cortes@notsoweb.com>
|
||||||
*
|
*
|
||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
*/
|
*/
|
||||||
class UserSeeder extends Seeder
|
class UserSeeder extends Seeder
|
||||||
@ -21,34 +21,25 @@ class UserSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$developer = UserSecureSupport::create('developer@notsoweb.com');
|
$developer = UserSecureSupport::create('developer@golsystems.com');
|
||||||
|
|
||||||
User::create([
|
User::create([
|
||||||
'name' => 'Developer',
|
'name' => 'admin',
|
||||||
'paternal' => 'Notsoweb',
|
'paternal' => 'golsystems',
|
||||||
'maternal' => 'Software',
|
'maternal' => 'desarrollo',
|
||||||
'email' => $developer->email,
|
'email' => $developer->email,
|
||||||
'password' => $developer->hash,
|
'password' => $developer->hash,
|
||||||
])->assignRole(__('developer'));
|
])->assignRole(__('developer'));
|
||||||
|
|
||||||
$admin = UserSecureSupport::create('admin@notsoweb.com');
|
$admin = UserSecureSupport::create('admin@golsystems.com');
|
||||||
|
|
||||||
User::create([
|
User::create([
|
||||||
'name' => 'Admin',
|
'name' => 'Admin',
|
||||||
'paternal' => 'Notsoweb',
|
'paternal' => 'Golsystems',
|
||||||
'maternal' => 'Software',
|
'maternal' => 'Desarrollo',
|
||||||
'email' => $admin->email,
|
'email' => $admin->email,
|
||||||
'password' => $admin->hash,
|
'password' => $admin->hash,
|
||||||
])->assignRole(__('admin'));
|
])->assignRole(__('admin'));
|
||||||
|
|
||||||
$demo = UserSecureSupport::create('demo@notsoweb.com');
|
|
||||||
|
|
||||||
User::create([
|
|
||||||
'name' => 'Demo',
|
|
||||||
'paternal' => 'Notsoweb',
|
|
||||||
'maternal' => 'Software',
|
|
||||||
'email' => $demo->email,
|
|
||||||
'password' => $demo->hash,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,7 @@
|
|||||||
// Rutas de Arcos RFID
|
// Rutas de Arcos RFID
|
||||||
Route::resource('/arcos', ArcoController::class);
|
Route::resource('/arcos', ArcoController::class);
|
||||||
Route::patch('/arcos/{id}/toggle-estado', [ArcoController::class, 'toggleEstado']);
|
Route::patch('/arcos/{id}/toggle-estado', [ArcoController::class, 'toggleEstado']);
|
||||||
|
Route::get('/arcos/{id}/detecciones/dia', [ArcoController::class, 'deteccionesDelDia']);
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Rutas públicas */
|
/** Rutas públicas */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user