Разработка сайта фитнес-клуба на 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка сайта фитнес-клуба на 1С-Битрикс
Сложная
от 1 недели до 3 месяцев
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    745
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка сайта фитнес-клуба на 1С-Битрикс

Сайт фитнес-клуба — это не витрина с фотографиями залов. Это рабочий инструмент, через который клиент записывается на тренировку, покупает абонемент, отслеживает остаток занятий и взаимодействует с тренером. Всё это должно работать без ручного вмешательства администратора, синхронизироваться с внутренними системами клуба и выдерживать пиковые нагрузки в понедельник вечером, когда полгорода решает начать новую жизнь.

Разберём, как это реализуется на 1С-Битрикс — от структуры данных до логики бронирования мест.

Расписание занятий: Highload-блоки и фильтрация

Расписание — центральный элемент сайта. Клиент приходит сюда чаще всего, и если расписание тормозит или неудобно фильтруется — он уходит в Telegram-бот конкурента.

Почему Highload-блок, а не обычный инфоблок. Обычный инфоблок (b_iblock_element) хранит данные в EAV-модели: каждое свойство — отдельная строка в b_iblock_element_property. При 300 занятиях в неделю, 15 залах и 40 тренерах таблица свойств разрастается на десятки тысяч строк. Фильтрация по комбинации «зал + день + тренер + направление» превращается в серию JOIN-ов, которые на боевом сервере дают 800-1200 мс.

Highload-блок (b_hlblock_entity) — это плоская таблица в MySQL/PostgreSQL. Одна строка = одно занятие, все поля — колонки. Фильтрация работает через обычные индексы.

Структура Highload-блока FitnessSchedule:

Поле Тип Назначение
UF_DATE date Дата занятия
UF_TIME_START string Начало (формат HH:MM)
UF_TIME_END string Окончание
UF_HALL_ID integer ID зала (связь с HL FitnessHalls)
UF_TRAINER_ID integer ID тренера (связь с инфоблоком тренеров)
UF_DIRECTION_ID integer Направление: йога, кроссфит, бассейн...
UF_CAPACITY integer Максимум участников
UF_BOOKED integer Текущее количество записавшихся
UF_STATUS enumeration active / cancelled / full
UF_IS_RECURRING boolean Повторяющееся по шаблону
UF_TEMPLATE_ID integer Ссылка на шаблон расписания

Для повторяющихся занятий создаётся отдельный Highload-блок ScheduleTemplate с полями дня недели и времени. Cron-задача (agents Битрикса или системный cron) раз в неделю генерирует конкретные занятия на следующую неделю по шаблонам. Это позволяет тренеру отменить конкретное занятие 15 марта, не ломая всё расписание.

Фильтрация на фронте. Используем Bitrix\Highloadblock\HighloadBlockTable::compileEntity() для получения ORM-сущности, далее стандартный DataManager::getList() с фильтром:

$result = $entityClass::getList([
    'filter' => [
        'UF_DATE' => $selectedDate,
        'UF_HALL_ID' => $hallId,
        'UF_STATUS' => 'active',
    ],
    'order' => ['UF_TIME_START' => 'ASC'],
]);

На фронте расписание рендерится как сетка: по горизонтали — залы, по вертикали — временные слоты. Клиент переключает день, фильтрует по направлению или тренеру. AJAX-запросы через компонент bitrix:highloadblock.list или кастомный REST-эндпоинт.

Онлайн-запись с лимитом мест и waitlist

Запись на занятие — это не просто «нажал кнопку, попал в список». Это транзакционная операция с проверкой лимита, конкурентным доступом и механизмом ожидания.

Основной сценарий:

  1. Клиент нажимает «Записаться» на конкретном занятии
  2. Система проверяет: UF_BOOKED < UF_CAPACITY
  3. Если да — создаёт запись в Highload-блоке FitnessBooking, инкрементирует UF_BOOKED
  4. Если нет — предлагает встать в лист ожидания

Проблема конкурентного доступа. Два клиента одновременно нажимают «Записаться» на занятие, где осталось одно место. Без блокировки оба получат подтверждение, а на тренировке окажется лишний человек.

Решение — использование \Bitrix\Main\Application::getConnection() с транзакцией и блокировкой строки:

$connection = \Bitrix\Main\Application::getConnection();
$connection->startTransaction();

$row = $entityClass::getList([
    'filter' => ['ID' => $scheduleId],
    'select' => ['UF_BOOKED', 'UF_CAPACITY'],
    'runtime' => [/* FOR UPDATE через raw SQL */],
])->fetch();

if ($row['UF_BOOKED'] < $row['UF_CAPACITY']) {
    // создаём бронирование, инкрементируем UF_BOOKED
    $connection->commitTransaction();
} else {
    $connection->rollbackTransaction();
    // предлагаем waitlist
}

На практике чистый ORM Битрикса не поддерживает SELECT ... FOR UPDATE, поэтому критическую секцию оборачиваем в raw SQL через $connection->query().

Лист ожидания (waitlist). Отдельный Highload-блок FitnessWaitlist с полями: UF_SCHEDULE_ID, UF_USER_ID, UF_POSITION, UF_CREATED_AT. Когда кто-то отменяет запись, агент Битрикса проверяет waitlist и автоматически переносит первого в очереди в основной список, отправляя SMS/push через модуль messageservice.

Отмена записи. Клуб обычно разрешает отмену за 2-4 часа до начала. Логика проверки времени — в обработчике события, который сравнивает UF_TIME_START с текущим временем и блокирует отмену, если лимит прошёл.

Продажа абонементов через модуль sale

Абонементы фитнес-клуба — это не товары из каталога. У них своя логика: срок действия, количество посещений, заморозка.

Типы абонементов реализуются как элементы инфоблока «Абонементы» со свойствами:

  • DURATION_DAYS — срок действия в днях
  • VISIT_LIMIT — лимит посещений (0 = безлимит)
  • TYPE — разовый / месячный / годовой
  • FREEZE_ALLOWED — можно ли замораживать
  • FREEZE_MAX_DAYS — максимальный срок заморозки

При покупке через \Bitrix\Sale\Order::create() абонемент добавляется в корзину как обычный товар, но после оплаты срабатывает обработчик события OnSaleOrderPaid. Он создаёт запись в Highload-блоке UserSubscription с полями: UF_USER_ID, UF_START_DATE, UF_END_DATE, UF_VISITS_LEFT, UF_IS_FROZEN, UF_FREEZE_START.

Заморозка абонемента. Клиент в личном кабинете нажимает «Заморозить». Система проверяет FREEZE_ALLOWED и FREEZE_MAX_DAYS, устанавливает UF_IS_FROZEN = true, сохраняет UF_FREEZE_START. При разморозке — пересчитывает UF_END_DATE, добавляя количество замороженных дней.

Интеграция с CRM-системами клуба

Фитнес-клубы редко работают только через сайт. Основные системы учёта — 1С:Фитнес клуб и Mobifitness.

1С:Фитнес клуб. Обмен через стандартный протокол CommerceML или через REST API самой 1С (HTTP-сервисы). Синхронизируются: справочник услуг, расписание, клиентская база, продажи абонементов. Обмен запускается по cron каждые 15-30 минут.

Mobifitness API. REST API с авторизацией по токену. Основные эндпоинты: /api/v1/schedule, /api/v1/bookings, /api/v1/clients. Битрикс выступает фронтендом, а Mobifitness — мастер-системой расписания. В этом случае Highload-блок FitnessSchedule заполняется не вручную, а через синхронизацию с API.

Выбор архитектуры зависит от того, какая система является мастером данных. Если клуб уже работает в Mobifitness — сайт подтягивает расписание оттуда. Если клуб переходит на цифру с нуля — Битрикс может быть основной системой.

Личный кабинет клиента

Личный кабинет строится на стандартном модуле main (авторизация, профиль) с расширениями:

  • История посещений — выборка из FitnessBooking по UF_USER_ID с JOIN на расписание
  • Остаток занятий — поле UF_VISITS_LEFT из UserSubscription
  • Продление абонемента — кнопка, которая создаёт заказ в sale с привязкой к текущей подписке
  • Заморозка/разморозка — интерфейс управления статусом подписки

Авторизация — через телефон с SMS-кодом (модуль messageservice + кастомный компонент). Фитнес-аудитория не любит пароли.

Тренерские профили

Тренеры — отдельный инфоблок с привязкой к направлениям через множественное свойство типа «Привязка к элементам». Каждый тренер имеет: фото, сертификаты (файловые свойства), опыт, описание, ссылку на расписание (фильтр по UF_TRAINER_ID).

На детальной странице тренера автоматически выводится его расписание на текущую неделю — один AJAX-запрос к FitnessSchedule с фильтром по тренеру.

Сроки реализации

Масштаб проекта Состав Срок
Небольшой клуб (1 зал, 5-7 направлений) Расписание, запись, абонементы, личный кабинет 8-10 недель
Сеть из 3-5 клубов + мультисайтовость, единая база, интеграция с Mobifitness 14-18 недель
Крупная сеть (10+ клубов) + B2B-портал для корпклиентов, мобильное приложение через REST API Битрикса, сложная тарификация 20-28 недель

Что учесть до старта

Перед разработкой нужно определить мастер-систему расписания: будет ли расписание вестись в Битриксе или в сторонней CRM. Это определяет направление синхронизации и архитектуру Highload-блоков. Второй вопрос — платёжный шлюз: для абонементов с автосписанием нужен эквайринг с поддержкой рекуррентных платежей, а это отдельная интеграция через sale.paysystem.