Capítulo 12: Reserva de salas de reuniones y Workflow
A estas alturas, estamos seguros de que usted ya está bastante familiarizado con NocoBase.
En este capítulo, implementaremos juntos un escenario especial: el módulo de gestión de reuniones.
Este módulo incluye funciones como la reserva de salas de reuniones y notificaciones. A lo largo del proceso, construiremos paso a paso, desde cero, un módulo de gestión de reuniones, comenzando por lo básico y avanzando gradualmente hacia funcionalidades más complejas. Empecemos por diseñar la estructura básica de las tablas de datos de este módulo.
12.1 Diseño de la estructura de las tablas de datos
La estructura de las tablas de datos puede entenderse como el marco básico del módulo de gestión de reuniones. Aquí nos centraremos en la tabla de salas de reuniones y la tabla de reservas, e introduciremos algunas relaciones nuevas, como la relación muchos a muchos con los usuarios.

12.1.1 Tabla de salas de reuniones
La tabla de salas de reuniones se utiliza para almacenar la información básica de todas las salas, incluyendo campos como nombre, ubicación, capacidad, configuración, etc.
Ejemplo de estructura de la tabla
12.1.2 Tabla de reservas
La tabla de reservas se utiliza para registrar toda la información de reservas de reuniones, incluyendo campos como sala, usuarios participantes, intervalo de tiempo, título y descripción de la reunión.
Ejemplo de estructura de la tabla
Relación muchos a muchos
En la tabla de reservas existe una relación "muchos a muchos": un usuario puede asistir a varias reuniones y una reunión puede tener varios usuarios. Esta relación muchos a muchos requiere configurar correctamente las claves foráneas. Para facilitar la gestión, podemos nombrar la tabla intermedia como booking_users.

12.2 Construcción del módulo de gestión de reuniones
Una vez diseñada la estructura de las tablas, podemos crear ambas tablas según el diseño y construir el módulo de "Gestión de reuniones". A continuación se indican los pasos de creación y configuración:
12.2.1 Creación de bloques de tabla
Primero, agregue el módulo de "Gestión de reuniones" en la página, creando respectivamente un bloque de tabla de salas de reuniones y un bloque de tabla de reservas. A continuación cree un bloque de calendario para la tabla de reservas, con la vista predeterminada configurada como "Día".

Configuración de la asociación del bloque de tabla de salas
Asocie el bloque de tabla de salas de reuniones con los otros dos bloques, de modo que se filtren automáticamente los registros de reservas correspondientes a la sala. A continuación, puede probar las funciones de filtrado, creación, eliminación, consulta y modificación, para verificar la interacción básica del módulo.
💡 Conexión de bloques de NocoBase (¡recomendado!):
Además del bloque de filtros anterior, nuestros bloques de tabla también pueden conectarse con otros bloques, lo que permite obtener un efecto de filtrado al hacer clic.
Como se muestra en la imagen siguiente, en la configuración de la tabla de salas, conectamos los otros dos bloques de la tabla de reservas (bloque de tabla de reservas y bloque de calendario de reservas).

Una vez establecida la conexión, al hacer clic en la tabla de salas verá que las otras dos tablas se filtran al mismo tiempo. Vuelva a hacer clic en el elemento seleccionado para deseleccionarlo.
12.3 Detección de la disponibilidad de las salas
Una vez configurada la página, debemos añadir una función importante: la detección de la disponibilidad de las salas. Esta función comprueba, al crear o actualizar una reunión, si la sala objetivo está ocupada en el intervalo de tiempo especificado, evitando así conflictos de reserva.
12.3.1 Configuración del Workflow de "Evento previo a la operación"
Para realizar la detección al hacer una reserva, utilizaremos un tipo especial de workflow, el Evento previo a la operación:
- Evento previo a la operación (Plugin comercial): ejecuta una serie de operaciones antes de crear, eliminar o modificar datos, pudiendo pausarse e interceptarse en cualquier momento. ¡Este enfoque se asemeja mucho al flujo de desarrollo de código que usamos a diario!

12.3.2 Configuración de los nodos
En el workflow de detección de disponibilidad necesitaremos los siguientes tipos de nodos:
- Nodo de cálculo (lógica de transformación de datos, para procesar casos de modificación y creación)
- Operación SQL (ejecutar consultas SQL)
- Análisis JSON (Plugin comercial, para analizar datos JSON)
- Mensaje de respuesta (Plugin comercial, para devolver mensajes informativos)
12.3.3 Vinculación de la tabla de reservas y configuración del disparador
Ahora vincularemos la tabla de reservas, seleccionaremos el modo de disparador "Modo global", y elegiremos como tipos de operación la creación y la actualización de registros.

12.4 Configuración del nodo de cálculo
12.4.1 Creación del nodo de cálculo "Convertir ID vacío en -1"
Comenzaremos creando un nodo de cálculo que convierta el ID vacío en -1. El nodo de cálculo permite transformar variables del modo que necesitemos, ofreciendo las tres formas siguientes:
- Math.js (consulte Math.js)
- Formula.js (consulte Formula.js)
- Plantilla de cadena (para la concatenación de datos)
Aquí utilizaremos Formula.js para evaluar el valor numérico:

12.5. Creación del nodo de operación SQL
A continuación, crearemos el nodo de operación SQL que ejecutará la consulta para verificar las salas disponibles:
12.5.1 Sentencia SQL para consultar salas disponibles
Atención sobre SQL: las variables se sustituyen directamente en la sentencia SQL; revise cuidadosamente las variables para evitar inyecciones SQL. Añada comillas simples en los lugares apropiados.
Las variables corresponden a:
{{$jobsMapByNodeKey.3a0lsms6tgg}} representa el resultado del nodo anterior, [Datos del nodo / Convertir ID vacío en -1].
{{$context.params.values.end_time}} representa [Variable del disparador / Parámetros / Objeto de valores enviados / Hora de fin].
{{$context.params.values.start_time}} representa [Variable del disparador / Parámetros / Objeto de valores enviados / Hora de inicio].
12.5.2 Prueba de la consulta SQL
Nuestro objetivo es consultar todas las salas que no tengan conflicto con el intervalo de tiempo objetivo.
Durante el proceso, puede hacer clic en "Test run" abajo, modificar los valores de las variables y depurar la consulta SQL.


12.6 Análisis JSON
12.6.1 Configuración del nodo de análisis JSON
Tras la prueba del paso anterior, podemos observar que el resultado tiene la siguiente forma; en este punto necesitamos activar el Plugin JSON query node:
Existen tres formas de analizar JSON: JMESPath JSON Path Plus JSONata
Aquí elegiremos una, por ejemplo el formato JMESPath. Como necesitamos filtrar la lista de nombres de todas las salas disponibles, la expresión sería:
La configuración de mapeo de propiedades es para listas de objetos y, por el momento, no es necesaria, así que se puede dejar en blanco.

12.7 Evaluación condicional
Configuraremos el nodo de evaluación condicional, que comprueba si la sala actual se encuentra en la lista de salas disponibles. Según el resultado Sí o No, configuraremos los mensajes de respuesta correspondientes:
Para la condición, basta con elegir el modo "Básico":

12.7.1 Sí: configuración del mensaje de éxito
En este punto debemos activar el Plugin Workflow: Response message:

12.7.2 No: configuración del mensaje de error
Atención: cuando la evaluación falle, debemos configurar siempre un nodo de "Fin del flujo" para terminar manualmente el proceso.

12.8 Pruebas y depuración detallada
Ahora pasaremos a la fase de pruebas finales del sistema de gestión de reuniones. El objetivo de esta etapa es confirmar que nuestro workflow detecta y bloquea correctamente las reservas de salas en conflicto.
12.8.1 Añadir una reserva con intervalo de tiempo en conflicto
Primero intentaremos añadir una reunión con un intervalo que entre en conflicto con una reserva existente, para comprobar si el sistema bloquea la operación y muestra un mensaje de error.
- Configurar un intervalo de tiempo en conflicto
Intentaremos añadir una nueva reserva en la "Sala de reuniones 1", con el intervalo
2024-11-14 00:00:00 - 2024-11-14 23:00:00
Este intervalo abarca todo el día, por lo que se ha provocado deliberadamente un conflicto con las reservas existentes.
- Confirmar las reservas existentes
En la "Sala de reuniones 1" ya existen dos intervalos reservados:
2024-11-14 09:00:00 a 2024-11-14 12:00:002024-11-14 14:00:00 a 2024-11-14 16:30:00
Ambos intervalos se solapan con el que vamos a añadir
(2024-11-14 00:00:00 - 2024-11-14 23:00:00).
Por lo tanto, según la lógica, el sistema debería detectar el conflicto de tiempo y bloquear esta reserva.
- Enviar la reserva y verificar la respuesta
Hacemos clic en el botón Enviar y el sistema ejecutará la lógica de detección del workflow:
Respuesta exitosa: tras el envío, el sistema muestra una alerta de conflicto, indicando que la lógica de detección funciona correctamente. La página nos informa correctamente de que no es posible completar esta reserva.

12.8.2 Añadir una reserva sin conflicto de tiempo
A continuación, probemos una reserva sin conflicto.
¡Aseguremos que cuando los horarios de la reunión no se solapan podemos reservar la sala con éxito!
- Configurar un intervalo sin conflictos
Elegiremos un intervalo sin conflictos, por ejemplo
2024-11-10 16:00:00 - 2024-11-10 17:00:00.
Este intervalo no se solapa con las reservas existentes, por lo que cumple con los requisitos para reservar la sala.
- Enviar la reserva sin conflictos
Hacemos clic en el botón Enviar y el sistema vuelve a ejecutar la lógica de detección del workflow:
Verifiquemos juntos: ¡Envío exitoso! El sistema muestra el mensaje "Reserva exitosa", lo que demuestra que la función también funciona correctamente cuando no hay conflictos.

12.8.3 Modificar el horario de una reserva existente
Además de crear nuevas reservas, también puede probar modificar la hora de una reserva existente.
Por ejemplo, cambiar la hora de una reunión existente a otro intervalo sin conflictos y volver a hacer clic en Enviar.
¡Esta parte la dejamos para usted!
12.9 Optimización del dashboard y panel personal de agenda
Una vez superadas todas las pruebas funcionales, podemos seguir mejorando y optimizando el dashboard para mejorar la experiencia del usuario.
12.9.1 Ajuste del diseño del dashboard
En el dashboard podemos reorganizar el contenido de la página según los hábitos de uso, para que los usuarios puedan ver los datos del sistema con mayor facilidad.
Para mejorar aún más la experiencia, podemos crear un panel personal de agenda exclusivo para cada usuario. Los pasos son:
- Crear un nuevo bloque "Agenda personal": agregue un nuevo bloque de calendario o lista en el dashboard que muestre la agenda personal del usuario.
- Configurar el valor predeterminado del miembro: establezca el valor predeterminado del miembro como el usuario actual, de modo que al abrir el dashboard se muestren por defecto las reuniones relacionadas con cada uno.
De este modo, optimizamos aún más la experiencia del usuario en el módulo de gestión de reuniones.
Tras estas configuraciones, la funcionalidad y el diseño del dashboard serán más intuitivos y fáciles de usar, ¡y se enriquecerá considerablemente!


¡Mediante los pasos anteriores hemos implementado y optimizado con éxito las funciones principales del módulo de gestión de reuniones! Esperamos que, en este proceso, haya podido ir dominando las funciones esenciales de NocoBase y haya disfrutado de la experiencia de construir un sistema modular.
¡Continúe explorando y dé rienda suelta a su creatividad! Si encuentra algún problema, no olvide que siempre puede consultar la documentación oficial de NocoBase o unirse a la comunidad de NocoBase para discutirlo.


