Files

168 lines
8.7 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
// Общий модуль bfd_IntegrationAPIHelpers
//
// Назначение: вспомогательные процедуры/функции для HTTP-сервиса bfd_IntegrationAPI
// (read-only REST API для проекта bit-flight-deck).
//
// Свойства модуля (выставить в Конфигураторе):
// Сервер = Истина
// Вызов сервера = Истина
// Внешнее соединение = Истина (для всякого случая)
// Привилегированный = Истина (важно — позволяет читать всё в обход RLS)
////////////////////////////////////////////////////////////////////////////////
#Область ПрограммныйИнтерфейс
// Формирует HTTPСервисОтвет с JSON-телом.
// Параметры:
// Данные — Произвольный (Структура / Массив / Число / Строка / Дата / Булево / Неопределено)
// Код — Число (по умолчанию 200)
// Возвращаемое значение: HTTPСервисОтвет
//
Функция СформироватьОтветJSON(Знач Данные, Знач Код = 200) Экспорт
ЗаписьJSON = Новый ЗаписьJSON;
// Минимальный конструктор для совместимости с 8.3.14.
// Дата 1С обрабатывается в НормализоватьДляJSON ниже (преобразуется в ISO-строку),
// поэтому ФорматДатыJSON в параметрах не нужен.
ПараметрыJSON = Новый ПараметрыЗаписи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 в 8.3.14 не принимает Null без специальных параметров.
Если Значение = Null Тогда
Возврат Неопределено;
КонецЕсли;
Если Значение = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Тип = ТипЗнч(Значение);
Если Тип = Тип("Структура") Тогда
Результат = Новый Структура;
Для Каждого КлючЗначение Из Значение Цикл
Результат.Вставить(КлючЗначение.Ключ, НормализоватьДляJSON(КлючЗначение.Значение));
КонецЦикла;
Возврат Результат;
ИначеЕсли Тип = Тип("Соответствие") Тогда
Результат = Новый Соответствие;
Для Каждого КлючЗначение Из Значение Цикл
Результат.Вставить(КлючЗначение.Ключ, НормализоватьДляJSON(КлючЗначение.Значение));
КонецЦикла;
Возврат Результат;
ИначеЕсли Тип = Тип("Массив") Тогда
Результат = Новый Массив;
Для Каждого Элемент Из Значение Цикл
Результат.Добавить(НормализоватьДляJSON(Элемент));
КонецЦикла;
Возврат Результат;
ИначеЕсли Тип = Тип("Строка") ИЛИ Тип = Тип("Число") ИЛИ Тип = Тип("Булево") Тогда
Возврат Значение;
ИначеЕсли Тип = Тип("Дата") Тогда
// Платформа в ПараметрыЗаписиJSON 8.3.14 не умеет сериализовать Дату 1С —
// преобразуем в ISO-строку явно.
Если НЕ ЗначениеЗаполнено(Значение) Тогда
Возврат "";
КонецЕсли;
Возврат Формат(Значение, "ДФ=yyyy-MM-ddTHH:mm:ss");
Иначе
// Ссылки, перечисления, ХранилищеЗначения, прочие объекты 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);
КонецФункции
#КонецОбласти