Розробка мультикрокової форми зворотного зв'язку 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Розробка мультикрокової форми зворотного зв'язку 1С-Бітрікс
Середня
~1-2 тижні
Часті питання

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

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • 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
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Розробка мультикрокової форми зворотного зв'язку 1С-Бітрікс

Мультикрокова форма зворотного зв'язку відрізняється від звичайної покрокової тим, що її мета — не продаж, а отримання структурованого звернення. Технічні запити, скарги, звернення до підтримки, заявки на повернення — ситуації, коли потрібно послідовно зібрати контекст. Тип звернення визначає, які поля показувати далі. Це вже умовна логіка, яка ближча до квіз-воронки, але орієнтована на сервісні, а не продажні сценарії.

Архітектура з умовними полями

Ключова особливість: на першому кроці користувач обирає тип звернення — і подальші кроки змінюються. Це вимагає умовного рендерингу.

Конфігурація кроків з умовами:

const FEEDBACK_FORM_CONFIG = {
    steps: [
        {
            id: 'step_type',
            title: 'Тип звернення',
            fields: [
                {
                    name: 'type',
                    type: 'radio-cards',
                    required: true,
                    options: [
                        {value: 'technical', label: 'Технічне питання', icon: '⚙️'},
                        {value: 'billing',   label: 'Питання щодо оплати', icon: '💳'},
                        {value: 'complaint', label: 'Скарга',              icon: '⚠️'},
                        {value: 'other',     label: 'Інше',                icon: '💬'},
                    ],
                },
            ],
        },
        {
            id: 'step_technical',
            showWhen: {field: 'type', value: 'technical'},
            title: 'Опис проблеми',
            fields: [
                {name: 'product', type: 'select', label: 'Продукт', required: true,
                 options: ['Мобільний застосунок', 'Веб-сайт', 'API']},
                {name: 'error_text', type: 'textarea', label: 'Опишіть помилку', required: true},
                {name: 'screenshot', type: 'file', label: 'Скриншот (необов\'язково)', accept: 'image/*'},
            ],
        },
        {
            id: 'step_billing',
            showWhen: {field: 'type', value: 'billing'},
            title: 'Дані про платіж',
            fields: [
                {name: 'order_id',    type: 'text',   label: 'Номер замовлення',  required: true},
                {name: 'amount',      type: 'number', label: 'Сума платежу',       required: true},
                {name: 'issue_type',  type: 'select', label: 'Проблема',           required: true,
                 options: ['Подвійне списання', 'Немає чека', 'Неправильна сума', 'Інше']},
            ],
        },
        {
            id: 'step_contact',
            title: 'Ваші контакти',
            fields: [
                {name: 'name',  type: 'text',  label: 'Ім\'я',    required: true},
                {name: 'email', type: 'email', label: 'Email',    required: true},
                {name: 'phone', type: 'tel',   label: 'Телефон',  required: false},
            ],
        },
    ],
};

JavaScript-контролер з умовною логікою

class ConditionalMultistepForm {
    constructor(config) {
        this.config    = config;
        this.answers   = {};
        this.stepsPath = this.calculatePath();
        this.currentIndex = 0;
    }

    // Обчислити актуальний шлях кроків на основі поточних відповідей
    calculatePath() {
        return this.config.steps.filter(step => {
            if (!step.showWhen) return true;
            const {field, value} = step.showWhen;
            const answer = this.answers[field];
            return Array.isArray(value) ? value.includes(answer) : answer === value;
        });
    }

    handleAnswer(fieldName, value) {
        this.answers[fieldName] = value;
        // Перерахувати шлях — набір кроків міг змінитися
        this.stepsPath = this.calculatePath();
    }

    get currentStep() {
        return this.stepsPath[this.currentIndex] ?? null;
    }

    get totalSteps() {
        return this.stepsPath.length;
    }

    canGoNext() {
        const step = this.currentStep;
        if (!step) return false;

        return step.fields
            .filter(f => f.required)
            .every(f => !!this.answers[f.name]);
    }

    next() {
        if (!this.canGoNext()) return false;
        if (this.currentIndex < this.stepsPath.length - 1) {
            this.currentIndex++;
            return true;
        }
        return false; // Останній крок
    }

    prev() {
        if (this.currentIndex > 0) {
            this.currentIndex--;
        }
    }

    isLastStep() {
        return this.currentIndex === this.stepsPath.length - 1;
    }

    getSubmitData() {
        return {
            type:    this.answers.type,
            answers: this.answers,
        };
    }
}

Обробка файлів (скриншот)

Завантаження файлів у мультикроковій формі вимагає або негайного завантаження при виборі, або надсилання разом з іншими даними.

Негайне завантаження при виборі файлу — через AJAX, повертає ID завантаженого файлу в Бітрікс:

// /local/ajax/upload_temp_file.php
if (!$_FILES['file'] || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
    echo json_encode(['error' => 'Помилка завантаження']);
    exit;
}

// Перевірка типу файлу
$allowedMime = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
if (!in_array($_FILES['file']['type'], $allowedMime)) {
    echo json_encode(['error' => 'Неприпустимий тип файлу']);
    exit;
}

// Зберегти як тимчасовий файл Бітрікс
$fileId = \CFile::SaveFile([
    'name'     => $_FILES['file']['name'],
    'size'     => $_FILES['file']['size'],
    'tmp_name' => $_FILES['file']['tmp_name'],
    'type'     => $_FILES['file']['type'],
], 'feedback_forms');

echo json_encode(['file_id' => $fileId]);

При фінальному надсиланні — передати file_id разом з іншими даними.

Збереження та створення звернення в CRM

Звернення направляються залежно від типу:

// /local/ajax/feedback_form_submit.php

$data = json_decode(file_get_contents('php://input'), true);
$type = $data['type'] ?? 'other';

\Bitrix\Main\Loader::includeModule('crm');

switch ($type) {
    case 'technical':
        // Технічні звернення → угода у воронці «Підтримка»
        $deal = new \CCrmDeal(false);
        $deal->Add([
            'TITLE'      => 'Тех. звернення: ' . ($data['answers']['product'] ?? ''),
            'CATEGORY_ID' => CRM_SUPPORT_PIPELINE_ID,
            'STAGE_ID'   => 'C' . CRM_SUPPORT_PIPELINE_ID . ':NEW',
            'COMMENTS'   => $data['answers']['error_text'] ?? '',
            'CONTACT_ID' => $this->findOrCreateContact($data),
        ]);
        break;

    case 'billing':
        // Фінансові питання → лід з тегом
        $lead = new \CCrmLead(false);
        $lead->Add([
            'TITLE'    => 'Білінг: замовлення #' . ($data['answers']['order_id'] ?? ''),
            'COMMENTS' => 'Проблема: ' . ($data['answers']['issue_type'] ?? ''),
        ]);
        break;

    default:
        // Інші — лід
        $lead = new \CCrmLead(false);
        $lead->Add([
            'TITLE'   => 'Звернення: ' . $data['answers']['name'],
            'SOURCE_ID' => 'WEB',
        ]);
}

echo json_encode(['success' => true]);

Сповіщення

При отриманні звернення — сповістити відповідального. Використовуємо поштові події Бітрікс (b_event_log):

\Bitrix\Main\Mail\Event::send([
    'EVENT_NAME' => 'FEEDBACK_NEW_TICKET',
    'LID'        => SITE_ID,
    'C_FIELDS'   => [
        'TYPE'  => $typeLabel,
        'NAME'  => $data['answers']['name'],
        'EMAIL' => $data['answers']['email'],
        'TEXT'  => json_encode($data['answers'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
    ],
    'TO_EMAIL'   => FEEDBACK_MANAGER_EMAIL,
]);

Шаблон поштової події створюється в Налаштування → Поштові події → Поштові шаблони.

Терміни розробки

Варіант Склад Термін
Базова мультикрокова 2–3 кроки, тип звернення, лід у CRM 3–5 днів
З умовною логікою Різні поля за типом, завантаження файлів 6–10 днів
Повний Service Desk + Особистий кабінет, статуси звернень, SLA 15–25 днів