Розробка мультикрокової форми зворотного зв'язку 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 днів |







