Здравствуйте.
Если задать поиск в сети Internet по ключевым словам PERCo-Web и 1С Вы найдете совсем немного статей на эту тему. А те что найдете, будут касаться устаревшей версии PERCo-S-20. Про PERCo-Web будет лишь информация, что где-то есть написанный модуль для 1С, и что его нужно будет купить.
Если Вам нужно получить данные из этой СКУД, то у Вас есть 2 пути: делать запросы к MySQL, на которой, скорее всего, "крутится" PERCo-Web или использовать API.
MySQL хоть и дает полный доступ к данным, но по умолчанию, не дает доступа с других ПК и моих знаний не хватило, как победить этот момент. API, к сожалению, ограничен данными, и выдает лишь только те, которые предусмотрел разработчик.
Все API инструкции Вы можете увидеть по адресу ВашСерверPERCo-Web/dev. Инструкций довольно много, но кому-то их может и не хватить.
Данные в этой статье мы будем получать через API путем HTTPЗапросов. HTTPЗапросов будет два вида: POST и GET. На самом деле, их больше, но для старта нам этого хватит. Остальное - сами или в комментариях.
Небольшое отступление. В 1С есть метод ВызватьHTTPМетод, в котором можно указать, какой в запросе метод post или get. Но он используется только для относительно новых версий платформы и только на сервере. Будем стремиться к универсальности. Поэтому, мы будем использовать методы: ОтправитьДляОбработки для post и Получить для get. По этой же причине, я буду показывать код для простого приложения. Для управляемого Вы переделаете его сами.
Для начала, нужно понять, что для получения данных, как и в любом другом случае, нам нужно авторизоваться на сервере. Авторизация здесь происходит не по логину паролю, а по длинной строке различных символов. Такая строка называется ключом или токеном. А вот сам токен уже можно получить по логину и паролю.
Вы можете получить токен, при помощи API запроса /system/auth. В документации есть подробный раздел даже с примерами для разных языков программирования, но, видимо, разработчик 1С за язык не считает, потому его (примера) для 1С нет. В документации написано, что следует использовать метод POST. Для получения токена я написал такую функцию:
Функция ВернутьТокен (server, login, password)
// Заголовок запроса.
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
Заголовки.Вставить("Authorization", "Bearer null");
// Запрос
АдресЗапроса = "/system/auth";
Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
// Параметры запроса.
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("login", login);
ПараметрыЗапроса.Вставить("password", password);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ПроверятьСтруктуру = Ложь;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса);
тхтJSON = ЗаписьJSON.Закрыть();
Запрос.УстановитьТелоИзСтроки(тхтJSON);
// Соединение
Соединение = Новый HTTPСоединение(server);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
Если Ответ.КодСостояния = 200 Тогда
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Возврат Данные.token;
Иначе
Возврат Неопределено;
КонецЕсли;
Исключение
Соединение = Неопределено;
Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
Возврат Неопределено;
КонецПопытки;
КонецФункции
Теперь для получения токена следует выполнить код вида:
Токен = ВернутьТокен("server/api","login","password"); //вставьте реальные данные вместо server, login, password
Затем, желательно, проверить, что токен это не Неопределено и только тогда использовать его для авторизации (аутентификации). Способы передачи токена для запроса:
- В заголовке «Авторизация»: «Bearer [ТОКЕН]»
- В параметре запроса ?token=[ТОКЕН]
Способ передачи токена в параметре запроса небезопасен, поэтому эта возможность будет удалена в ближайшее время.
Токен имеет короткое время действия, по окончании которого, он перестает действовать. Поэтому, мы будем его получать перед каждым запросом, и каждый раз он будет разным.
Теперь получим список сотрудников. Метод GET:
Процедура СписокСотрудников(Кнопка)
server = "server/api"; //вставьте реальные данные вместо server
Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
// Заголовок запроса.
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
Заголовки.Вставить("Authorization", "Bearer " + Токен);
// Запрос
АдресЗапроса = "/users/staff/fullList";
Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
// Соединение
Соединение = Новый HTTPСоединение(server);
Попытка
Ответ = Соединение.Получить(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
Если Ответ.КодСостояния = 200 Тогда
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
КонецЕсли;
Исключение
Соединение = Неопределено;
Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
КонецПопытки;
КонецПроцедуры
Данные будут в массиве Данные. Разработчик понимает, что все сотрудники нам не нужны, поэтому в эту инструкцию встроен отбор по ids. Это параметр, но вставить его в тело, как в POST не получится, поэтому, добавим его просто изменив URL. Приведу пример для ids=2450,2040:
Процедура ОтборПоID(Кнопка)
idсотрудников = "2450,2040"; //вставьте реальные данные вместо 2450,2040. можно один, можно больше двух
server = "server/api"; //вставьте реальные данные вместо server
Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
// Заголовок запроса.
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
Заголовки.Вставить("Authorization", "Bearer " + Токен);
// Запрос
АдресЗапроса = "/users/staff/fullList";
Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
Запрос.АдресРесурса = Запрос.АдресРесурса + "?ids=" + idсотрудников;
// Соединение
Соединение = Новый HTTPСоединение(server);
Попытка
Ответ = Соединение.Получить(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку("UTF-8");
Если Ответ.КодСостояния = 200 Тогда
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
КонецЕсли;
Исключение
Соединение = Неопределено;
Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
КонецПопытки;
КонецПроцедуры
Третий пример - получение картинки. Там есть свои нюансы.
Процедура Картинка(Кнопка)
server = "server/api"; //вставьте реальные данные вместо server
Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
idсотрудника = "2450"; //вставьте реальные данные вместо 2450
// Заголовок запроса.
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
Заголовки.Вставить("Authorization", "Bearer " + Токен);
// Запрос
АдресЗапроса = "/users/" + idсотрудника + "/image";
АдресЗапроса = АдресЗапроса + "?field_id=1";
Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
// Соединение
Соединение = Новый HTTPСоединение(server);
Попытка
Ответ = Соединение.Получить(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку("UTF-8");
Если Ответ.КодСостояния = 200 Тогда
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
ДД = Base64Значение(СтрЗаменить(Данные.image,"data:image/jpeg;base64,", "")); //убираем лишние данные из Base64строки, они в картинку не входят, в отличие от строки
кр = Новый Картинка(ДД);
ЭлементыФормы.Картинка.Картинка = кр; //не забудьте на форме создать элемент управления поле картинки "Картинка"
КонецЕсли;
Исключение
Соединение = Неопределено;
Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
КонецПопытки;
КонецПроцедуры
Адрес запроса формируется довольно сложно. Упростить его у меня не получилось.
Следующий пример - получение подробной информации о сотруднике:
Процедура ПодробнаяИнформация(Кнопка)
ОчиститьСообщения();
server = "server/api"; //вставьте реальные данные вместо server
Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
id = "121"; //вставьте реальные данные вместо 121
// Заголовок запроса.
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
Заголовки.Вставить("Authorization", "Bearer " + Токен);
// Запрос
АдресЗапроса = "/users/staff";
АдресЗапроса = АдресЗапроса + "/" + id;
//
Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
// Соединение
Соединение = Новый HTTPСоединение(server);
Попытка
Ответ = Соединение.Получить(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку("UTF-8");
Если Ответ.КодСостояния = 200 Тогда
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
Данные = ПрочитатьJSON(Чтение,Истина); //обратите внимание на параметр Истина. Получаем данные в виде соответствий
Чтение.Закрыть();
Сообщить("Код:" + id);
Сообщить("Найдены карты:");
Для Каждого identifier Из Данные["identifier"] Цикл
Сообщить("КодПропуска:" + identifier["identifier"]);
КонецЦикла;
Сообщить("Фото:" + Данные["photo"]);
HTTPСоединение = Новый HTTPСоединение("server"); //вставьте реальные данные вместо server
HTTPЗапрос = Новый HTTPЗапрос(Данные["photo"]);
HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
ДвоичныеДанныеКартинки = HTTPОтвет.ПолучитьТелоКакДвоичныеДанные();
ЭлементыФормы.Картинка.Картинка = Новый Картинка(ДвоичныеДанныеКартинки); //не забудьте на форме вставить картинку
Сообщить("ТабНомер:" + Данные["tabel_number"]);
Сообщить("Фамилия:" + Данные["last_name"]);
Сообщить("Имя:" + Данные["first_name"]);
Сообщить("Отчество:" + Данные["middle_name"]);
Сообщить("Подразделений у сотрудника тут может быть несколько. Найдены следующие:");
Для Каждого division Из Данные["division"] Цикл
Сообщить(division.Значение);
КонецЦикла;
Сообщить("ДействительноПо:" + Данные.Получить("end_datetime"));
Сообщить("Найдены доступы:");
Для Каждого access_template Из Данные["access_template"] Цикл
Для Каждого Элемент Из access_template Цикл
Сообщить(Элемент.Ключ + ":" + Элемент.Значение);
КонецЦикла;
КонецЦикла;
КонецЕсли;
Исключение
Соединение = Неопределено;
Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
КонецПопытки;
КонецПроцедуры
Покажу, как использовать фильтр. Фильтр представляет собой неформатированный JSON - в одну строчку вида: {"type": "", "rows": [{"column": "", "value": ""}]} type: 'and' или 'or' - условие выборки, логическое И или ИЛИ. rows - массив объектов, содержащий название колонки и значение для поиска. Например, найдем сотрудника не по ID, а по табельному номеру "007", использовав фильтр {"type": "and","rows": [{"column": "tabel_number","value": "007"}]}
Процедура ПоискПоТабельному(Кнопка)
ОчиститьСообщения();
server = "server/api"; //вставьте реальные данные вместо server
Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
tabel_number = "007"; //вставьте реальные данные вместо 007
// Заголовок запроса.
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
Заголовки.Вставить("Authorization", "Bearer " + Токен);
// Параметры запроса.
Фильтр = Новый Структура;
Фильтр.Вставить("column","tabel_number");
Фильтр.Вставить("value",tabel_number);
Колонки = Новый Массив;
Колонки.Добавить(Фильтр);
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("type", "and");
ПараметрыЗапроса.Вставить("rows", Колонки);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ПроверятьСтруктуру = Ложь;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса);
тхтJSON = ЗаписьJSON.Закрыть();
//Уберем форматирование в JSON, сделаем в одну строку
тхтJSON = СтрЗаменить(СтрЗаменить(тхтJSON,Символы.ПС,""),Символы.ВК,"");
// Запрос
АдресЗапроса = "/users/staff/table";
АдресЗапроса = АдресЗапроса + "?status=active" + "&filters=" + тхтJSON; //данная инструкция позволяет искать или только действующих, или только уволенных сотрудников, вставляем параметр действующих, второй параметр идет через знак &
//
Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
// Соединение
Соединение = Новый HTTPСоединение(server);
Попытка
Ответ = Соединение.Получить(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку("UTF-8");
Если Ответ.КодСостояния = 200 Тогда
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Сообщить(ТекстОтвета);
КонецЕсли;
Исключение
Соединение = Неопределено;
Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
КонецПопытки;
КонецПроцедуры
Будьте внимательны! Фильтр ищет не по строгому соответствию, а по вхождению, то есть будут найдены все сотрудники, у которых в табельном встречается 007, например, не только 007, а еще и 0007 и 0070...
И последний пример - запись в СКУД - поменяем табельный номер 007, на 001. Тут следует использовать метод POST:
Процедура КнопкаВыполнитьНажатие(Кнопка)
server = "server/api"; //вставьте реальные данные вместо server
Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
ID = "007"; //вставьте реальные данные вместо 007
// Заголовок запроса.
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
Заголовки.Вставить("Authorization", "Bearer " + Токен);
// Запрос
АдресЗапроса = "/users/staff";
АдресЗапроса = АдресЗапроса + "/" + ID;
Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
// Параметры запроса.
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("tabel_number", "001"); //вставьте реальные данные вместо 001
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ПроверятьСтруктуру = Ложь;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса);
тхтJSON = ЗаписьJSON.Закрыть();
Запрос.УстановитьТелоИзСтроки(тхтJSON);
// Соединение
Соединение = Новый HTTPСоединение(server);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
Если Ответ.КодСостояния = 200 Тогда
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
КонецЕсли;
Исключение
Соединение = Неопределено;
Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
КонецПопытки;
КонецПроцедуры
На сегодня это все! Жду вопросов, ответов на них, критики и пожеланий.... Вопрос от меня: Как получить доступ к MySQL PERCo-Web? Кто знает - пишите!
Вступайте в нашу телеграмм-группу Инфостарт