add: detecciones día

This commit is contained in:
Juan Felipe Zapata Moreno 2026-01-08 12:01:54 -06:00
parent fe324af630
commit a4528a58b5
7 changed files with 351 additions and 270 deletions

View File

@ -21,7 +21,8 @@ public function __construct(
) {}
/**
* Consultar y registrar vehículo por PLACA o VIN (Alta de vehículo robado)
* Consultar vehículo por placa/VIN y darlo de alta como robado
* POST /api/vehicles/consultar
*/
public function consultarVehiculo(Request $request): JsonResponse
{
@ -34,37 +35,34 @@ public function consultarVehiculo(Request $request): JsonResponse
]);
if ($validator->fails()) {
return ApiResponse::INTERNAL_ERROR->response([
return ApiResponse::BAD_REQUEST->response([
'success' => false,
'message' => 'Datos inválidos',
'errors' => $validator->errors()
]);
}
$placa = $request->placa;
$vin = $request->vin;
$datosVehiculo = null;
// Buscar vehículo en vehicle_fakes
$vehiculo = VehicleFake::when($vin, function ($query) use ($vin) {
return $query->where('vin', $vin);
})
->when($placa, function ($query) use ($placa) {
return $query->orWhere('placa', $placa);
})
->first();
if ($request->vin) {
$datosVehiculo = $this->vehicleService->consultarVehiculoPorTag($request->vin);
}
if (!$vehiculo) {
if (!$datosVehiculo && $request->placa) {
$datosVehiculo = $this->vehicleService->consultarVehiculoPorTag($request->placa);
}
if (!$datosVehiculo || !isset($datosVehiculo['tag_number'])) {
return ApiResponse::NOT_FOUND->response([
'success' => false,
'message' => 'No se encontró el vehículo'
'message' => 'No se encontró el vehículo en el sistema'
]);
}
// Generar EPC
$epc = 'E280117000000' . $vehiculo->vin;
$fastId = $datosVehiculo['tag_number'];
// Verificar si ya está en Redis
$key = "vehiculo:robado:{$placa}-{$vin}";
$key = "vehiculo:robado:{$fastId}";
if (Redis::exists($key)) {
return ApiResponse::BAD_REQUEST->response([
'success' => false,
@ -72,50 +70,35 @@ public function consultarVehiculo(Request $request): JsonResponse
]);
}
// Guardar en Redis como robado
// Guardar en Redis usando la estructura del VehicleService
$datos = [
'epc' => $epc,
'folio_tag' => $vehiculo->folio_tag,
'tag_number' => $vehiculo->tag_number,
'vin' => $vehiculo->vin,
'placa' => $vehiculo->placa,
'marca' => $vehiculo->marca,
'modelo' => $vehiculo->modelo,
'color' => $vehiculo->color,
'fecha_robo' => now()->format('Y-m-d'),
'acta' => 'MANUAL-' . now()->format('Ymd-His'),
'denunciante' => 'SISTEMA',
'fecha_acta' => now()->format('Y-m-d'),
'fast_id' => $fastId,
'vin' => $datosVehiculo['vin'] ?? null,
'placa' => $datosVehiculo['placa'] ?? null,
'marca' => $datosVehiculo['marca'] ?? null,
'modelo' => $datosVehiculo['modelo'] ?? null,
'color' => $datosVehiculo['color'] ?? null,
'fecha_robo' => $request->fecha_robo,
'autoridad' => $request->autoridad,
'acta' => $request->acta,
'denunciante' => $request->denunciante,
'fecha_acta' => $request->fecha_acta,
'primera_deteccion' => now()->toIso8601String(),
'ultima_deteccion' => now()->toIso8601String(),
'detecciones' => 0
];
Redis::set($key, json_encode($datos));
Log::warning('Vehículo dado de alta como robado (MANUAL)', [
'epc' => $epc,
'vin' => $vehiculo->vin,
'placa' => $vehiculo->placa
]);
return ApiResponse::OK->response([
'success' => true,
'message' => 'Vehículo registrado como robado exitosamente',
'vehiculo' => [
'epc' => $epc,
'folio_tag' => $vehiculo->folio_tag,
'tag_number' => $vehiculo->tag_number,
'vin' => $vehiculo->vin,
'placa' => $vehiculo->placa,
'marca' => $vehiculo->marca,
'modelo' => $vehiculo->modelo,
'color' => $vehiculo->color
]
'message' => 'Vehículo consultado y registrado como robado exitosamente',
'vehiculo' => $datos
]);
}
/**
* Dar de baja (registrar como recuperado) un vehículo por PLACA o VIN
* Dar de baja (registrar como recuperado)
*/
public function recuperarVehiculo(Request $request): JsonResponse
{
@ -139,8 +122,6 @@ public function recuperarVehiculo(Request $request): JsonResponse
$placa = $request->placa;
$vin = $request->vin;
Log::info('Buscando vehículo robado para recuperar', ['placa' => $placa, 'vin' => $vin]);
// 1. Buscar en Redis (vehículos robados activos)
$vehiculoEncontrado = $this->buscarEnRedis($vin, $placa);
@ -152,17 +133,10 @@ public function recuperarVehiculo(Request $request): JsonResponse
}
$datosRedis = $vehiculoEncontrado['datos'];
$epc = $vehiculoEncontrado['epc'];
Log::info('Vehículo encontrado en Redis', [
'epc' => $epc,
'vin' => $datosRedis['vin'],
'placa' => $datosRedis['placa']
]);
// 2. Guardar en MySQL como recuperado
$vehiculoRecuperado = Vehicle::create([
'epc' => $epc,
'fast_id' => $datosRedis['fast_id'] ?? null,
'vin' => $datosRedis['vin'] ?? null,
'placa' => $datosRedis['placa'] ?? null,
'fecha_robo' => $datosRedis['fecha_robo'] ?? null,
@ -174,20 +148,15 @@ public function recuperarVehiculo(Request $request): JsonResponse
]);
// 3. Eliminar de Redis
Redis::del("vehiculo:robado:{$epc}");
Log::info('Vehículo registrado como recuperado', [
'id' => $vehiculoRecuperado->id,
'vin' => $vehiculoRecuperado->vin,
'placa' => $vehiculoRecuperado->placa
]);
$fastId = $vehiculoEncontrado['fast_id'];
Redis::del("vehiculo:robado:{$fastId}");
return ApiResponse::OK->response([
'success' => true,
'message' => 'Vehículo registrado como recuperado exitosamente',
'vehiculo' => [
'id' => $vehiculoRecuperado->id,
'epc' => $vehiculoRecuperado->epc,
'fast_id' => $vehiculoRecuperado->fast_id,
'vin' => $vehiculoRecuperado->vin,
'placa' => $vehiculoRecuperado->placa,
'fecha_robo' => $vehiculoRecuperado->fecha_robo,
@ -211,7 +180,7 @@ public function recuperarVehiculo(Request $request): JsonResponse
}
/**
* Buscar vehículo en Redis por VIN o Placa
* Buscar vehículo en Redis
*/
private function buscarEnRedis(?string $vin, ?string $placa): ?array
{
@ -227,11 +196,11 @@ private function buscarEnRedis(?string $vin, ?string $placa): ?array
// Buscar por VIN o Placa
if (($vin && $vehiculo['vin'] === $vin) || ($placa && $vehiculo['placa'] === $placa)) {
// Extraer el EPC del key
$epc = str_replace('vehiculo:robado:', '', $key);
// Extraer el fast_id del key
$fastId = str_replace('vehiculo:robado:', '', $key);
return [
'epc' => $epc,
'fast_id' => $fastId,
'datos' => $vehiculo
];
}
@ -298,6 +267,39 @@ public function listarDetecciones()
]);
}
/**
* Listar detecciones del día desde Redis
* GET /api/vehicles/detecciones/dia
*/
public function listarDeteccionesDelDia(Request $request)
{
$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->listarDeteccionesDelDia($fecha);
return ApiResponse::OK->response([
'success' => true,
'fecha' => $fecha ?? now()->format('Y-m-d'),
'total' => count($detecciones),
'detecciones' => $detecciones
]);
} catch (\Exception $e) {
return ApiResponse::INTERNAL_ERROR->response([
'success' => false,
'message' => 'Error al obtener detecciones del día',
'error' => $e->getMessage()
]);
}
}
public function buscarVehiculo(Request $request)
{
$validated = $request->validate([
@ -385,18 +387,14 @@ public function buscarPorTag(Request $request)
{
$validated = $request->validate([
'fast_id' => 'required|string',
'epc' => 'nullable|string',
'antena' => 'nullable|string',
'timestamp' => 'nullable|date'
]);
// Obtener el arco autenticado del middleware
$arco = $request->get('arco_autenticado');
// Si no se proporciona EPC, usar el FastID como identificador
$epc = $validated['epc'] ?? $validated['fast_id'];
$resultado = $this->vehicleService->procesarDeteccion(
$epc,
$validated['fast_id'],
$arco->ip_address,
$validated['timestamp'] ?? null

View File

@ -18,7 +18,7 @@ class Detection extends Model
protected $fillable = [
'arco_id',
'epc',
'fast_id',
'vin',
'placa',
'marca',

View File

@ -10,7 +10,7 @@
class Vehicle extends Model
{
protected $fillable = [
'epc',
'fast_id',
'vin',
'placa',
'fecha_robo',

View File

@ -27,15 +27,15 @@ public function __construct()
}
/**
* Consultar vehículo por tag_number
* Consultar vehículo por tag_number, placa o VIN
*
*/
public function consultarVehiculoPorTag(?string $tagNumber = null)
public function consultarVehiculoPorTag(?string $criterio = null)
{
try {
// solo busca por tag_number
if (empty($tagNumber)) {
Log::warning('ConsultaRepuveConstancia: No se proporcionó tag_number');
// Validar que se proporcionó algún criterio de búsqueda
if (empty($criterio)) {
Log::warning('ConsultaRepuveConstancia: No se proporcionó criterio de búsqueda');
return null;
}
@ -46,19 +46,54 @@ public function consultarVehiculoPorTag(?string $tagNumber = null)
return null;
}
// Consultar vehículos con filtro tag_number
// Determinar el tipo de búsqueda (intentar primero como tag_number, luego placa, luego VIN)
$url = $this->baseUrl . $this->vehiculosEndpoint;
Log::info('ConsultaRepuveConstancia: Consultando', [
'url' => $url,
'tag_number' => $tagNumber
'criterio' => $criterio
]);
// Intentar buscar por tag_number primero
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
])->timeout(30)->get($url, [
'tag_number' => $tagNumber
'tag_number' => $criterio
]);
// Si no lo encuentra por tag_number, intentar por placa
if ($response->successful()) {
$data = $response->json();
if (isset($data['data']['records']['data']) && !empty($data['data']['records']['data'])) {
$vehiculoEncontrado = $data['data']['records']['data'][0];
return $this->transformarDatosVehiculo($vehiculoEncontrado);
}
}
// Intentar búsqueda por placa
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
])->timeout(30)->get($url, [
'placa' => $criterio
]);
// Si no lo encuentra por placa, intentar por VIN
if ($response->successful()) {
$data = $response->json();
if (isset($data['data']['records']['data']) && !empty($data['data']['records']['data'])) {
$vehiculoEncontrado = $data['data']['records']['data'][0];
return $this->transformarDatosVehiculo($vehiculoEncontrado);
}
}
// Intentar búsqueda por VIN
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
])->timeout(30)->get($url, [
'niv' => $criterio
]);
if (!$response->successful()) {
@ -84,7 +119,7 @@ public function consultarVehiculoPorTag(?string $tagNumber = null)
if (empty($vehiculos)) {
Log::info('ConsultaRepuveConstancia: Vehículo no encontrado', [
'tag_number' => $tagNumber
'criterio' => $criterio
]);
return null;
}
@ -96,7 +131,7 @@ public function consultarVehiculoPorTag(?string $tagNumber = null)
} catch (Exception $e) {
Log::error('ConsultaRepuveConstancia: Error al consultar vehículo', [
'tag_number' => $tagNumber,
'criterio' => $criterio,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);

View File

@ -11,13 +11,15 @@
class VehicleService
{
public function __construct(
private ReporteRoboService $reporteRobo,
private ConsultaRepuveConstancia $consultaRepuveCons
) {}
public function procesarDeteccion(string $epc, string $fastId, string $arcoIp, ?string $timestamp = null): array
/**
* Procesar detección de vehículo por fast_id
*/
public function procesarDeteccion(string $fastId, string $arcoIp): array
{
$key = "vehiculo:robado:{$epc}";
$key = "vehiculo:robado:{$fastId}";
// Buscar arco por IP
$arco = Arco::buscarPorIp($arcoIp);
@ -28,171 +30,53 @@ public function procesarDeteccion(string $epc, string $fastId, string $arcoIp, ?
if ($enRedis) {
// Ya está marcado como robado, verificar si sigue así
$resultado = $this->verificarVehiculoRobado($epc, json_decode($enRedis, true));
$this->registrarDeteccion($epc, $resultado, $arcoId);
$resultado = $this->verificarVehiculoRobado($fastId, json_decode($enRedis, true));
$this->registrarDeteccion($fastId, $resultado, $arcoId);
return $resultado;
}
// No está en Redis, consultar servicios
$resultado = $this->consultarNuevoVehiculo($epc, $fastId);
$this->registrarDeteccion($epc, $resultado, $arcoId);
$resultado = $this->consultarNuevoVehiculo($fastId);
$this->registrarDeteccion($fastId, $resultado, $arcoId);
return $resultado;
}
private function consultarNuevoVehiculo(string $epc, string $fastId): array
/**
* Consultar vehículo por tag_id, placa o VIN
*/
public function consultarVehiculoPorTag(string $fastId)
{
// Consultar con FastID (tag_number)
$datosVehiculo = $this->consultaRepuveCons->consultarVehiculoPorTag($fastId);
try {
$vehiculoExterno = $this->consultaRepuveCons->consultarVehiculoPorTag($fastId);
if (!$datosVehiculo || !$datosVehiculo['vin']) {
Log::warning('Vehículo NO encontrado.', [
'epc' => $epc,
if ($vehiculoExterno) {
Log::info('VehicleService: Vehículo encontrado', [
'fast_id' => $fastId,
'tag_number' => $vehiculoExterno['tag_number'] ?? null,
'placa' => $vehiculoExterno['placa'] ?? null,
'vin' => $vehiculoExterno['vin'] ?? null
]);
} else {
Log::info('VehicleService: Vehículo no encontrado', [
'fast_id' => $fastId
]);
return [
'success' => false,
'message' => 'No se encontró información del vehículo.'
];
}
// Consultar REPUVE para verificar si está robado
$reporteRobo = $this->reporteRobo->consultarRobado(
$datosVehiculo['vin'],
$datosVehiculo['placa']
);
return $vehiculoExterno;
if ($reporteRobo['tiene_reporte']) {
// Está robado → Guardar en Redis
$this->guardarEnRedis($epc, $datosVehiculo, $reporteRobo['datos']);
Log::warning('¡VEHÍCULO ROBADO DETECTADO!', [
'epc' => $epc,
} catch (\Exception $e) {
Log::error('VehicleService: Error en consulta', [
'fast_id' => $fastId,
'vin' => $datosVehiculo['vin'],
'placa' => $datosVehiculo['placa']
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return [
'success' => true,
'tiene_reporte_robo' => true,
'estado' => 'ROBADO',
'accion' => 'GUARDADO EN BD DE ROBADOS',
'vehiculo' => array_merge($datosVehiculo, $reporteRobo['datos'])
];
}
// No está robado - vehículo LIBRE
Log::info('Vehículo detectado - LIBRE (sin reporte de robo)', [
'epc' => $epc,
'fast_id' => $fastId,
'vin' => $datosVehiculo['vin'],
'placa' => $datosVehiculo['placa']
]);
return [
'success' => true,
'tiene_reporte_robo' => false,
'estado' => 'LIBRE',
'vehiculo' => $datosVehiculo
];
}
private function verificarVehiculoRobado(string $epc, array $datosRedis): array
{
// Consultar REPUVE para verificar estado actual
$reporteRobo = $this->reporteRobo->consultarRobado(
$datosRedis['vin'],
$datosRedis['placa']
);
if (!$reporteRobo['tiene_reporte']) {
// No tiene reporte robo - RECUPERADO
$this->registrarRecuperacion($epc, $datosRedis);
Log::info('¡VEHÍCULO RECUPERADO!', [
'epc' => $epc,
'vin' => $datosRedis['vin'],
'placa' => $datosRedis['placa']
]);
return [
'success' => true,
'tiene_reporte_robo' => false,
'estado' => 'RECUPERADO',
'accion' => 'GUARDADO EN RECUPERADOS Y ELIMINADO DE ROBADOS',
'vehiculo' => $datosRedis
];
}
// Sigue robado → Actualizar contador en Redis
$this->actualizarDeteccionRedis($epc, $datosRedis);
Log::warning('Vehículo robado detectado nuevamente', [
'epc' => $epc,
'detecciones' => $datosRedis['detecciones'] + 1
]);
return [
'success' => true,
'tiene_reporte_robo' => true,
'estado' => 'ROBADO',
'accion' => 'ACTUALIZADO_EN_REDIS',
'vehiculo' => $datosRedis
];
}
private function guardarEnRedis(string $epc, array $datosEstatal, array $datosRobo)
{
$key = "vehiculo:robado:{$epc}";
$datos = [
'epc' => $epc,
'vin' => $datosEstatal['vin'],
'placa' => $datosEstatal['placa'],
'fecha_robo' => $datosRobo['fecha_robo'] ?? null,
'autoridad' => $datosRobo['autoridad'] ?? null,
'acta' => $datosRobo['acta'] ?? null,
'denunciante' => $datosRobo['denunciante'] ?? null,
'fecha_acta' => $datosRobo['fecha_acta'] ?? null,
'primera_deteccion' => now()->toIso8601String(),
'ultima_deteccion' => now()->toIso8601String(),
'detecciones' => 1
];
Redis::set($key, json_encode($datos));
}
private function actualizarDeteccionRedis(string $epc, array $datosActuales)
{
$key = "vehiculo:robado:{$epc}";
$datosActuales['ultima_deteccion'] = now()->toIso8601String();
$datosActuales['detecciones'] = ($datosActuales['detecciones'] ?? 0) + 1;
Redis::set($key, json_encode($datosActuales));
}
private function registrarRecuperacion(string $epc, array $datosRedis)
{
// Guardar en MySQL
Vehicle::create([
'epc' => $epc,
'vin' => $datosRedis['vin'],
'placa' => $datosRedis['placa'],
'fecha_robo' => $datosRedis['fecha_robo'],
'autoridad_robo' => $datosRedis['autoridad'],
'acta_robo' => $datosRedis['acta'],
'denunciante' => $datosRedis['denunciante'],
'fecha_recuperacion' => now(),
'fecha_acta' => $datosRedis['fecha_acta'] ?? null,
'datos_robo_original' => $datosRedis
]);
// Eliminar de Redis
Redis::del("vehiculo:robado:{$epc}");
return null;
}
}
/**
* Listar todos los vehículos robados activos en Redis
*/
public function listarVehiculosRobados(): array
{
$keys = Redis::keys('vehiculo:robado:*');
@ -208,7 +92,128 @@ public function listarVehiculosRobados(): array
return $vehiculos;
}
private function registrarDeteccion(string $epc, array $resultado, ?int $arcoId = null)
/**
* Listar todas las detecciones del día desde Redis
* @param string|null $fecha Fecha en formato Y-m-d (opcional, por defecto hoy)
* @return array
*/
public function listarDeteccionesDelDia(?string $fecha = null): array
{
$fecha = $fecha ?? now()->format('Y-m-d');
$pattern = "deteccion:dia:{$fecha}:*";
$keys = Redis::keys($pattern);
$detecciones = [];
foreach ($keys as $key) {
$datos = Redis::get($key);
if ($datos) {
$detecciones[] = json_decode($datos, true);
}
}
// Ordenar por fecha de detección (más reciente primero)
usort($detecciones, function($a, $b) {
return strcmp($b['fecha_deteccion'], $a['fecha_deteccion']);
});
return $detecciones;
}
/**
* Obtener estadísticas de detecciones del día
* @param string|null $fecha Fecha en formato Y-m-d (opcional, por defecto hoy)
* @return array
*/
public function obtenerEstadisticasDelDia(?string $fecha = null): array
{
$detecciones = $this->listarDeteccionesDelDia($fecha);
$total = count($detecciones);
$robados = collect($detecciones)->where('tiene_reporte_robo', true)->count();
$libres = collect($detecciones)->where('tiene_reporte_robo', false)->count();
return [
'fecha' => $fecha ?? now()->format('Y-m-d'),
'total_detecciones' => $total,
'vehiculos_robados' => $robados,
'vehiculos_libres' => $libres,
'detecciones' => $detecciones
];
}
/**
* Consultar nuevo vehículo (no está en Redis de robados)
*/
private function consultarNuevoVehiculo(string $fastId): array
{
// Consultar con FastID (tag_number)
$datosVehiculo = $this->consultaRepuveCons->consultarVehiculoPorTag($fastId);
if (!$datosVehiculo || !$datosVehiculo['vin']) {
Log::warning('Vehículo NO encontrado.', [
'fast_id' => $fastId
]);
return [
'success' => false,
'message' => 'No se encontró información del vehículo.'
];
}
Log::info('Vehículo detectado - LIBRE (no está en Redis de robados)', [
'fast_id' => $fastId,
'vin' => $datosVehiculo['vin'],
'placa' => $datosVehiculo['placa']
]);
return [
'success' => true,
'tiene_reporte_robo' => false,
'estado' => 'LIBRE',
'vehiculo' => $datosVehiculo
];
}
/**
* Verificar vehículo robado (ya está en Redis)
*/
private function verificarVehiculoRobado(string $fastId, array $datosRedis): array
{
$this->actualizarDeteccionRedis($fastId, $datosRedis);
Log::warning('Vehículo robado detectado nuevamente', [
'fast_id' => $fastId,
'vin' => $datosRedis['vin'] ?? null,
'placa' => $datosRedis['placa'] ?? null,
'detecciones' => ($datosRedis['detecciones'] ?? 0) + 1
]);
return [
'success' => true,
'tiene_reporte_robo' => true,
'estado' => 'ROBADO',
'accion' => 'ACTUALIZADO_EN_REDIS',
'vehiculo' => $datosRedis
];
}
/**
* Actualizar contador de detecciones en Redis
*/
private function actualizarDeteccionRedis(string $fastId, array $datosActuales)
{
$key = "vehiculo:robado:{$fastId}";
$datosActuales['ultima_deteccion'] = now()->toIso8601String();
$datosActuales['detecciones'] = ($datosActuales['detecciones'] ?? 0) + 1;
Redis::set($key, json_encode($datosActuales));
}
/**
* Registrar detección en MySQL y Redis (detecciones del día)
*/
private function registrarDeteccion(string $fastId, array $resultado, ?int $arcoId = null)
{
if (!$resultado['success'] || !isset($resultado['vehiculo'])) {
return;
@ -216,9 +221,10 @@ private function registrarDeteccion(string $epc, array $resultado, ?int $arcoId
$vehiculo = $resultado['vehiculo'];
// Registrar en MySQL
Detection::create([
'arco_id' => $arcoId,
'epc' => $epc,
'fast_id' => $fastId,
'vin' => $vehiculo['vin'] ?? null,
'placa' => $vehiculo['placa'] ?? null,
'marca' => $vehiculo['marca'] ?? null,
@ -226,42 +232,43 @@ private function registrarDeteccion(string $epc, array $resultado, ?int $arcoId
'color' => $vehiculo['color'] ?? null,
'fecha_deteccion' => now()
]);
// Registrar en Redis (detecciones del día)
$this->registrarDeteccionDelDia($fastId, $vehiculo, $arcoId, $resultado);
}
/**
* Consultar vehículo por tag_id
* Registrar detección en Redis para el día actual
* Formato de key: deteccion:dia:YYYY-MM-DD:{fastId}:{timestamp}
* Expira automáticamente a las 23:59:59 del día
*/
public function consultarVehiculoPorTag(?string $epc = null, ?string $tagId = null)
private function registrarDeteccionDelDia(string $fastId, array $vehiculo, ?int $arcoId, array $resultado)
{
try {
// Validar que se proporcionó tag_id
if (empty($tagId)) {
Log::warning('VehicleService: No se proporcionó tag_id');
return null;
}
$vehiculoExterno = $this->consultaRepuveCons->consultarVehiculoPorTag($tagId);
$fecha = now()->format('Y-m-d');
$timestamp = now()->timestamp;
$key = "deteccion:dia:{$fecha}:{$fastId}:{$timestamp}";
if ($vehiculoExterno) {
Log::info('VehicleService: Vehículo encontrado', [
'tag_id' => $vehiculoExterno['tag_id'] ?? null,
'tag_number' => $vehiculoExterno['tag_number'] ?? null,
'vin' => $vehiculoExterno['vin'] ?? null
]);
} else {
Log::info('VehicleService: Vehículo no encontrado', [
'tag_id' => $tagId
]);
}
$datosDeteccion = [
'fast_id' => $fastId,
'vin' => $vehiculo['vin'] ?? null,
'placa' => $vehiculo['placa'] ?? null,
'marca' => $vehiculo['marca'] ?? null,
'modelo' => $vehiculo['modelo'] ?? null,
'color' => $vehiculo['color'] ?? null,
'arco_id' => $arcoId,
'estado' => $resultado['estado'] ?? 'LIBRE',
'tiene_reporte_robo' => $resultado['tiene_reporte_robo'] ?? false,
'fecha_deteccion' => now()->toIso8601String(),
];
return $vehiculoExterno;
// Guardar en Redis
Redis::set($key, json_encode($datosDeteccion));
} catch (\Exception $e) {
Log::error('VehicleService: Error en consulta', [
'tag_id' => $tagId,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return null;
}
// Calcular segundos hasta el final del día (23:59:59)
$finDelDia = now()->endOfDay();
$segundosHastaFinDelDia = $finDelDia->timestamp - now()->timestamp;
// Establecer expiración automática al final del día
Redis::expire($key, $segundosHastaFinDelDia);
}
}

View File

@ -0,0 +1,40 @@
<?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
{
// Renombrar columna en tabla detections
Schema::table('detections', function (Blueprint $table) {
$table->renameColumn('epc', 'fast_id');
});
// Renombrar columna en tabla vehicles
Schema::table('vehicles', function (Blueprint $table) {
$table->renameColumn('epc', 'fast_id');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Revertir cambio en tabla detections
Schema::table('detections', function (Blueprint $table) {
$table->renameColumn('fast_id', 'epc');
});
// Revertir cambio en tabla vehicles
Schema::table('vehicles', function (Blueprint $table) {
$table->renameColumn('fast_id', 'epc');
});
}
};

View File

@ -33,6 +33,7 @@
Route::get('/vehicles/robados', [VehicleController::class, 'listarRobados']);
Route::get('/vehicles', [VehicleController::class, 'listarRecuperados']);
Route::get('/vehicles/detecciones', [VehicleController::class, 'listarDetecciones']);
Route::get('/vehicles/detecciones/dia', [VehicleController::class, 'listarDeteccionesDelDia']);
Route::get('/vehicles/robado', [VehicleController::class, 'buscarVehiculoRobado']);
// Rutas de Arcos RFID