laravel reverb
This commit is contained in:
parent
0487421758
commit
1b4eba2c6c
59
app/Events/VehiculoRobadoDetectado.php
Normal file
59
app/Events/VehiculoRobadoDetectado.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Events;
|
||||||
|
|
||||||
|
use App\Models\AlertaRobo;
|
||||||
|
use Illuminate\Broadcasting\Channel;
|
||||||
|
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||||
|
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||||
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class VehiculoRobadoDetectado implements ShouldBroadcast
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||||
|
|
||||||
|
public AlertaRobo $alerta;
|
||||||
|
|
||||||
|
public function __construct(AlertaRobo $alerta)
|
||||||
|
{
|
||||||
|
$this->alerta = $alerta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Canal público para todos los usuarios
|
||||||
|
*/
|
||||||
|
public function broadcastOn(): Channel
|
||||||
|
{
|
||||||
|
return new Channel('alertas-robos');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nombre del evento en el frontend
|
||||||
|
*/
|
||||||
|
public function broadcastAs(): string
|
||||||
|
{
|
||||||
|
return 'vehiculo.robado.detectado';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Datos que se envían al frontend
|
||||||
|
*/
|
||||||
|
public function broadcastWith(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'alerta_id' => $this->alerta->id,
|
||||||
|
'fast_id' => $this->alerta->fast_id,
|
||||||
|
'vin' => $this->alerta->vin,
|
||||||
|
'placa' => $this->alerta->placa,
|
||||||
|
'marca' => $this->alerta->marca,
|
||||||
|
'modelo' => $this->alerta->modelo,
|
||||||
|
'color' => $this->alerta->color,
|
||||||
|
'arco_id' => $this->alerta->arco_id,
|
||||||
|
'arco_nombre' => $this->alerta->arco_nombre,
|
||||||
|
'antena' => $this->alerta->antena,
|
||||||
|
'fecha_deteccion' => $this->alerta->fecha_deteccion->toIso8601String(),
|
||||||
|
'mensaje' => "🚨 VEHÍCULO ROBADO DETECTADO: {$this->alerta->placa} en {$this->alerta->arco_nombre}",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
133
app/Http/Controllers/Api/AlertaRoboController.php
Normal file
133
app/Http/Controllers/Api/AlertaRoboController.php
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\AlertaRobo;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Notsoweb\ApiResponse\Enums\ApiResponse;
|
||||||
|
|
||||||
|
class AlertaRoboController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Listar alertas pendientes (no vistas)
|
||||||
|
* GET /api/alertas/pendientes
|
||||||
|
*/
|
||||||
|
public function pendientes(Request $request)
|
||||||
|
{
|
||||||
|
$alertas = AlertaRobo::pendientes()
|
||||||
|
->recientes()
|
||||||
|
->with(['arco', 'usuario'])
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return ApiResponse::OK->response([
|
||||||
|
'success' => true,
|
||||||
|
'total' => $alertas->count(),
|
||||||
|
'alertas' => $alertas
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listar todas las alertas con filtros
|
||||||
|
* GET /api/alertas
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$query = AlertaRobo::query()->with(['arco', 'usuario']);
|
||||||
|
|
||||||
|
// Filtro por estado (visto/no visto)
|
||||||
|
if ($request->has('visto')) {
|
||||||
|
$query->where('visto', $request->boolean('visto'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filtro por arco
|
||||||
|
if ($request->has('arco_id')) {
|
||||||
|
$query->where('arco_id', $request->arco_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filtro por placa
|
||||||
|
if ($request->has('placa') && !empty($request->placa)) {
|
||||||
|
$query->where('placa', 'like', '%' . $request->placa . '%');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filtro por VIN
|
||||||
|
if ($request->has('vin') && !empty($request->vin)) {
|
||||||
|
$query->where('vin', 'like', '%' . $request->vin . '%');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filtro por rango de fechas
|
||||||
|
if ($request->has('fecha_desde')) {
|
||||||
|
$query->where('fecha_deteccion', '>=', $request->fecha_desde);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('fecha_hasta')) {
|
||||||
|
$query->where('fecha_deteccion', '<=', $request->fecha_hasta);
|
||||||
|
}
|
||||||
|
|
||||||
|
$alertas = $query->orderBy('fecha_deteccion', 'desc')
|
||||||
|
->paginate($request->input('per_page', 15));
|
||||||
|
|
||||||
|
return ApiResponse::OK->response([
|
||||||
|
'success' => true,
|
||||||
|
'alertas' => $alertas
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ver una alerta específica
|
||||||
|
* GET /api/alertas/{id}
|
||||||
|
*/
|
||||||
|
public function show(int $id)
|
||||||
|
{
|
||||||
|
$alerta = AlertaRobo::with(['arco', 'usuario'])->find($id);
|
||||||
|
|
||||||
|
if (!$alerta) {
|
||||||
|
return ApiResponse::NOT_FOUND->response([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Alerta no encontrada'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse::OK->response([
|
||||||
|
'success' => true,
|
||||||
|
'alerta' => $alerta
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirmar/marcar alerta como vista
|
||||||
|
* PUT /api/alertas/{id}/confirmar
|
||||||
|
*/
|
||||||
|
public function confirmar(Request $request, int $id)
|
||||||
|
{
|
||||||
|
$alerta = AlertaRobo::find($id);
|
||||||
|
|
||||||
|
if (!$alerta) {
|
||||||
|
return ApiResponse::NOT_FOUND->response([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Alerta no encontrada'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($alerta->visto) {
|
||||||
|
return ApiResponse::BAD_REQUEST->response([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Esta alerta ya fue confirmada anteriormente',
|
||||||
|
'confirmada_por' => $alerta->usuario?->name,
|
||||||
|
'fecha_confirmacion' => $alerta->fecha_confirmacion
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marcar como vista
|
||||||
|
$alerta->visto = true;
|
||||||
|
$alerta->usuario_id = auth()->id(); // Usuario autenticado que confirmó
|
||||||
|
$alerta->fecha_confirmacion = now();
|
||||||
|
$alerta->save();
|
||||||
|
|
||||||
|
return ApiResponse::OK->response([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Alerta confirmada exitosamente',
|
||||||
|
'alerta' => $alerta
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
73
app/Models/AlertaRobo.php
Normal file
73
app/Models/AlertaRobo.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class AlertaRobo extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'alertas_robos';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'fast_id',
|
||||||
|
'vin',
|
||||||
|
'placa',
|
||||||
|
'marca',
|
||||||
|
'modelo',
|
||||||
|
'color',
|
||||||
|
'arco_id',
|
||||||
|
'arco_nombre',
|
||||||
|
'antena',
|
||||||
|
'fecha_deteccion',
|
||||||
|
'visto',
|
||||||
|
'usuario_id',
|
||||||
|
'fecha_confirmacion',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'visto' => 'boolean',
|
||||||
|
'fecha_deteccion' => 'datetime',
|
||||||
|
'fecha_confirmacion' => 'datetime',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relación con el arco
|
||||||
|
*/
|
||||||
|
public function arco(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Arco::class, 'arco_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relación con el usuario que confirmó
|
||||||
|
*/
|
||||||
|
public function usuario(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'usuario_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope para obtener alertas pendientes (no vistas)
|
||||||
|
*/
|
||||||
|
public function scopePendientes($query)
|
||||||
|
{
|
||||||
|
return $query->where('visto', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope para obtener alertas vistas
|
||||||
|
*/
|
||||||
|
public function scopeVistas($query)
|
||||||
|
{
|
||||||
|
return $query->where('visto', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope para ordenar por más reciente
|
||||||
|
*/
|
||||||
|
public function scopeRecientes($query)
|
||||||
|
{
|
||||||
|
return $query->orderBy('fecha_deteccion', 'desc');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\Models\Vehicle;
|
use App\Events\VehiculoRobadoDetectado;
|
||||||
|
use App\Models\AlertaRobo;
|
||||||
use App\Models\Detection;
|
use App\Models\Detection;
|
||||||
use App\Models\Arco;
|
use App\Models\Arco;
|
||||||
use Illuminate\Support\Facades\Redis;
|
use Illuminate\Support\Facades\Redis;
|
||||||
@ -27,7 +28,7 @@ public function procesarDeteccion(string $fastId, int $arcoId, ?string $antena =
|
|||||||
|
|
||||||
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), $arcoId, $antena);
|
||||||
$this->registrarDeteccion($fastId, $resultado, $arcoId, $antena);
|
$this->registrarDeteccion($fastId, $resultado, $arcoId, $antena);
|
||||||
return $resultado;
|
return $resultado;
|
||||||
}
|
}
|
||||||
@ -87,7 +88,6 @@ public function consultarVehiculoPorTag(string $fastId)
|
|||||||
'fast_id' => $fastId
|
'fast_id' => $fastId
|
||||||
]);
|
]);
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error('VehicleService: Error en consulta', [
|
Log::error('VehicleService: Error en consulta', [
|
||||||
'fast_id' => $fastId,
|
'fast_id' => $fastId,
|
||||||
@ -118,8 +118,6 @@ public function listarVehiculosRobados(): array
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Listar todas las detecciones del día desde Redis
|
* 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
|
public function listarDeteccionesDelDia(?string $fecha = null): array
|
||||||
{
|
{
|
||||||
@ -145,8 +143,6 @@ public function listarDeteccionesDelDia(?string $fecha = null): array
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtener estadísticas de detecciones del día
|
* 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
|
public function obtenerEstadisticasDelDia(?string $fecha = null): array
|
||||||
{
|
{
|
||||||
@ -245,19 +241,22 @@ private function consultarNuevoVehiculo(string $fastId): array
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verificar vehículo robado (ya está en Redis)
|
* Verificar vehículo robado (si ya está en Redis)
|
||||||
*/
|
*/
|
||||||
private function verificarVehiculoRobado(string $fastId, array $datosRedis): array
|
private function verificarVehiculoRobado(string $fastId, array $datosRedis, ?int $arcoId = null, ?string $antena = null): array
|
||||||
{
|
{
|
||||||
|
// Actualizar contador de detecciones
|
||||||
$this->actualizarDeteccionRedis($fastId, $datosRedis);
|
$this->actualizarDeteccionRedis($fastId, $datosRedis);
|
||||||
|
|
||||||
Log::warning('Vehículo robado detectado nuevamente', [
|
Log::warning('¡VEHÍCULO ROBADO DETECTADO!', [
|
||||||
'fast_id' => $fastId,
|
'fast_id' => $fastId,
|
||||||
'vin' => $datosRedis['vin'] ?? null,
|
'vin' => $datosRedis['vin'] ?? null,
|
||||||
'placa' => $datosRedis['placa'] ?? null,
|
'placa' => $datosRedis['placa'] ?? null
|
||||||
'detecciones' => ($datosRedis['detecciones'] ?? 0) + 1
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Crear alerta en la base de datos
|
||||||
|
$this->crearAlertaRobo($fastId, $datosRedis, $arcoId, $antena);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'tiene_reporte_robo' => true,
|
'tiene_reporte_robo' => true,
|
||||||
@ -267,6 +266,7 @@ private function verificarVehiculoRobado(string $fastId, array $datosRedis): arr
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actualizar contador de detecciones en Redis
|
* Actualizar contador de detecciones en Redis
|
||||||
*/
|
*/
|
||||||
@ -363,4 +363,38 @@ private function registrarDeteccionDelDia(string $fastId, array $vehiculo, ?int
|
|||||||
// Establecer expiración automática al final del día
|
// Establecer expiración automática al final del día
|
||||||
Redis::expire($key, $segundosHastaFinDelDia);
|
Redis::expire($key, $segundosHastaFinDelDia);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crear alerta de vehículo robado y disparar evento
|
||||||
|
*/
|
||||||
|
private function crearAlertaRobo(string $fastId, array $datosVehiculo, ?int $arcoId, ?string $antena): void
|
||||||
|
{
|
||||||
|
// Obtener nombre del arco
|
||||||
|
$arcoNombre = $arcoId ? Arco::find($arcoId)?->nombre : 'Desconocido';
|
||||||
|
|
||||||
|
// Crear alerta en la base de datos
|
||||||
|
$alerta = AlertaRobo::create([
|
||||||
|
'fast_id' => $fastId,
|
||||||
|
'vin' => $datosVehiculo['vin'] ?? null,
|
||||||
|
'placa' => $datosVehiculo['placa'] ?? null,
|
||||||
|
'marca' => $datosVehiculo['marca'] ?? null,
|
||||||
|
'modelo' => $datosVehiculo['modelo'] ?? null,
|
||||||
|
'color' => $datosVehiculo['color'] ?? null,
|
||||||
|
'arco_id' => $arcoId,
|
||||||
|
'arco_nombre' => $arcoNombre,
|
||||||
|
'antena' => $antena,
|
||||||
|
'fecha_deteccion' => now(),
|
||||||
|
'visto' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Disparar evento para Laravel Reverb (WebSocket)
|
||||||
|
event(new VehiculoRobadoDetectado($alerta));
|
||||||
|
|
||||||
|
Log::info('Alerta de vehículo robado creada y evento disparado', [
|
||||||
|
'alerta_id' => $alerta->id,
|
||||||
|
'fast_id' => $fastId,
|
||||||
|
'placa' => $alerta->placa,
|
||||||
|
'arco' => $arcoNombre
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/passport": "^12.4",
|
"laravel/passport": "^12.4",
|
||||||
"laravel/pulse": "^1.4",
|
"laravel/pulse": "^1.4",
|
||||||
"laravel/reverb": "^1.4",
|
"laravel/reverb": "^1.7",
|
||||||
"laravel/tinker": "^2.10",
|
"laravel/tinker": "^2.10",
|
||||||
"notsoweb/laravel-core": "dev-main",
|
"notsoweb/laravel-core": "dev-main",
|
||||||
"spatie/laravel-permission": "^6.16",
|
"spatie/laravel-permission": "^6.16",
|
||||||
|
|||||||
20
composer.lock
generated
20
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "0cdf26aa072a7f833793cfba72e94e81",
|
"content-hash": "2aee9315866597be53eadf5c315e8b69",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
@ -1855,16 +1855,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/reverb",
|
"name": "laravel/reverb",
|
||||||
"version": "v1.5.0",
|
"version": "v1.7.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/laravel/reverb.git",
|
"url": "https://github.com/laravel/reverb.git",
|
||||||
"reference": "bf84766ad35d9174fb508147f956e8bcf2e46e91"
|
"reference": "4300fbbc3535f5cbbdf600b00edca1e4c515bfcf"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/laravel/reverb/zipball/bf84766ad35d9174fb508147f956e8bcf2e46e91",
|
"url": "https://api.github.com/repos/laravel/reverb/zipball/4300fbbc3535f5cbbdf600b00edca1e4c515bfcf",
|
||||||
"reference": "bf84766ad35d9174fb508147f956e8bcf2e46e91",
|
"reference": "4300fbbc3535f5cbbdf600b00edca1e4c515bfcf",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -1884,8 +1884,8 @@
|
|||||||
"symfony/http-foundation": "^6.3|^7.0"
|
"symfony/http-foundation": "^6.3|^7.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"orchestra/testbench": "^8.0|^9.0|^10.0",
|
"orchestra/testbench": "^8.36|^9.15|^10.8",
|
||||||
"pestphp/pest": "^2.0|^3.0",
|
"pestphp/pest": "^2.0|^3.0|^4.0",
|
||||||
"phpstan/phpstan": "^1.10",
|
"phpstan/phpstan": "^1.10",
|
||||||
"ratchet/pawl": "^0.4.1",
|
"ratchet/pawl": "^0.4.1",
|
||||||
"react/async": "^4.2",
|
"react/async": "^4.2",
|
||||||
@ -1931,9 +1931,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/laravel/reverb/issues",
|
"issues": "https://github.com/laravel/reverb/issues",
|
||||||
"source": "https://github.com/laravel/reverb/tree/v1.5.0"
|
"source": "https://github.com/laravel/reverb/tree/v1.7.0"
|
||||||
},
|
},
|
||||||
"time": "2025-03-31T14:06:47+00:00"
|
"time": "2026-01-06T16:26:25+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/serializable-closure",
|
"name": "laravel/serializable-closure",
|
||||||
@ -10494,5 +10494,5 @@
|
|||||||
"php": "^8.3"
|
"php": "^8.3"
|
||||||
},
|
},
|
||||||
"platform-dev": {},
|
"platform-dev": {},
|
||||||
"plugin-api-version": "2.6.0"
|
"plugin-api-version": "2.9.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('alertas_robos', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('fast_id');
|
||||||
|
$table->string('vin')->nullable();
|
||||||
|
$table->string('placa')->nullable();
|
||||||
|
$table->string('marca')->nullable();
|
||||||
|
$table->string('modelo')->nullable();
|
||||||
|
$table->string('color')->nullable();
|
||||||
|
$table->unsignedBigInteger('arco_id');
|
||||||
|
$table->string('arco_nombre');
|
||||||
|
$table->string('antena')->nullable();
|
||||||
|
$table->timestamp('fecha_deteccion');
|
||||||
|
$table->boolean('visto')->default(false);
|
||||||
|
$table->unsignedBigInteger('usuario_id')->nullable();
|
||||||
|
$table->timestamp('fecha_confirmacion')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
// Índices para optimizar consultas
|
||||||
|
$table->index('visto');
|
||||||
|
$table->index('arco_id');
|
||||||
|
$table->index('fecha_deteccion');
|
||||||
|
|
||||||
|
// Foreign keys
|
||||||
|
$table->foreign('arco_id')->references('id')->on('arcos')->onDelete('cascade');
|
||||||
|
$table->foreign('usuario_id')->references('id')->on('users')->onDelete('set null');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('alertas_robos');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -13,6 +13,8 @@ services:
|
|||||||
- DB_PASSWORD=${DB_PASSWORD}
|
- DB_PASSWORD=${DB_PASSWORD}
|
||||||
- DB_DATABASE=${DB_DATABASE}
|
- DB_DATABASE=${DB_DATABASE}
|
||||||
- DB_PORT=${DB_PORT}
|
- DB_PORT=${DB_PORT}
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/var/www/arcos-backend
|
- ./:/var/www/arcos-backend
|
||||||
- ./vendor:/var/www/arcos/vendor
|
- ./vendor:/var/www/arcos/vendor
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\Api\AlertaRoboController;
|
||||||
|
use App\Http\Controllers\Api\PruebaReverbController;
|
||||||
use App\Http\Controllers\Api\VehicleController;
|
use App\Http\Controllers\Api\VehicleController;
|
||||||
use App\Http\Controllers\Api\ArcoController;
|
use App\Http\Controllers\Api\ArcoController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
@ -40,6 +42,13 @@
|
|||||||
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']);
|
Route::get('/arcos/{id}/detecciones/dia', [ArcoController::class, 'deteccionesDelDia']);
|
||||||
|
|
||||||
|
//alerta
|
||||||
|
Route::get('/alertas', [AlertaRoboController::class, 'index']);
|
||||||
|
Route::get('/alertas/{id}', [AlertaRoboController::class, 'show']);
|
||||||
|
Route::get('/alertas/pendientes', [AlertaRoboController::class, 'pendientes']);
|
||||||
|
Route::put('/alertas/{id}/confirmar', [AlertaRoboController::class, 'confirmar']);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Rutas públicas */
|
/** Rutas públicas */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user