grales
This commit is contained in:
@@ -121,6 +121,25 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Nueva card para Ventanilla Única -->
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card h-100 card-hover">
|
||||
<div class="card-body text-center">
|
||||
<div class="security-icon mb-3">
|
||||
<i class="fas fa-university text-warning"></i>
|
||||
</div>
|
||||
<h5 class="card-title">Ventanilla Única</h5>
|
||||
<p class="card-text text-muted">
|
||||
Configurar ejecutable y certificados para transmisiones de Manifestación de Valor Electrónica
|
||||
</p>
|
||||
<a href="/IMPORTADORES/seguridad/ventanillaUnica" class="btn btn-outline-warning btn-animated">
|
||||
<i class="fas fa-cogs me-2"></i>Configurar VU
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
349
views/seguridad/ventanilla_unica.php
Normal file
349
views/seguridad/ventanilla_unica.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php include __DIR__ . '/../partials/sidebar_configuracion.php'; ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🔐 Configuración Ventanilla Única</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
<style>
|
||||
body { font-family: 'Segoe UI', sans-serif; background-color: #f4f6f9; }
|
||||
.sidebar { width: 220px; height: 100vh; background-color: #343a40; position: fixed; top: 0; left: 0; padding-top: 56px; z-index: 1040; }
|
||||
.sidebar .nav-link { font-weight: bold; color: white; transition: all 0.3s ease; }
|
||||
.sidebar .nav-link:hover, .sidebar .nav-link.active { background-color: #495057; color: #fff; }
|
||||
.content { margin-top: 56px; padding: 40px 20px; position: relative; z-index: 1; background-color: #f4f6f9; transition: margin-left 0.3s ease; }
|
||||
@media (min-width: 768px) { .content { margin-left: 250px; } }
|
||||
@media (max-width: 767.98px) {
|
||||
.content { margin-left: 0; }
|
||||
.sidebar .nav-link { font-weight: normal; color: #343a40; background-color: transparent; }
|
||||
.sidebar .nav-link:hover, .sidebar .nav-link.active { background-color: #e9ecef; color: #212529; }
|
||||
}
|
||||
.card { border-radius: 12px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); }
|
||||
.btn-animated { transition: all 0.3s ease; }
|
||||
.btn-animated:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); }
|
||||
.form-floating { position: relative; }
|
||||
.form-floating > .form-control:focus ~ label { color: #0d6efd; }
|
||||
.security-header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
|
||||
.status-indicator { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); }
|
||||
.path-input { font-family: 'Courier New', monospace; font-size: 0.9em; }
|
||||
.config-section { border-left: 4px solid #0d6efd; padding-left: 20px; margin-bottom: 30px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<!-- Header -->
|
||||
<div class="security-header text-white p-4 rounded-3 mb-4">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h4 class="mb-1"><i class="fas fa-university me-2"></i>Configuración Ventanilla Única</h4>
|
||||
<p class="mb-0 opacity-75">Configuración para transmisiones de Manifestación de Valor Electrónica</p>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<a href="/IMPORTADORES/seguridad/index" class="btn btn-light btn-sm">
|
||||
<i class="fas fa-arrow-left me-1"></i>Regresar a Seguridad
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mensajes de éxito/error -->
|
||||
<?php if (isset($_SESSION['config_success'])): ?>
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
<i class="fas fa-check-circle me-2"></i>
|
||||
<?= htmlspecialchars($_SESSION['config_success']) ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
<?php unset($_SESSION['config_success']); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_SESSION['config_error'])): ?>
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
<i class="fas fa-exclamation-triangle me-2"></i>
|
||||
<?= htmlspecialchars($_SESSION['config_error']) ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
<?php unset($_SESSION['config_error']); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="mb-0"><i class="fas fa-cogs me-2"></i>Configuración de Ventanilla Única</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="/IMPORTADORES/seguridad/guardarConfiguracionVU" method="POST" id="configForm" enctype="multipart/form-data">
|
||||
|
||||
<!-- Sección 1: Certificados FIEL -->
|
||||
<div class="config-section">
|
||||
<h6 class="text-success mb-3">
|
||||
<i class="fas fa-certificate me-2"></i>Certificados FIEL
|
||||
</h6>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="archivo_key" class="form-label">
|
||||
<i class="fas fa-key me-1"></i>Archivo KEY *
|
||||
</label>
|
||||
<input type="file"
|
||||
class="form-control"
|
||||
id="archivo_key"
|
||||
name="archivo_key"
|
||||
accept=".key"
|
||||
<?= empty($configuracion_vu['ruta_archivo_key']) ? 'required' : '' ?>>
|
||||
<?php if (!empty($configuracion_vu['ruta_archivo_key'])): ?>
|
||||
<div class="mt-2 p-2 bg-light rounded">
|
||||
<small class="text-success">
|
||||
<i class="fas fa-check me-1"></i>
|
||||
Archivo actual: <?= basename($configuracion_vu['ruta_archivo_key']) ?>
|
||||
</small>
|
||||
<input type="hidden" name="ruta_archivo_key_actual" value="<?= htmlspecialchars($configuracion_vu['ruta_archivo_key']) ?>">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<small class="text-muted d-block mt-1">
|
||||
Solo archivos .key permitidos
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="archivo_cer" class="form-label">
|
||||
<i class="fas fa-certificate me-1"></i>Archivo CER *
|
||||
</label>
|
||||
<input type="file"
|
||||
class="form-control"
|
||||
id="archivo_cer"
|
||||
name="archivo_cer"
|
||||
accept=".cer"
|
||||
<?= empty($configuracion_vu['ruta_archivo_cer']) ? 'required' : '' ?>>
|
||||
<?php if (!empty($configuracion_vu['ruta_archivo_cer'])): ?>
|
||||
<div class="mt-2 p-2 bg-light rounded">
|
||||
<small class="text-success">
|
||||
<i class="fas fa-check me-1"></i>
|
||||
Archivo actual: <?= basename($configuracion_vu['ruta_archivo_cer']) ?>
|
||||
</small>
|
||||
<input type="hidden" name="ruta_archivo_cer_actual" value="<?= htmlspecialchars($configuracion_vu['ruta_archivo_cer']) ?>">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<small class="text-muted d-block mt-1">
|
||||
Solo archivos .cer permitidos
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="password"
|
||||
class="form-control"
|
||||
id="clave_fiel"
|
||||
name="clave_fiel"
|
||||
value="<?= htmlspecialchars($configuracion_vu['clave_fiel']) ?>"
|
||||
placeholder="Contraseña FIEL"
|
||||
required>
|
||||
<label for="clave_fiel">
|
||||
<i class="fas fa-lock me-1"></i>Clave de Acceso FIEL *
|
||||
</label>
|
||||
<button type="button"
|
||||
class="btn btn-outline-secondary position-absolute end-0 top-50 translate-middle-y me-3"
|
||||
style="z-index: 10;"
|
||||
onclick="togglePassword('clave_fiel')">
|
||||
<i class="fas fa-eye" id="clave_fiel_icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
<small class="text-muted">
|
||||
<i class="fas fa-shield-alt me-1"></i>
|
||||
Esta contraseña se almacena de forma encriptada
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sección 2: Acceso Ventanilla Única -->
|
||||
<div class="config-section">
|
||||
<h6 class="text-warning mb-3">
|
||||
<i class="fas fa-user-cog me-2"></i>Acceso a Ventanilla Única
|
||||
</h6>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="rfc_usuario_vu"
|
||||
name="rfc_usuario_vu"
|
||||
value="<?= htmlspecialchars($configuracion_vu['rfc_usuario_vu']) ?>"
|
||||
placeholder="RFC12345678901"
|
||||
maxlength="13"
|
||||
style="text-transform: uppercase;"
|
||||
required>
|
||||
<label for="rfc_usuario_vu">
|
||||
<i class="fas fa-id-card me-1"></i>RFC Usuario VU *
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="password"
|
||||
class="form-control"
|
||||
id="clave_webservice"
|
||||
name="clave_webservice"
|
||||
value="<?= htmlspecialchars($configuracion_vu['clave_webservice']) ?>"
|
||||
placeholder="Contraseña Web Service">
|
||||
<label for="clave_webservice">
|
||||
<i class="fas fa-globe me-1"></i>Clave de Acceso Web Service (Opcional)
|
||||
</label>
|
||||
<button type="button"
|
||||
class="btn btn-outline-secondary position-absolute end-0 top-50 translate-middle-y me-3"
|
||||
style="z-index: 10;"
|
||||
onclick="togglePassword('clave_webservice')">
|
||||
<i class="fas fa-eye" id="clave_webservice_icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-muted">
|
||||
<i class="fas fa-info-circle me-1"></i>
|
||||
Las contraseñas se almacenan de forma encriptada por seguridad
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Información adicional -->
|
||||
<?php if ($configuracion_vu['fecha_creacion'] || $configuracion_vu['fecha_actualizacion']): ?>
|
||||
<div class="alert alert-info">
|
||||
<i class="fas fa-info-circle me-2"></i>
|
||||
<strong>Información de configuración:</strong><br>
|
||||
<?php if ($configuracion_vu['fecha_creacion']): ?>
|
||||
Creada: <?= $configuracion_vu['fecha_creacion']->format('d/m/Y H:i') ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if ($configuracion_vu['fecha_actualizacion']): ?>
|
||||
Última actualización: <?= $configuracion_vu['fecha_actualizacion']->format('d/m/Y H:i') ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Botones de acción -->
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<button type="button"
|
||||
class="btn btn-outline-info btn-animated"
|
||||
onclick="probarConfiguracion()">
|
||||
<i class="fas fa-vial me-2"></i>Probar Configuración
|
||||
</button>
|
||||
<div>
|
||||
<button type="button"
|
||||
class="btn btn-outline-secondary me-2"
|
||||
onclick="limpiarFormulario()">
|
||||
<i class="fas fa-eraser me-1"></i>Limpiar
|
||||
</button>
|
||||
<button type="submit"
|
||||
class="btn btn-primary btn-animated">
|
||||
<i class="fas fa-save me-2"></i>Guardar Configuración
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Función para mostrar/ocultar contraseñas
|
||||
function togglePassword(fieldId) {
|
||||
const field = document.getElementById(fieldId);
|
||||
const icon = document.getElementById(fieldId + '_icon');
|
||||
|
||||
if (field.type === 'password') {
|
||||
field.type = 'text';
|
||||
icon.classList.remove('fa-eye');
|
||||
icon.classList.add('fa-eye-slash');
|
||||
} else {
|
||||
field.type = 'password';
|
||||
icon.classList.remove('fa-eye-slash');
|
||||
icon.classList.add('fa-eye');
|
||||
}
|
||||
}
|
||||
|
||||
// Función para limpiar el formulario
|
||||
function limpiarFormulario() {
|
||||
if (confirm('¿Estás seguro de que deseas limpiar todos los campos?')) {
|
||||
document.getElementById('configForm').reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Función para probar la configuración
|
||||
function probarConfiguracion() {
|
||||
const btn = event.target;
|
||||
const originalHtml = btn.innerHTML;
|
||||
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Probando...';
|
||||
btn.disabled = true;
|
||||
|
||||
fetch('/IMPORTADORES/seguridad/probarConexionVU', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Configuración Válida',
|
||||
text: data.message,
|
||||
confirmButtonColor: '#28a745'
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Error en Configuración',
|
||||
text: data.message,
|
||||
confirmButtonColor: '#dc3545'
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Error de Conexión',
|
||||
text: 'No se pudo probar la configuración. Verifica tu conexión.',
|
||||
confirmButtonColor: '#dc3545'
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
btn.innerHTML = originalHtml;
|
||||
btn.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
// Validación en tiempo real de rutas de archivos
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const pathInputs = document.querySelectorAll('.path-input');
|
||||
|
||||
pathInputs.forEach(input => {
|
||||
input.addEventListener('blur', function() {
|
||||
const statusId = this.id.replace('ruta_', '') + '-status';
|
||||
const statusElement = document.getElementById(statusId);
|
||||
|
||||
if (this.value.trim()) {
|
||||
// Aquí podrías agregar validación adicional
|
||||
statusElement.innerHTML = '<i class="fas fa-check text-success"></i>';
|
||||
} else {
|
||||
statusElement.innerHTML = '';
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Convertir RFC a mayúsculas automáticamente
|
||||
document.getElementById('rfc_usuario_vu').addEventListener('input', function() {
|
||||
this.value = this.value.toUpperCase();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user