Настройка онлайн-записи к врачу на 1С-Битрикс

Сайт медицинской клиники с формой «Оставьте заявку и мы перезвоним» теряет до 60% конверсии — пользователь хочет выбрать конкретного врача, конкретное время и получить подтверждение немедленно. Онлайн-запись с выбором слота — стандарт для любой современной клиники, причём лучшие реализации использую
Услуги, которые мы предлагаем
Показано 1 из 1Все 1626 услуг
Настройка онлайн-записи к врачу на 1С-Битрикс
Простой
~1 день

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1454
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    1017
  • 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
    759
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    879
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    802
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    1162

Сайт медицинской клиники с формой «Оставьте заявку и мы перезвоним» теряет до 60% конверсии — пользователь хочет выбрать конкретного врача, конкретное время и получить подтверждение немедленно. Онлайн-запись с выбором слота — стандарт для любой современной клиники, причём лучшие реализации используют документированные компоненты 1С-Битрикс, обеспечивающие безопасность и масштабирование. Реализация на 1С-Битрикс позволяет связать расписание с МИС или управлять им внутри системы, если МИС нет. Наши инженеры с сертификацией Битрикс внедрили такие решения в 20+ клиниках, сократив время записи в среднем на 50%.

Экономия от внедрения: клиенты уменьшают нагрузку на колл-центр на 40% и получают окупаемость проекта за 6–8 месяцев. В сравнении с кастомным PHP-решением скорость внедрения на 1С-Битрикс выше в 2–3 раза, а стоимость поддержки — ниже на 30%. Готовые компоненты и API платформы ускоряют разработку: встроенная авторизация, уведомления, личный кабинет и защита от атак.

Техническая реализация онлайн-записи

Источник расписания — ключевой момент при проектировании. Рассмотрим два варианта.

Вариант A: Расписание в Битрикс. Администратор клиники управляет расписанием врачей через интерфейс в Битрикс. Записи хранятся в Битрикс и передаются в МИС (или не передаются — клиника без МИС). Подходит для небольших клиник без сложной МИС.

Вариант B: Расписание из МИС. Битрикс синхронизирует расписание из МИС каждые N минут. Записи создаются через API МИС. Сайт — только интерфейс, мастер-данные в МИС.

Далее описываем Вариант A — автономное расписание в Битрикс.

Структура таблиц

-- Шаблон рабочего времени врача CREATE TABLE local_doctor_schedule_template ( ID INT AUTO_INCREMENT PRIMARY KEY, DOCTOR_ID INT NOT NULL, -- ID элемента инфоблока «Врачи» DAY_OF_WEEK TINYINT NOT NULL, -- 1=Пн, 7=Вс TIME_FROM TIME NOT NULL, TIME_TO TIME NOT NULL, SLOT_DURATION INT DEFAULT 30, -- минут на приём ACTIVE CHAR(1) DEFAULT 'Y' ); -- Конкретные слоты (генерируются из шаблона) CREATE TABLE local_doctor_slots ( ID BIGINT AUTO_INCREMENT PRIMARY KEY, DOCTOR_ID INT NOT NULL, SLOT_DATE DATE NOT NULL, SLOT_TIME TIME NOT NULL, STATUS ENUM('free','reserved','booked','blocked') DEFAULT 'free', APPOINTMENT_ID BIGINT, INDEX idx_doctor_date (DOCTOR_ID, SLOT_DATE, STATUS) ); -- Записи пациентов CREATE TABLE local_appointments ( ID BIGINT AUTO_INCREMENT PRIMARY KEY, DOCTOR_ID INT NOT NULL, SLOT_ID BIGINT NOT NULL, USER_ID INT, -- NULL для незарегистрированных PATIENT_NAME VARCHAR(200), PATIENT_PHONE VARCHAR(20), PATIENT_EMAIL VARCHAR(200), SERVICE_ID INT, -- Услуга (инфоблок услуг) COMMENT TEXT, STATUS ENUM('pending','confirmed','cancelled','completed') DEFAULT 'pending', CREATED_AT DATETIME, CONFIRMED_AT DATETIME, CANCELLED_AT DATETIME ); 

Генерация слотов из шаблона

Агент, запускаемый ежедневно, генерирует слоты на следующие 30 дней:

function GenerateDoctorSlots(): string { $targetDate = (new \DateTime())->modify('+30 days'); $today = new \DateTime(); $templates = LocalDoctorScheduleTemplateTable::getList([ 'filter' => ['ACTIVE' => 'Y'], 'select' => ['DOCTOR_ID', 'DAY_OF_WEEK', 'TIME_FROM', 'TIME_TO', 'SLOT_DURATION'], ]); while ($tpl = $templates->fetch()) { $date = clone $today; while ($date <= $targetDate) { if ((int)$date->format('N') === (int)$tpl['DAY_OF_WEEK']) { generateSlotsForDay($tpl, $date); } $date->modify('+1 day'); } } return __FUNCTION__ . '();'; } function generateSlotsForDay(array $tpl, \DateTime $date): void { $from = new \DateTime($date->format('Y-m-d') . ' ' . $tpl['TIME_FROM']); $to = new \DateTime($date->format('Y-m-d') . ' ' . $tpl['TIME_TO']); $interval = new \DateInterval('PT' . $tpl['SLOT_DURATION'] . 'M'); $current = clone $from; while ($current < $to) { // Не создаём дубли $exists = LocalDoctorSlotsTable::getCount([ 'DOCTOR_ID' => $tpl['DOCTOR_ID'], 'SLOT_DATE' => $date->format('Y-m-d'), 'SLOT_TIME' => $current->format('H:i:s'), ]); if (!$exists) { LocalDoctorSlotsTable::add([ 'DOCTOR_ID' => $tpl['DOCTOR_ID'], 'SLOT_DATE' => $date->format('Y-m-d'), 'SLOT_TIME' => $current->format('H:i:s'), 'STATUS' => 'free', ]); } $current->add($interval); } } 

Компонент бронирования

Компонент /local/components/local/appointment.booking/ разработан на основе Компонент 2.0 с шагами:

Шаг 1 — Выбор врача/специализации. Фильтр по специализации из инфоблока врачей. AJAX-обновление списка врачей.

Шаг 2 — Выбор даты и времени. Календарь с подсвеченными доступными датами. При выборе даты — AJAX-запрос доступных слотов:

// AJAX-обработчик /local/ajax/get-slots.php $doctorId = (int)$_POST['doctor_id']; $date = $_POST['date']; // Y-m-d $slots = LocalDoctorSlotsTable::getList([ 'filter' => [ 'DOCTOR_ID' => $doctorId, 'SLOT_DATE' => $date, 'STATUS' => 'free', ], 'order' => ['SLOT_TIME' => 'ASC'], 'select' => ['ID', 'SLOT_TIME'], ])->fetchAll(); header('Content-Type: application/json'); echo json_encode(['slots' => $slots]); 

Шаг 3 — Форма пациента. Имя, телефон, email, комментарий. Для авторизованных — данные подставляются из профиля. Валидация номера телефона.

Шаг 4 — Подтверждение и бронирование.

public function bookSlot(int $slotId, array $patientData, int $serviceId = 0): int { $connection = \Bitrix\Main\Application::getConnection(); $connection->startTransaction(); try { // Атомарное резервирование слота $connection->queryExecute(" UPDATE local_doctor_slots SET STATUS = 'reserved' WHERE ID = ? AND STATUS = 'free' ", [$slotId]); if ($connection->getAffectedRowsCount() === 0) { throw new \RuntimeException('Этот слот уже занят'); } $appointmentId = LocalAppointmentsTable::add([ 'DOCTOR_ID' => $this->getSlotDoctorId($slotId), 'SLOT_ID' => $slotId, 'USER_ID' => $patientData['user_id'] ?? null, 'PATIENT_NAME' => $patientData['name'], 'PATIENT_PHONE' => $patientData['phone'], 'PATIENT_EMAIL' => $patientData['email'], 'SERVICE_ID' => $serviceId, 'COMMENT' => $patientData['comment'] ?? '', 'STATUS' => 'confirmed', ])->getId(); // Обновляем слот — статус и привязка к записи LocalDoctorSlotsTable::update($slotId, [ 'STATUS' => 'booked', 'APPOINTMENT_ID' => $appointmentId, ]); $connection->commitTransaction(); // Уведомления вне транзакции $this->sendConfirmationSms($patientData['phone'], $appointmentId); $this->sendConfirmationEmail($patientData['email'], $appointmentId); return $appointmentId; } catch (\Exception $e) { $connection->rollbackTransaction(); throw $e; } } 

Транзакция с UPDATE ... WHERE STATUS = 'free' и проверкой affectedRows — защита от race condition при одновременной записи двух пользователей на один слот. При атомарном UPDATE используется блокировка строки на уровне БД. В случае конфликта второй запрос получит исключение. Это стандартный паттерн обработки параллельных бронирований.

Как мы решаем проблему двойной записи?

Атомарные UPDATE с проверкой affectedRows внутри транзакции. Если два пользователя одновременно отправляют запрос, только один успешно обновит слот. Второй получит ошибку «Этот слот уже занят». Дополнительно блокируем строку в БД на время транзакции — это гарантирует консистентность.

Как отменить запись из личного кабинета?

Пациент может отменить запись не позднее чем за N часов до приёма:

public function cancelAppointment(int $appointmentId, int $userId): void { $appointment = LocalAppointmentsTable::getById($appointmentId)->fetch(); if (!$appointment || (int)$appointment['USER_ID'] !== $userId) { throw new \RuntimeException('Запись не найдена'); } $slot = LocalDoctorSlotsTable::getById($appointment['SLOT_ID'])->fetch(); $slotDateTime = new \DateTime($slot['SLOT_DATE'] . ' ' . $slot['SLOT_TIME']); if ($slotDateTime <= (new \DateTime())->modify('+2 hours')) { throw new \RuntimeException('Отмена записи возможна не позднее чем за 2 часа'); } LocalAppointmentsTable::update($appointmentId, ['STATUS' => 'cancelled']); LocalDoctorSlotsTable::update($appointment['SLOT_ID'], ['STATUS' => 'free', 'APPOINTMENT_ID' => null]); } 

Сравнение вариантов интеграции

Характеристика Расписание в Битрикс Расписание из МИС
Сложность внедрения Низкая — 3–5 недель Высокая — 6–10 недель
Управление данными Через админку Битрикс Через МИС, Битрикс только интерфейс
Автономность Полная Зависимость от МИС
Подходит для Клиник без МИС или с простой МИС Клиник с существующей МИС
Затраты на разработку на 50% ниже выше из-за интеграции

Что входит в работу

  • Проектирование структуры таблиц и агентов
  • Разработка и установка компонента бронирования (выбор врача → дата → слот → форма → подтверждение)
  • Настройка агента генерации слотов
  • AJAX-обработчики для динамического обновления слотов
  • Реализация защиты от race condition
  • Интеграция SMS/email-уведомлений и напоминаний
  • Личный кабинет пациента с историей и отменой записи
  • Документация по API и администрированию
  • Обучение администраторов (2–4 часа)
  • Техническая поддержка на 30 дней после запуска

Процесс внедрения и сроки

  1. Аналитика — изучаем текущее расписание, загрузку врачей, МИС (если есть). Оцениваем объём: в среднем 30 врачей генерируют 600 слотов в день.
  2. Проектирование — согласовываем структуру данных, логику слотов. Создаём прототип интерфейса.
  3. Реализация — пишем код, настраиваем компоненты. Включаем агент генерации слотов на 30 дней вперёд.
  4. Тестирование — проверяем на реальных сценариях: двойная запись, перенос, отмена. Проводим нагрузочное тестирование до 1000 одновременных запросов.
  5. Деплой — выкатываем на бой, настраиваем права доступа. Мониторим логи первые 24 часа.
  6. Обучение — показываем администраторам интерфейс и резервное копирование. Предоставляем документацию.

Сроки: 3–5 недель автономная система без МИС. 6–10 недель с интеграцией МИС.

Свяжитесь с нами для расчёта точных сроков под ваш проект. Получите консультацию сертифицированного инженера по 1С-Битрикс.