//////////////////////////////////////////////////////////////////////////////// // Общий модуль bfd_IntegrationAPIHelpers // // Назначение: вспомогательные процедуры/функции для HTTP-сервиса bfd_IntegrationAPI // (read-only REST API для проекта bit-flight-deck). // // Свойства модуля (выставить в Конфигураторе): // Сервер = Истина // Вызов сервера = Истина // Внешнее соединение = Истина (для всякого случая) // Привилегированный = Истина (важно — позволяет читать всё в обход RLS) //////////////////////////////////////////////////////////////////////////////// #Область ПрограммныйИнтерфейс // Формирует HTTPСервисОтвет с JSON-телом. // Параметры: // Данные — Произвольный (Структура / Массив / Число / Строка / Дата / Булево / Неопределено) // Код — Число (по умолчанию 200) // Возвращаемое значение: HTTPСервисОтвет // Функция СформироватьОтветJSON(Знач Данные, Знач Код = 200) Экспорт ЗаписьJSON = Новый ЗаписьJSON; // Дефолтные параметры записи JSON (без переносов строк недоступно в 8.3.14 — используем умолчание). ПараметрыJSON = Новый ПараметрыЗаписиJSON; ЗаписьJSON.УстановитьСтроку(ПараметрыJSON); // ЗаписатьJSON не умеет сериализовать произвольные 1С-типы (ссылки, перечисления, ХранилищеЗначения и т.п.). // Перед записью нормализуем структуру/массив — превращаем «не примитивы» в строку. БезопасныеДанные = НормализоватьДляJSON(Данные); ЗаписатьJSON(ЗаписьJSON, БезопасныеДанные); Ответ = Новый HTTPСервисОтвет(Код); Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8"); Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть(), КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); Возврат Ответ; КонецФункции // Рекурсивно нормализует значение для безопасной сериализации в JSON. // Структура → новая Структура с нормализованными значениями. // Массив → новый Массив с нормализованными элементами. // Дата/Число/Булево/Строка/Неопределено/Null → как есть. // Остальное (ссылки, перечисления, любые объекты 1С) → Строка(Значение). // Функция НормализоватьДляJSON(Знач Значение) Экспорт Если Значение = Неопределено ИЛИ Значение = Null Тогда Возврат Значение; КонецЕсли; Тип = ТипЗнч(Значение); Если Тип = Тип("Структура") Тогда Результат = Новый Структура; Для Каждого КлючЗначение Из Значение Цикл Результат.Вставить(КлючЗначение.Ключ, НормализоватьДляJSON(КлючЗначение.Значение)); КонецЦикла; Возврат Результат; ИначеЕсли Тип = Тип("Соответствие") Тогда Результат = Новый Соответствие; Для Каждого КлючЗначение Из Значение Цикл Результат.Вставить(КлючЗначение.Ключ, НормализоватьДляJSON(КлючЗначение.Значение)); КонецЦикла; Возврат Результат; ИначеЕсли Тип = Тип("Массив") Тогда Результат = Новый Массив; Для Каждого Элемент Из Значение Цикл Результат.Добавить(НормализоватьДляJSON(Элемент)); КонецЦикла; Возврат Результат; ИначеЕсли Тип = Тип("Строка") ИЛИ Тип = Тип("Число") ИЛИ Тип = Тип("Булево") ИЛИ Тип = Тип("Дата") Тогда Возврат Значение; Иначе // Ссылки, перечисления, ХранилищеЗначения, прочие объекты 1С → строкой Попытка Возврат Строка(Значение); Исключение Возврат ""; КонецПопытки; КонецЕсли; КонецФункции // Сериализованная ошибка. // Функция СформироватьОтветОшибки(Знач СообщениеОшибки, Знач Код = 500) Экспорт Структура = Новый Структура("error", СообщениеОшибки); Возврат СформироватьОтветJSON(Структура, Код); КонецФункции // Парсит ISO 8601 дату из строки query-параметра. // Возвращает Дату или '00010101' при ошибке/пусто. // Функция ПарсДатуISO(Знач СтрокаДаты) Экспорт Если ПустаяСтрока(СтрокаДаты) Тогда Возврат Дата(1, 1, 1); КонецЕсли; ОчищеннаяСтрока = СтрЗаменить(СтрЗаменить(СтрокаДаты, "T", " "), "Z", ""); Попытка Возврат Дата(ОчищеннаяСтрока); Исключение Возврат Дата(1, 1, 1); КонецПопытки; КонецФункции // Строковое представление GUID ссылки или пустая строка. // Безопасно для составных типов (где значение может быть строкой): // - если значение пусто → ""; // - если ссылка → её UUID строкой; // - если строка/число/булево/etc → Строка(Значение). // Функция UUID(Знач Ссылка) Экспорт Если НЕ ЗначениеЗаполнено(Ссылка) Тогда Возврат ""; КонецЕсли; Попытка Возврат Строка(Ссылка.УникальныйИдентификатор()); Исключение // Не ссылка (составной тип измерения / Число / Строка / Перечисление и т.п.) Возврат Строка(Ссылка); КонецПопытки; КонецФункции // Лимит выборки из query-параметра. // Функция ПарсЛимит(Знач Запрос, Знач MaxDefault = 1000, Знач MaxAllowed = 10000) Экспорт Параметр = Запрос.ПараметрыЗапроса.Получить("limit"); Если ПустаяСтрока(Параметр) Тогда Возврат MaxDefault; КонецЕсли; Попытка Значение = Число(Параметр); Исключение Возврат MaxDefault; КонецПопытки; Если Значение <= 0 Тогда Возврат MaxDefault; КонецЕсли; Возврат Мин(Значение, MaxAllowed); КонецФункции #КонецОбласти