From 99d48f393a36f31e32d8dd73388cc47f0f1e2890 Mon Sep 17 00:00:00 2001 From: NikitaKalitov Date: Mon, 27 Jul 2026 09:50:04 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20=D0=B3?= =?UTF-8?q?=D0=B0=D0=B9=D0=B4=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/backend-quickstart.md | 80 ++++++++++++++++++++++++++++++++++++++ docs/bitrix-integration.md | 11 +++--- 2 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 docs/backend-quickstart.md diff --git a/docs/backend-quickstart.md b/docs/backend-quickstart.md new file mode 100644 index 0000000..6a8ec5d --- /dev/null +++ b/docs/backend-quickstart.md @@ -0,0 +1,80 @@ +# Гайд: как встроить конструктор диаграмм в поле Bitrix + +Короткая практическая версия — только три вопроса: куда положить билд, как собрать HTML и куда писать начальное значение. Про полноценный переиспользуемый тип свойства инфоблока (регистрация, `ConvertToDB` и т.п.) — отдельный документ, [`docs/bitrix-integration.md`](./bitrix-integration.md). Если поле одно и на одной странице — этого гайда достаточно. + +## 1. Куда положить билд конструктора + +Приложение — статическая сборка (`npm run build` → `dist/`), которая раздаётся тем же nginx, что и сам портал. Ничего разворачивать отдельно не нужно. + +1. Собрать в репозитории `portal-chart-builder`: + ``` + VITE_BITRIX_ORIGIN=https://ВАШ-ДОМЕН-ПОРТАЛА VITE_BASE_PATH=/local/diagram-app/ npm run build + ``` + - `VITE_BITRIX_ORIGIN` — origin портала (без пути). Обязателен — без него приложение намеренно не запустится (защита от случайного `postMessage('*')`). + - `VITE_BASE_PATH` — подпуть, под которым будет отдаваться приложение. Должен совпадать с тем, куда положите `dist/` на шаге 2. +2. Скопировать содержимое `dist/` в `local/diagram-app/` внутри каталога сайта на сервере (тот же каталог, где лежит остальной код портала — `bitrix_www`/аналог на проде). +3. Готово: приложение доступно по `https://ВАШ-ДОМЕН-ПОРТАЛА/local/diagram-app/index.html`. + +**При каждом повторном деплое** (обновили React-приложение, положили новый `dist/` поверх старого) — добавляйте к `src` iframe cache-busting параметр (`?v=<дата/хэш билда>`). У `.html`-файлов на большинстве Bitrix-стендов стоит `Cache-Control` на 30 дней — без версии в URL браузер администратора может продолжать открывать старый `index.html` со старыми хэшами JS/CSS ещё месяц. + +## 2. Как сформировать HTML + +Три части: скрытое поле со значением, iframe с приложением, скрипт-мост между ними. + +```html + + + + +``` + +Как это работает: +- iframe грузит приложение → оно шлёт мосту `{ type: 'diagram:ready' }`. +- Мост в ответ шлёт `{ type: 'diagram:init', payload: input.value }` — приложение рисует диаграмму из этого значения (или пустой холст, если `payload` пуст). +- Каждая правка в редакторе прилетает мосту как `{ type: 'diagram:change', payload: '' }` — мост тут же кладёт её в `input.value`. +- Дальше это обычный `` внутри формы: если у него есть `id`, `name` и он лежит в `
` — браузер сам отправит его значение при обычном сабмите формы. Никакого дополнительного JS для сохранения не нужно. + +**`id`/`name` = `"DIAGRAM-DATA"` захардкожены** — это ок, если поле на странице ровно одно. Если полей несколько (например, полноценный переиспользуемый тип свойства, который может стоять на разных элементах) — `name` должен быть уникальным и совпадать с тем, что ожидает обработчик сохранения на бэкенде (в терминах Bitrix custom property type — `$strHTMLControlName['VALUE']`, см. `docs/bitrix-integration.md`, раздел 3). + +**Обязательно к соблюдению, не опционально:** +- `event.origin` проверяется у входящих сообщений (уже в сниппете выше). +- `targetOrigin` у `postMessage` — всегда конкретный домен (`APP_ORIGIN`), никогда `'*'`. +- Значение попадает на страницу только через `value`-атрибут (`htmlspecialcharsbx()`), не через встраивание в JS-код — так не нужно никакого JSON-специфичного экранирования, обычного `htmlspecialcharsbx()` достаточно. + +## 3. Куда записывать начальное значение + +`value=""` — сюда подставляется то, что уже сохранено для этого элемента/записи (JSON-строка со схемой диаграммы) или пустая строка, если диаграммы ещё нет. + +Откуда взять `$currentValue` — зависит от того, где именно хранится значение на вашей стороне (поле БД, свойство инфоблока, опция и т.п.) — это единственное, что специфично для конкретной интеграции, дальше всё стандартно: + +```php +$currentValue = /* ваш способ прочитать сохранённое значение, например: */ + $arElement['PROPERTY_DIAGRAM_VALUE'] ?? ''; +``` + +Требований к содержимому со стороны бэкенда — минимум: это либо пустая строка, либо синтаксически валидный JSON. Всю содержательную валидацию (обязательные поля узлов и т.п.) делает само React-приложение — бэкенду глубже проверять не нужно. Пример реального значения — в `docs/bitrix-integration.md`, раздел 6. + +## Проверка + +1. Открыть страницу — iframe показывает пустую диаграмму (для нового элемента) или ранее сохранённую. +2. Отредактировать (подвигать фигуры, поменять текст). +3. Сабмитнуть форму как обычно (не внутри iframe). +4. Перезагрузить страницу — изменения на месте. +5. Проверить напрямую в БД/хранилище — там лежит валидный JSON. diff --git a/docs/bitrix-integration.md b/docs/bitrix-integration.md index 5d073e5..ddcdf16 100644 --- a/docs/bitrix-integration.md +++ b/docs/bitrix-integration.md @@ -41,8 +41,6 @@ class DiagramProperty { $inputName = htmlspecialcharsbx($strHTMLControlName['VALUE']); $rawValue = $value['VALUE'] ?? ''; - // JSON_HEX_* флаги обязательны — см. раздел 5. - $jsValue = json_encode($rawValue, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT); // Вариант A — рекомендуемый, приложение лежит внутри дерева портала (см. раздел 7): // appOrigin — это просто origin текущего запроса, appUrl — конкретный файл. @@ -60,8 +58,11 @@ class DiagramProperty style="width:100%;height:600px;border:1px solid #ccc">