Commit 0bafc88763a6c36356b26672ace0e458407ff30b

Authored by Antigravity AI
1 parent a3050e01

Hito: Estadísticas Reales y Actualización Forzada de FDW (.123)

VERSION.txt
@@ -10,3 +10,4 @@ PROYECTO GIS-GEOSERVER - 2026.04.06.12.44.00 ID DOCKER: d983a409769d. Observacià @@ -10,3 +10,4 @@ PROYECTO GIS-GEOSERVER - 2026.04.06.12.44.00 ID DOCKER: d983a409769d. ObservaciÃ
10 PROYECTO GIS-GEOSERVER - 2026.04.06.13.31.00 ID DOCKER: d983a409769d. Observación: Prueba de funcionamiento del Manual v1.1 tras estandarización de prefijos y manual de recuperación. 10 PROYECTO GIS-GEOSERVER - 2026.04.06.13.31.00 ID DOCKER: d983a409769d. Observación: Prueba de funcionamiento del Manual v1.1 tras estandarización de prefijos y manual de recuperación.
11 PROYECTO GIS-GEOSERVER - 2026.04.07.08.18.07 ID DOCKER: d983a409769d. Observación: Optimización visual de interfaz completada: unificación de anchos al 100%, limpieza de barra superior, traslado de controles al sidebar y registro legal SIGEM-MIC/DINAPI. 11 PROYECTO GIS-GEOSERVER - 2026.04.07.08.18.07 ID DOCKER: d983a409769d. Observación: Optimización visual de interfaz completada: unificación de anchos al 100%, limpieza de barra superior, traslado de controles al sidebar y registro legal SIGEM-MIC/DINAPI.
12 PROYECTO GIS-GEOSERVER - 2026.04.07.20.37.47 ID DOCKER: d983a409769d. Observación: Modernización definitiva del Dashboard completada: Replicación de bloque de bienvenida legado, integración de mapa embebido en modo limpio y reestructuración de la fila inferior de gestión al 100% de ancho. Versión estable validada.Version SIG (Abril 2026) - 2026.04.07.22.30.00 ID DOCKER: d983a409769d. Observación: Éxito en implementación de Login Dinámico (SaaS), integración de logos binarios, eslóganes y responsables desde el servidor .254. 12 PROYECTO GIS-GEOSERVER - 2026.04.07.20.37.47 ID DOCKER: d983a409769d. Observación: Modernización definitiva del Dashboard completada: Replicación de bloque de bienvenida legado, integración de mapa embebido en modo limpio y reestructuración de la fila inferior de gestión al 100% de ancho. Versión estable validada.Version SIG (Abril 2026) - 2026.04.07.22.30.00 ID DOCKER: d983a409769d. Observación: Éxito en implementación de Login Dinámico (SaaS), integración de logos binarios, eslóganes y responsables desde el servidor .254.
  13 +Version SIG (Abril 2026) - 2026.04.07.23.35.00 ID DOCKER: cb7329596324. Observación: Éxito en la implementación de Estadísticas Reales (formato vertical fdw_X.estadisticas_datos) y actualización forzada de FDW desde el menú Administración.
src/main/java/com/sigem/gis/controller/AdminController.java
@@ -20,7 +20,7 @@ public class AdminController { @@ -20,7 +20,7 @@ public class AdminController {
20 Map<String, Object> response = new HashMap<>(); 20 Map<String, Object> response = new HashMap<>();
21 try { 21 try {
22 System.out.println("Solicitud de actualización FDW recibida para Entidad: " + entidadId); 22 System.out.println("Solicitud de actualización FDW recibida para Entidad: " + entidadId);
23 - fdwService.setupFdw(entidadId); 23 + fdwService.setupFdw(entidadId, true);
24 24
25 response.put("success", true); 25 response.put("success", true);
26 response.put("message", "Datos del municipio " + entidadId + " actualizados con éxito (FDW y Geometrías vinculadas)."); 26 response.put("message", "Datos del municipio " + entidadId + " actualizados con éxito (FDW y Geometrías vinculadas).");
src/main/java/com/sigem/gis/controller/GisController.java
@@ -88,4 +88,17 @@ public class GisController { @@ -88,4 +88,17 @@ public class GisController {
88 return ResponseEntity.status(500).body(Map.of("error", e.getMessage())); 88 return ResponseEntity.status(500).body(Map.of("error", e.getMessage()));
89 } 89 }
90 } 90 }
  91 + @GetMapping("/entidad/{id}/estadisticas")
  92 + public ResponseEntity<?> getEstadisticas(@PathVariable String id) {
  93 + try {
  94 + String schemaName = "fdw_" + id;
  95 + String sql = "SELECT descripcion, valor FROM " + schemaName + ".estadisticas_datos";
  96 + List<Map<String, Object>> results = gisJdbcTemplate.queryForList(sql);
  97 +
  98 + return ResponseEntity.ok(results);
  99 + } catch (Exception e) {
  100 + e.printStackTrace();
  101 + return ResponseEntity.status(500).body(Map.of("error", e.getMessage()));
  102 + }
  103 + }
91 } 104 }
src/main/java/com/sigem/gis/security/AuthController.java
@@ -64,7 +64,7 @@ public class AuthController { @@ -64,7 +64,7 @@ public class AuthController {
64 String responsable = convertObjectToString(entidadData.get("responsable")); 64 String responsable = convertObjectToString(entidadData.get("responsable"));
65 65
66 // 2. Asegurar Infraestructura FDW (Regla 16: Solo crea si no existe) 66 // 2. Asegurar Infraestructura FDW (Regla 16: Solo crea si no existe)
67 - fdwService.setupFdw(request.getEntidad()); 67 + fdwService.setupFdw(request.getEntidad(), false);
68 String schemaName = "fdw_" + request.getEntidad(); 68 String schemaName = "fdw_" + request.getEntidad();
69 69
70 System.out.println("Validando usuario vía FDW local para entidad: " + request.getEntidad()); 70 System.out.println("Validando usuario vía FDW local para entidad: " + request.getEntidad());
src/main/java/com/sigem/gis/service/FdwService.java
@@ -22,7 +22,7 @@ public class FdwService { @@ -22,7 +22,7 @@ public class FdwService {
22 @Qualifier("gisJdbcTemplate") 22 @Qualifier("gisJdbcTemplate")
23 private JdbcTemplate gisJdbcTemplate; 23 private JdbcTemplate gisJdbcTemplate;
24 24
25 - public void setupFdw(String entidadId) { 25 + public void setupFdw(String entidadId, boolean forceUpdate) {
26 // 1. Obtener datos de la entidad desde el Directorio Maestro (.254) 26 // 1. Obtener datos de la entidad desde el Directorio Maestro (.254)
27 String sqlEntidad = "SELECT sigem_site, sigem_dbname, boundno, boundse, latlong, zoom, maxzoom, minzoom " + 27 String sqlEntidad = "SELECT sigem_site, sigem_dbname, boundno, boundse, latlong, zoom, maxzoom, minzoom " +
28 "FROM public.entidades WHERE entidad = ?"; 28 "FROM public.entidades WHERE entidad = ?";
@@ -56,9 +56,9 @@ public class FdwService { @@ -56,9 +56,9 @@ public class FdwService {
56 // ... (verificación de infraestructura fdw igual hasta la creación de vistas) 56 // ... (verificación de infraestructura fdw igual hasta la creación de vistas)
57 // ... 57 // ...
58 String checkSql = "SELECT count(*) FROM information_schema.tables WHERE table_schema = ? AND table_name = 'usuarios'"; 58 String checkSql = "SELECT count(*) FROM information_schema.tables WHERE table_schema = ? AND table_name = 'usuarios'";
59 - Integer count = gisJdbcTemplate.queryForObject(checkSql, Integer.class, schemaName);  
60 -  
61 - if (count == null || count == 0) { 59 + Integer count = (forceUpdate) ? 0 : gisJdbcTemplate.queryForObject(checkSql, Integer.class, schemaName);
  60 +
  61 + if (forceUpdate || count == null || count == 0) {
62 // (creación de server, user mapping y esquema igual) 62 // (creación de server, user mapping y esquema igual)
63 gisJdbcTemplate.execute("DROP SERVER IF EXISTS " + serverName + " CASCADE"); 63 gisJdbcTemplate.execute("DROP SERVER IF EXISTS " + serverName + " CASCADE");
64 gisJdbcTemplate.execute(String.format( 64 gisJdbcTemplate.execute(String.format(
@@ -69,7 +69,7 @@ public class FdwService { @@ -69,7 +69,7 @@ public class FdwService {
69 serverName, user, pass)); 69 serverName, user, pass));
70 gisJdbcTemplate.execute("CREATE SCHEMA IF NOT EXISTS " + schemaName); 70 gisJdbcTemplate.execute("CREATE SCHEMA IF NOT EXISTS " + schemaName);
71 gisJdbcTemplate.execute(String.format( 71 gisJdbcTemplate.execute(String.format(
72 - "IMPORT FOREIGN SCHEMA public LIMIT TO (v_liq_entidad_totalxobjeto, v_liq_entidad_percentiles, usuarios, ventanas_usuario) FROM SERVER %s INTO %s", 72 + "IMPORT FOREIGN SCHEMA public LIMIT TO (v_liq_entidad_totalxobjeto, v_liq_entidad_percentiles, usuarios, ventanas_usuario, estadisticas_datos) FROM SERVER %s INTO %s",
73 serverName, schemaName)); 73 serverName, schemaName));
74 } 74 }
75 75
src/main/resources/static/widgets.html
@@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
12 <style> 12 <style>
13 body { background-color: #f4f6f9; padding: 20px; font-family: 'Source Sans Pro', sans-serif; } 13 body { background-color: #f4f6f9; padding: 20px; font-family: 'Source Sans Pro', sans-serif; }
14 .welcome-header { font-size: 24px; color: #333; margin-bottom: 20px; font-weight: 600;} 14 .welcome-header { font-size: 24px; color: #333; margin-bottom: 20px; font-weight: 600;}
  15 + .info-box-text { font-size: 11px; font-weight: 600; text-transform: uppercase; }
15 /* Estilos para el mapa embebido */ 16 /* Estilos para el mapa embebido */
16 .map-container { 17 .map-container {
17 width: 100%; 18 width: 100%;
@@ -30,7 +31,7 @@ @@ -30,7 +31,7 @@
30 </head> 31 </head>
31 <body> 32 <body>
32 <div class="welcome-header"> 33 <div class="welcome-header">
33 - <i class="fas fa-home text-primary"></i> Tablero General (Estadísticas Simuladas) 34 + Tablero General
34 </div> 35 </div>
35 36
36 <!-- FILA 1: INFO BOXES ESTILO LEGADO (ESTADÍSTICAS) --> 37 <!-- FILA 1: INFO BOXES ESTILO LEGADO (ESTADÍSTICAS) -->
@@ -201,10 +202,33 @@ @@ -201,10 +202,33 @@
201 <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script> 202 <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
202 <script> 203 <script>
203 // Dinamizar el título con el nombre de la entidad si está disponible 204 // Dinamizar el título con el nombre de la entidad si está disponible
  205 + const entidadId = localStorage.getItem('entidad');
204 const entidadNombre = localStorage.getItem('entidad_nombre'); 206 const entidadNombre = localStorage.getItem('entidad_nombre');
  207 +
205 if (entidadNombre && entidadNombre !== 'null') { 208 if (entidadNombre && entidadNombre !== 'null') {
206 document.getElementById('welcome-title').innerHTML = `<i class="fas fa-map mr-1"></i> Bienvenido al Sistema Integrado de Gestión Municipal de ${entidadNombre}`; 209 document.getElementById('welcome-title').innerHTML = `<i class="fas fa-map mr-1"></i> Bienvenido al Sistema Integrado de Gestión Municipal de ${entidadNombre}`;
207 } 210 }
  211 +
  212 + // Cargar estadísticas reales
  213 + if (entidadId) {
  214 + fetch(`/gis-geoserver/api/gis/entidad/${entidadId}/estadisticas`)
  215 + .then(response => response.json())
  216 + .then(list => {
  217 + if (list && Array.isArray(list)) {
  218 + list.forEach(item => {
  219 + const desc = (item.descripcion || "").toUpperCase();
  220 + const val = Number(item.valor || 0).toLocaleString();
  221 +
  222 + if (desc.includes("CONTRIBUYENTE")) document.getElementById('contribnum').innerText = val;
  223 + if (desc.includes("PROPIEDAD")) document.getElementById('propnum').innerText = val;
  224 + if (desc.includes("COMERCIO")) document.getElementById('comnum').innerText = val;
  225 + if (desc.includes("VEHICULO")) document.getElementById('vehinum').innerText = val;
  226 + if (desc.includes("LICENCIA")) document.getElementById('licennum').innerText = val;
  227 + });
  228 + }
  229 + })
  230 + .catch(err => console.error("Error cargando estadísticas:", err));
  231 + }
208 </script> 232 </script>
209 </body> 233 </body>
210 </html> 234 </html>
GitLab Appliance - Powered by TurnKey Linux