Глава 12. Бронирование переговорных и Workflow
К этому моменту Вы уже хорошо знакомы с NocoBase.
В этой главе мы вместе реализуем особый сценарий: модуль управления совещаниями.
Этот модуль будет включать функции бронирования переговорных и уведомлений. Мы будем строить модуль управления совещаниями с нуля, начиная с основ и постепенно переходя к более сложной функциональности. Сначала разработаем структуру базовых таблиц для этого модуля.
12.1 Проектирование структуры таблиц
Структуру таблиц можно рассматривать как фундамент модуля управления совещаниями. Здесь мы сосредоточимся на таблице переговорных и таблице бронирований, а также рассмотрим новые отношения, в том числе многие ко многим с пользователями.

12.1.1 Таблица переговорных
Таблица переговорных хранит базовую информацию обо всех переговорных: название, расположение, вместимость, оснащение и т. д.
Пример структуры таблицы
12.1.2 Таблица бронирований
Таблица бронирований хранит информацию о всех записях на совещания: переговорная, участники, временной интервал, тема совещания и описание.
Пример структуры таблицы
Связь «многие ко многим»
В таблице бронирований используется связь «многие ко многим»: один пользователь может участвовать во многих совещаниях, а в одном совещании может участвовать много пользователей. Здесь нужно правильно настроить связь по внешнему ключу. Для удобства можно назвать промежуточную таблицу booking_users.

12.2 Создание модуля управления совещаниями
После проектирования структуры таблиц можно создать обе таблицы согласно проекту и собрать модуль «Управление совещаниями». Шаги создания и настройки:
12.2.1 Создание блока таблицы
Сначала добавьте на страницу модуль «Управление совещаниями», создайте отдельные блок таблицы переговорных и блок таблицы бронирований (таблица). Затем добавьте блок календаря для таблицы бронирований и установите вид по умолчанию «День».

Связывание блока таблицы переговорных
Свяжите блок таблицы переговорных с двумя другими блоками: при этом записи бронирований будут автоматически фильтроваться по выбранной переговорной. Затем попробуйте функции фильтрации, добавления, удаления, поиска и редактирования, чтобы протестировать базовое взаимодействие модуля.
Связывание блоков NocoBase (рекомендуется!)
Помимо ранее использованных блоков фильтра, блок таблицы тоже можно связывать с другими блоками — для фильтрации по клику.
Как показано ниже, в настройках таблицы переговорных свяжите два других блока бронирований (блок таблицы бронирований и блок календаря бронирований).

После успешной привязки кликайте по строкам таблицы переговорных — две другие таблицы будут автоматически фильтроваться. Повторный клик по выделенной строке сбрасывает выбор.
12.3 Проверка занятости переговорной
После настройки страницы добавим важную функцию: проверку занятости переговорной. Она будет проверять, не занята ли переговорная в выбранный временной интервал, при создании или обновлении совещания, чтобы избежать конфликтов бронирования.
12.3.1 Настройка workflow «Событие до операции»
Для проверки во время бронирования используем особый тип workflow — «Событие до операции»:
- Событие до операции (коммерческий plugin): выполняет последовательность операций перед созданием, изменением или удалением данных, м ожет в любой момент остановить выполнение и заранее перехватить операцию. Этот подход очень близок к привычному процессу разработки!

12.3.2 Настройка узлов
В workflow проверки занятости нам понадобятся узлы следующих типов:
- Узел вычислений (логика преобразования данных, для обработки операций изменения и добавления)
- SQL-операция (выполнение SQL-запроса)
- Парсинг JSON (коммерческий plugin, для разбора JSON-данных)
- Сообщение-ответ (коммерческий plugin, для возврата подсказки пользователю)
12.3.3 Привязка к таблице бронирований и настройка триггера
Привяжите workflow к таблице бронирований, выберите режим триггера «Глобальный режим» и установите типы операций — создание и обновление записи.

12.4 Настройка узла вычислений
12.4.1 Создание узла «Преобразование пустого ID в -1»
Сначала создадим узел вычислений, который будет преобразовывать пустой ID в -1. Узел вычислений может преобразовывать переменные нужным нам способом и поддерживает три формы операций:
- Math.js (см. Math.js)
- Formula.js (см. Formula.js)
- Шаблон строк (для к онкатенации данных)
Используем Formula.js для проверки числа:

12.5. Создание узла SQL-операции
Затем создаём узел SQL-операции, выполняющий запрос для поиска свободных переговорных:
12.5.1 SQL-запрос для поиска свободных переговорных
Внимание по SQL: переменные подставляются прямо в SQL, проверяйте их внимательно во избежание SQL-инъекций. Не забывайте про одинарные кавычки в нужных местах.
Переменные:
{{$jobsMapByNodeKey.3a0lsms6tgg}} — результат предыдущего узла, 【Данные узла / Преобразование пустого ID в -1】
{{$context.params.values.end_time}} — 【Переменная триггера/Параметры/Объект отправленных значений/Время окончания】
{{$context.params.values.start_time}} — 【Переменная триггера/Параметры/Объект отправленных значений/Время начала】
12.5.2 Тестирование SQL
Цель — найти все переговорные, не конфликтующие с заданным интервалом времени.
Можно нажать кнопку «Test run» внизу, изменить значения переменных и отладить SQL.


12.6 Парсинг JSON
12.6.1 Настройка узла парсинга JSON
После теста на предыдущем шаге результат имеет такой вид. Для его обработки нужно включить plugin JSON query node:
Доступны три способа разбора JSON: JMESPath JSON Path Plus JSONata
Здесь выбираем любой, например [JMESPath]. Нам нужен список названий доступных переговорных, поэтому пишем:
Привязка свойств выполняется для списков объектов, в данном случае она необязательна.

12.7 Условное ветвление
Настройте узел условного ветвления, чтобы определить, входит ли текущая переговорная в список доступных. В зависимости от результата (да или нет) сконфигурируем разные сообщения-ответы.
В качестве условия выберем «базовое» вычисление:

12.7.1 Да: настройка сообщения об успехе
Здесь нужно включить plugin Workflow: Response message:

12.7.2 Нет: настройка сообщения об ошибке
Внимание: при отрицательном результате обязательно добавьте узел «Завершить процесс», чтобы вручную остановить выполнение.

12.8 Проверка работы и пошаговая отладка
Перейдём к финальному тестированию системы управления совещаниями. Цель — убедиться, что workflow корректно обнаруживает конфликты бронирования и блокирует их.
12.8.1 Бронирование с конфликтным интервалом
Сначала попробуем добавить бронирование, время которого пересекается с уже существующими. Посмотрим, заблокирует ли система операцию и покажет ли ошибку.
- Установим конфликтный временной интервал
Попробуем добавить новое бронирование в «Переговорную 1» на интервал
2024-11-14 00:00:00 — 2024-11-14 23:00:00
Этот интервал охватывает весь день — мы намеренно создаём конфликт с уже существующими бронированиями.
- Существующие бронирования
В «Переговорной 1» уже есть два интервала:
2024-11-14 09:00:00 — 2024-11-14 12:00:002024-11-14 14:00:00 — 2024-11-14 16:30:00
Оба пересекаются с интервалом
(2024-11-14 00:00:00 — 2024-11-14 23:00:00).
Поэтому система должна обнаружить конфликт и заблокировать бронирование.
- Отправка бронирования и проверка реакции
Нажимаем кнопку Отправить — система выполняет workflow проверки:
Ожидаемый результат: после отправки появляется сообщение о конфликте, что подтверждает корректность логики проверки. Страница отображает, что бронирование выполнить невозможно.

12.8.2 Бронирование без конфликтов
Теперь протестируем сценарий без конфликтов.
Убедимся, что когда времена не перес екаются, бронирование переговорной выполняется успешно.
- Выбираем непересекающийся интервал
Например,
2024-11-10 16:00:00 — 2024-11-10 17:00:00.
Этот интервал не пересекается ни с одним существующим бронированием и удовлетворяет условиям.
- Отправляем бронирование
Нажимаем кнопку Отправить — система снова выполняет логику проверки workflow:
Проверим вместе: отправка успешна! Появляется сообщение «Бронирование выполнено». Это подтверждает, что без конфликтов функция тоже работает правильно.

12.8.3 Изменение времени существующего бронирования
Помимо создания новых бронирований Вы можете протестировать изменение времени уже существующих.
Например, измените время существующего совещания на другой непересекающийся интервал и снова отправьте.
Этот шаг оставляем Вам.
12.9 Доработка дашборда и панель личного расписания
После того как все функции прошли проверку, можно улучшить и оптимизировать дашборд для повышения удобства пользователей.
12.9.1 Корректировка раскладки дашборда
В дашборде можно перекомпоновать содержимое страницы под привычки пользователя, чтобы данные было проще просматривать.
Для дополнительного удобства можно создать каждому пользователю собственную панель совещаний. Конкретные шаги:
- Создать блок «Личное расписание»: добавьте на дашборд новый блок календаря или списка для отображения личных совещаний пользователя.
- Установить значение участника по умолчанию: задайте значение по умолчанию равным текущему пользователю, чтобы при открытии дашборда он сразу видел свои совещания.
Это улучшает опыт работы с модулем управления совещаниями.
После выполнения этих настроек дашб орд становится нагляднее и удобнее, а функциональность — заметно богаче!


С помощью описанных шагов мы успешно реализовали и оптимизировали основные функции модуля управления совещаниями! Надеемся, что в процессе работы Вы постепенно освоите ключевые возможности NocoBase и почувствуете удовольствие от модульного построения систем.
Продолжайте исследовать и проявляйте творческий подход! Если столкнётесь с трудностями, всегда обращайтесь к официальной документации NocoBase или к сообществу NocoBase для обсуждения.


