Налаштування онлайн-запису до лікаря на 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
    Розробка веб-сайту для компанії ФІКСПЕР
    1018
  • 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
    760
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    879
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    803
  • 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С-Бітрікс.