add: detecciones día
This commit is contained in:
parent
fe324af630
commit
a4528a58b5
@ -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
|
||||
|
||||
@ -18,7 +18,7 @@ class Detection extends Model
|
||||
|
||||
protected $fillable = [
|
||||
'arco_id',
|
||||
'epc',
|
||||
'fast_id',
|
||||
'vin',
|
||||
'placa',
|
||||
'marca',
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
class Vehicle extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'epc',
|
||||
'fast_id',
|
||||
'vin',
|
||||
'placa',
|
||||
'fecha_robo',
|
||||
|
||||
@ -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()
|
||||
]);
|
||||
|
||||
@ -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,
|
||||
'fast_id' => $fastId
|
||||
]);
|
||||
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.'
|
||||
];
|
||||
}
|
||||
return $vehiculoExterno;
|
||||
|
||||
// Consultar REPUVE para verificar si está robado
|
||||
$reporteRobo = $this->reporteRobo->consultarRobado(
|
||||
$datosVehiculo['vin'],
|
||||
$datosVehiculo['placa']
|
||||
);
|
||||
|
||||
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'])
|
||||
];
|
||||
return null;
|
||||
}
|
||||
|
||||
// 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}");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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');
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user