referencias añadidas reparada forma de topologia

This commit is contained in:
Abraham
2025-07-30 22:29:28 -07:00
parent 730754930d
commit 8bbe7a53ff
16 changed files with 1959 additions and 4188 deletions

View File

@@ -11,6 +11,8 @@ class Componente {
final String? ubicacion;
final String? imagenUrl;
final DateTime fechaRegistro;
final String? distribucionId; // ← Nuevo (si lo usas)
final String? rolLogicoId; // ← NUEVO
Componente({
required this.id,
@@ -23,7 +25,8 @@ class Componente {
this.ubicacion,
this.imagenUrl,
required this.fechaRegistro,
String? distribucionId,
this.distribucionId,
this.rolLogicoId,
});
factory Componente.fromMap(Map<String, dynamic> map) {
@@ -38,6 +41,8 @@ class Componente {
ubicacion: map['ubicacion'],
imagenUrl: map['imagen_url'],
fechaRegistro: DateTime.parse(map['fecha_registro']),
distribucionId: map['distribucion_id'],
rolLogicoId: map['rol_logico_id'],
);
}
@@ -53,10 +58,13 @@ class Componente {
'ubicacion': ubicacion,
'imagen_url': imagenUrl,
'fecha_registro': fechaRegistro.toIso8601String(),
'distribucion_id': distribucionId,
'rol_logico_id': rolLogicoId,
};
}
factory Componente.fromJson(String source) =>
Componente.fromMap(json.decode(source));
String toJson() => json.encode(toMap());
}

View File

@@ -0,0 +1,39 @@
class ConexionAlimentacion {
final String id;
final String origenId;
final String destinoId;
final String? cableId;
final String? descripcion;
final bool activo;
ConexionAlimentacion({
required this.id,
required this.origenId,
required this.destinoId,
this.cableId,
this.descripcion,
required this.activo,
});
factory ConexionAlimentacion.fromMap(Map<String, dynamic> map) {
return ConexionAlimentacion(
id: map['id'] ?? '',
origenId: map['origen_id'] ?? '',
destinoId: map['destino_id'] ?? '',
cableId: map['cable_id'],
descripcion: map['descripcion'],
activo: map['activo'] ?? false,
);
}
Map<String, dynamic> toMap() {
return {
'id': id,
'origen_id': origenId,
'destino_id': destinoId,
'cable_id': cableId,
'descripcion': descripcion,
'activo': activo,
};
}
}

View File

@@ -0,0 +1,58 @@
class RolLogicoComponente {
final int id;
final String nombre;
final String? descripcion;
RolLogicoComponente({
required this.id,
required this.nombre,
this.descripcion,
});
factory RolLogicoComponente.fromMap(Map<String, dynamic> map) {
return RolLogicoComponente(
id: map['id'] ?? 0,
nombre: map['nombre'] ?? '',
descripcion: map['descripcion'],
);
}
Map<String, dynamic> toMap() {
return {
'id': id,
'nombre': nombre,
'descripcion': descripcion,
};
}
RolLogicoComponente copyWith({
int? id,
String? nombre,
String? descripcion,
}) {
return RolLogicoComponente(
id: id ?? this.id,
nombre: nombre ?? this.nombre,
descripcion: descripcion ?? this.descripcion,
);
}
@override
String toString() {
return 'RolLogicoComponente(id: $id, nombre: $nombre, descripcion: $descripcion)';
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is RolLogicoComponente &&
other.id == id &&
other.nombre == nombre &&
other.descripcion == descripcion;
}
@override
int get hashCode {
return id.hashCode ^ nombre.hashCode ^ descripcion.hashCode;
}
}

View File

@@ -0,0 +1,51 @@
class TipoDistribucion {
final int id;
final String nombre;
TipoDistribucion({
required this.id,
required this.nombre,
});
factory TipoDistribucion.fromMap(Map<String, dynamic> map) {
return TipoDistribucion(
id: map['id'] ?? 0,
nombre: map['nombre'] ?? '',
);
}
Map<String, dynamic> toMap() {
return {
'id': id,
'nombre': nombre,
};
}
TipoDistribucion copyWith({
int? id,
String? nombre,
}) {
return TipoDistribucion(
id: id ?? this.id,
nombre: nombre ?? this.nombre,
);
}
@override
String toString() {
return 'TipoDistribucion(id: $id, nombre: $nombre)';
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is TipoDistribucion &&
other.id == id &&
other.nombre == nombre;
}
@override
int get hashCode {
return id.hashCode ^ nombre.hashCode;
}
}

View File

@@ -0,0 +1,199 @@
import 'package:nethive_neo/models/nethive/componente_model.dart';
import 'package:nethive_neo/models/nethive/conexion_componente_model.dart';
import 'package:nethive_neo/models/nethive/conexion_alimentacion_model.dart';
class TopologiaCompleta {
final List<ComponenteTopologia> componentes;
final List<ConexionDatos> conexionesDatos;
final List<ConexionEnergia> conexionesEnergia;
TopologiaCompleta({
required this.componentes,
required this.conexionesDatos,
required this.conexionesEnergia,
});
factory TopologiaCompleta.fromJson(Map<String, dynamic> json) {
return TopologiaCompleta(
componentes: (json['componentes'] as List<dynamic>? ?? [])
.map((c) => ComponenteTopologia.fromMap(c))
.toList(),
conexionesDatos: (json['conexiones_datos'] as List<dynamic>? ?? [])
.map((cd) => ConexionDatos.fromMap(cd))
.toList(),
conexionesEnergia: (json['conexiones_energia'] as List<dynamic>? ?? [])
.map((ce) => ConexionEnergia.fromMap(ce))
.toList(),
);
}
}
class ComponenteTopologia {
final String id;
final String nombre;
final int categoriaId;
final String categoria;
final String? descripcion;
final String? ubicacion;
final String? imagenUrl;
final bool enUso;
final bool activo;
final DateTime fechaRegistro;
final String? distribucionId;
final String? tipoDistribucion;
final String? nombreDistribucion;
ComponenteTopologia({
required this.id,
required this.nombre,
required this.categoriaId,
required this.categoria,
this.descripcion,
this.ubicacion,
this.imagenUrl,
required this.enUso,
required this.activo,
required this.fechaRegistro,
this.distribucionId,
this.tipoDistribucion,
this.nombreDistribucion,
});
factory ComponenteTopologia.fromMap(Map<String, dynamic> map) {
return ComponenteTopologia(
id: map['id'] ?? '',
nombre: map['nombre'] ?? '',
categoriaId: map['categoria_id'] ?? 0,
categoria: map['categoria'] ?? '',
descripcion: map['descripcion'],
ubicacion: map['ubicacion'],
imagenUrl: map['imagen_url'],
enUso: map['en_uso'] ?? false,
activo: map['activo'] ?? false,
fechaRegistro:
DateTime.tryParse(map['fecha_registro']?.toString() ?? '') ??
DateTime.now(),
distribucionId: map['distribucion_id'],
tipoDistribucion: map['tipo_distribucion'],
nombreDistribucion: map['nombre_distribucion'],
);
}
// Métodos de utilidad para topología
bool get esMDF =>
tipoDistribucion?.toLowerCase() == 'mdf' ||
ubicacion?.toLowerCase().contains('mdf') == true ||
categoria.toLowerCase().contains('mdf');
bool get esIDF =>
tipoDistribucion?.toLowerCase() == 'idf' ||
ubicacion?.toLowerCase().contains('idf') == true ||
categoria.toLowerCase().contains('idf');
bool get esSwitch => categoria.toLowerCase().contains('switch');
bool get esRouter =>
categoria.toLowerCase().contains('router') ||
categoria.toLowerCase().contains('firewall');
bool get esServidor =>
categoria.toLowerCase().contains('servidor') ||
categoria.toLowerCase().contains('server');
bool get esUPS => categoria.toLowerCase().contains('ups');
bool get esRack => categoria.toLowerCase().contains('rack');
bool get esPatchPanel =>
categoria.toLowerCase().contains('patch') ||
categoria.toLowerCase().contains('panel');
// Prioridad para ordenamiento en topología
int get prioridadTopologia {
if (esMDF) return 1;
if (esIDF) return 2;
if (esSwitch) return 3;
if (esRouter) return 4;
if (esServidor) return 5;
if (esUPS) return 6;
if (esRack) return 7;
if (esPatchPanel) return 8;
return 9;
}
}
class ConexionDatos {
final String id;
final String componenteOrigenId;
final String nombreOrigen;
final String componenteDestinoId;
final String nombreDestino;
final String? cableId;
final String? nombreCable;
final String? descripcion;
final bool activo;
ConexionDatos({
required this.id,
required this.componenteOrigenId,
required this.nombreOrigen,
required this.componenteDestinoId,
required this.nombreDestino,
this.cableId,
this.nombreCable,
this.descripcion,
required this.activo,
});
factory ConexionDatos.fromMap(Map<String, dynamic> map) {
return ConexionDatos(
id: map['id'] ?? '',
componenteOrigenId: map['componente_origen_id'] ?? '',
nombreOrigen: map['nombre_origen'] ?? '',
componenteDestinoId: map['componente_destino_id'] ?? '',
nombreDestino: map['nombre_destino'] ?? '',
cableId: map['cable_id'],
nombreCable: map['nombre_cable'],
descripcion: map['descripcion'],
activo: map['activo'] ?? false,
);
}
}
class ConexionEnergia {
final String id;
final String origenId;
final String nombreOrigen;
final String destinoId;
final String nombreDestino;
final String? cableId;
final String? nombreCable;
final String? descripcion;
final bool activo;
ConexionEnergia({
required this.id,
required this.origenId,
required this.nombreOrigen,
required this.destinoId,
required this.nombreDestino,
this.cableId,
this.nombreCable,
this.descripcion,
required this.activo,
});
factory ConexionEnergia.fromMap(Map<String, dynamic> map) {
return ConexionEnergia(
id: map['id'] ?? '',
origenId: map['origen_id'] ?? '',
nombreOrigen: map['nombre_origen'] ?? '',
destinoId: map['destino_id'] ?? '',
nombreDestino: map['nombre_destino'] ?? '',
cableId: map['cable_id'],
nombreCable: map['nombre_cable'],
descripcion: map['descripcion'],
activo: map['activo'] ?? false,
);
}
}

View File

@@ -10,6 +10,8 @@ class VistaTopologiaPorNegocio {
final String componenteNombre;
final String? descripcion;
final String categoriaComponente;
final int? rolLogicoId;
final String? rolLogico;
final bool enUso;
final bool activo;
final String? ubicacion;
@@ -26,6 +28,8 @@ class VistaTopologiaPorNegocio {
required this.componenteNombre,
this.descripcion,
required this.categoriaComponente,
this.rolLogicoId,
this.rolLogico,
required this.enUso,
required this.activo,
this.ubicacion,
@@ -35,29 +39,30 @@ class VistaTopologiaPorNegocio {
factory VistaTopologiaPorNegocio.fromMap(Map<String, dynamic> map) {
return VistaTopologiaPorNegocio(
negocioId: map['negocio_id']?.toString() ?? '',
nombreNegocio: map['nombre_negocio']?.toString() ?? '',
distribucionId: map['distribucion_id']?.toString(),
tipoDistribucion: map['tipo_distribucion']?.toString(),
distribucionNombre: map['distribucion_nombre']?.toString(),
componenteId: map['componente_id']?.toString() ?? '',
componenteNombre: map['componente_nombre']?.toString() ?? '',
descripcion: map['descripcion']?.toString(),
categoriaComponente: map['categoria_componente']?.toString() ?? '',
negocioId: map['negocio_id'] ?? '',
nombreNegocio: map['negocio_nombre'] ?? '',
distribucionId: map['distribucion_id'],
tipoDistribucion: map['tipo_distribucion'],
distribucionNombre: map['distribucion_nombre'],
componenteId: map['componente_id'] ?? '',
componenteNombre: map['componente_nombre'] ?? '',
descripcion: map['descripcion'],
categoriaComponente: map['categoria_componente'] ?? '',
rolLogicoId: map['rol_logico_id'],
rolLogico: map['rol_logico'],
enUso: map['en_uso'] == true,
activo: map['activo'] == true,
ubicacion: map['ubicacion']?.toString(),
imagenUrl: map['imagen_url']?.toString(),
ubicacion: map['ubicacion'],
imagenUrl: map['imagen_url'],
fechaRegistro:
DateTime.tryParse(map['fecha_registro']?.toString() ?? '') ??
DateTime.now(),
DateTime.tryParse(map['fecha_registro'] ?? '') ?? DateTime.now(),
);
}
Map<String, dynamic> toMap() {
return {
'negocio_id': negocioId,
'nombre_negocio': nombreNegocio,
'negocio_nombre': nombreNegocio,
'distribucion_id': distribucionId,
'tipo_distribucion': tipoDistribucion,
'distribucion_nombre': distribucionNombre,
@@ -65,6 +70,8 @@ class VistaTopologiaPorNegocio {
'componente_nombre': componenteNombre,
'descripcion': descripcion,
'categoria_componente': categoriaComponente,
'rol_logico_id': rolLogicoId,
'rol_logico': rolLogico,
'en_uso': enUso,
'activo': activo,
'ubicacion': ubicacion,
@@ -78,20 +85,36 @@ class VistaTopologiaPorNegocio {
String toJson() => json.encode(toMap());
// Método para obtener el tipo de componente principal basado en IDs
bool get esMDF => tipoDistribucion?.toUpperCase() == 'MDF';
bool get esIDF => tipoDistribucion?.toUpperCase() == 'IDF';
String get tipoComponentePrincipal {
final categoria = categoriaComponente.toLowerCase();
final nombre = componenteNombre.toLowerCase();
final desc = descripcion?.toLowerCase() ?? '';
// Clasificación basada en los nombres de categorías exactos
if (nombre.contains('switch') || desc.contains('switch')) return 'switch';
if (nombre.contains('router') ||
desc.contains('router') ||
nombre.contains('firewall') ||
desc.contains('firewall') ||
nombre.contains('fortigate') ||
(nombre.contains('cisco') &&
(nombre.contains('asa') || nombre.contains('pix')))) {
return 'router';
}
if (nombre.contains('servidor') ||
nombre.contains('server') ||
desc.contains('servidor') ||
desc.contains('server')) {
return 'servidor';
}
if (categoria == 'cable') return 'cable';
if (categoria == 'switch') return 'switch';
if (categoria == 'patch panel') return 'patch_panel';
if (categoria == 'rack') return 'rack';
if (categoria == 'ups') return 'ups';
if (categoria == 'mdf') return 'mdf';
if (categoria == 'idf') return 'idf';
if (categoria.contains('organizador')) return 'organizador';
// Clasificación por contenido para compatibilidad
if (categoria.contains('switch')) return 'switch';
if (categoria.contains('router') || categoria.contains('firewall'))
return 'router';
@@ -102,32 +125,13 @@ class VistaTopologiaPorNegocio {
return 'patch_panel';
if (categoria.contains('rack')) return 'rack';
if (categoria.contains('ups')) return 'ups';
if (categoria.contains('organizador')) return 'organizador';
return 'otro';
}
// Método mejorado para determinar si es MDF
bool get esMDF {
final categoria = categoriaComponente.toLowerCase();
return categoria == 'mdf' ||
tipoDistribucion?.toUpperCase() == 'MDF' ||
ubicacion?.toLowerCase().contains('mdf') == true;
}
// Método mejorado para determinar si es IDF
bool get esIDF {
final categoria = categoriaComponente.toLowerCase();
return categoria == 'idf' ||
tipoDistribucion?.toUpperCase() == 'IDF' ||
ubicacion?.toLowerCase().contains('idf') == true;
}
// Método para obtener el nivel de prioridad del componente (para ordenamiento en topología)
int get prioridadTopologia {
if (esMDF) return 1; // Máxima prioridad para MDF
if (esIDF) return 2; // Segunda prioridad para IDF
if (esMDF) return 1;
if (esIDF) return 2;
switch (tipoComponentePrincipal) {
case 'router':
return 3;
@@ -150,32 +154,26 @@ class VistaTopologiaPorNegocio {
}
}
// Método para determinar el color del componente en el diagrama
String getColorForDiagram() {
if (esMDF) return '#2196F3'; // Azul para MDF
if (esIDF) {
return enUso
? '#4CAF50'
: '#FF9800'; // Verde si está en uso, naranja si no
}
if (esMDF) return '#2196F3';
if (esIDF) return enUso ? '#4CAF50' : '#FF9800';
switch (tipoComponentePrincipal) {
case 'router':
return '#FF5722'; // Naranja rojizo
return '#FF5722';
case 'switch':
return '#9C27B0'; // Morado
return '#9C27B0';
case 'servidor':
return '#E91E63'; // Rosa
return '#E91E63';
case 'patch_panel':
return '#607D8B'; // Azul gris
return '#607D8B';
case 'rack':
return '#795548'; // Marrón
return '#795548';
case 'ups':
return '#FFC107'; // Ámbar
return '#FFC107';
case 'cable':
return '#4CAF50'; // Verde
return '#4CAF50';
case 'organizador':
return '#9E9E9E'; // Gris
return '#9E9E9E';
default:
return activo ? '#2196F3' : '#757575';
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff