Cerebellum_Crud-rest-custom-fields
CRUD REST для настраиваемых полей
Удаление настраиваемых полей
Удаление настраиваемых полей работает не совсем так, как ожидается при «наивной» реализации.
Во-первых, удаление логическое, а не физическое — запись помечается как удаленная, но сохраняется в базе. Здесь мы намеренно идём на конфликт с MapAdmin, т.к. он удаляет записи физически. Получается, что если Cerebellum удалит настраиваемое поле, то MapAdmin по-прежнему будет его видеть.
Второй момент, который облегчает понимание, для чего нужен первый: настраиваемое поле, помеченное как удаленное, не отображается в списке доступных для задачи настраиваемых полей, но при этом обрабатывается при сохранении задачи в базе. Например, пусть есть поле myCustomField и есть задача, в которой его значение равно «test». Пользователь помечает myCustomField как удалённое, а затем меняет заголовок задачи и сохраняет его. Так как myCustomField удалено, то пользователь не увидит его значение в задаче. Но так как поле обрабатывается при сохранении, то его значение, равное «test» фактически не теряется и по-прежнему будет сохранено в базе (более того, поле когда-нибудь может быть восстановлено вместе со своим значением).
Получается, если мы удалим какое-то поле, то оно более не будет видно пользователю в задачах, но сохранение всех использующих его задач не сломается. Этот плюс компенсирует то неудобство, что MapAdmin будет отображать как удалённые, так и активные настраиваемые поля. Собственно, с его точки зрения удалённые поля таковыми и не являются, т.к. по прежнему сохраняются в базе.
С точки зрения реализации это будет выглядеть следующим образом. В классе CustomField
есть четыре метода для доступа к настраиваемым полям:
List<CustomField> all();
CustomField byId(Long id);
List<CustomField> required(Long issueTypeId);
List<CustomField> defaults(Long issueTypeId);
Первый из них используется при отдаче пользователю списка доступных для редактирования настраиваемых полей. Этот метод не должен возвращать логически удалённые поля. Остальные методы используются при обработке значений настраиваемых полей во время сохранения. Соответственно, они должны работать с логически удалёнными полями как с обычными.
Еще более правильным решением будет создать private-версии методов byId(Long id)
, required(Long issueTypeId)
, defaults(Long issueTypeId)
и пользоваться ими только при сохранении настраиваемых полей.
[AI] GET /custom_field/:id
Получение информации по настраиваемому полю.
Если поле не существует или логически удалено, клиенту возвращается статус 404.
// OUT <---
{
"res": 1,
"resText": "",
"id": "123", // id нового поля
"name": "Адрес филиала организации", // название поля
"translit": "string",// транслитерация названия поля
"format": "text", // формат данных поля, возможные значения: "int", "float", "bool", "geometry", "string", "text", "list", "date"
"group_name": "Информация о филиалах организации", // название группы полей
"possible_values": ["первое значение", "второе значение", "третье значение"], // список возможных значений, доступно только для поля формата "list"
"regexp": "[0-9]{1,3}", // регулярное выражение, доступно только для полей форматов "string", "text", "int", "float"
"min_length": "5", // минимальная длина, доступно только для полей форматов "string", "text"
"max_length": "50", // максимальная длина, доступно только для полей форматов "string", "text"
"is_required": "f", // обязательное ли поле: "t", "f"
"default_value": "РТ, г.Казань", // значение по умолчанию, доступно для всех форматов полей, за исключением формата "geometry",
// значение задается с соответствии с форматом поля (текст, число, дата, булево значение)
"visible": "f", // видимость данного поля при отображении полной информации по задаче: "t", "f"
"is_for_all": "f", // доступно ли данное поле для всех типов новостей (видов работ): "t", "f
"news_type_ids": "["1", "2"]", //массив id типов новостей, для которых поле доступно, если оно не доступно всем типам новостей
"order": "10" // номер данного поля для отображения в списке настраиваемых полей
}
[AI] POST /custom_field
Создание нового настраиваемого (кастомного) поля.
// IN --->
{
"name": "Фактический адрес организации", // название нового поля, обязательный параметр
"format": "text", // формат данных поля, возможные значения: "int", "float", "bool", "geometry", "string", "text", "list", "date"; обязательный параметр
"group_name": "Информация об организации", // название группы полей, при указании несуществующей группы полей в таблицу будет добавлена запись.
"possible_values": ["первое значение", "второе значение"], // список возможных значений, доступно только для поля формата "list", и является обязательным параметром для поля формата "list"
"regexp": "[0-9]{1,3}", // регулярное выражение, доступно только для полей форматов "string", "text", "int", "float"
"min_length": "2", // минимальная длина, доступно только для полей форматов "string", "text"
"max_length": "25", // максимальная длина, доступно только для полей форматов "string", "text"
"is_required": "t", // обязательное ли поле: "t", "f", по умолчанию "f"
"default_value": "г.Москва", // значение по умолчанию, доступно для всех форматов полей, за исключением формата "geometry",
// значение задается с соответствии с форматом поля (текст, число, дата, булево значение)
"visible": "t" // видимость данного поля при отображении полной информации по задаче: "t", "f", по умолчанию "t"
}
При возникновении одной из следующих ситуаций клиенту возвращается статус 400:
- Передано поле possible_values, но формат настраиваемого поля не «list»;
- передано поле regexp, но формат не «string», «text», «int» или «float»;
- переданы поля min_length или max_length, но формат не «string» или «text»;
- передано поле default_value, но формат «geometry»;
- значение default_value (переданное или текущее)
- не соответствует формату поля (для форматов «bool», «int», «float», «date»);
- и/или не проходит валидацию по regexp/min_length/max_length;
- и/или не является одним из possible_values (для поля формата «list»).
// OUT <---
{
"res": 1,
"resText": "",
"id": "123", // id нового поля
"name": "Фактический адрес организации", // название нового поля
"translit": "Fakticheskiy_adres_organizatsi",// транслитерация названия поля
"format": "text", // формат данных поля, возможные значения: "int", "float", "bool", "geometry", "string", "text", "list", "date"
"group_name": "Информация об организации", // название группы полей, при указании несуществующей группы полей в таблицу будет добавлена запись.
"possible_values": ["первое значение", "второе значение"], // список возможных значений, доступно только для поля формата "list"
"regexp": "[0-9]{1,3}", // регулярное выражение, доступно только для полей форматов "string", "text", "int", "float"
"min_length": "2", // минимальная длина, доступно только для полей форматов "string", "text"
"max_length": "25", // максимальная длина, доступно только для полей форматов "string", "text"
"is_required": "t", // обязательное ли поле: "t", "f"
"default_value": "РТ, г.Москва", // значение по умолчанию, доступно для всех форматов полей, за исключением формата "geometry",
// значение задается с соответствии с форматом поля (текст, число, дата, булево значение)
"visible": "t", // видимость данного поля при отображении полной информации по задаче: "t", "f"
"is_for_all": "f", // доступно ли данное поле для всех типов новостей (видов работ): "t", "f"
"news_type_ids": "["1", "2"]", //массив id типов новостей, для которых поле доступно, если оно не доступно всем типам новостей
"order": "10" // номер данного поля для отображения в списке настраиваемых полей
}
[AI] PUT /custom_field/:id
Редактирование настраиваемого поля.
Формат поля изменить нельзя, т.к. это может вызвать массовую некорректность данных настраиваемых полей в задачах.
// IN --->
{
"name": "Адрес филиала организации", // измененное название поля
"group_name": "Информация о филиалах организации", // измененное название группы полей
"possible_values": ["первое значение", "второе значение", "третье значение"], // список возможных значений, доступно только для поля формата "list"
"regexp": "[0-9]{1,3}", // регулярное выражение, доступно только для полей форматов "string", "text", "int", "float"
"min_length": "5", // минимальная длина, доступно только для полей форматов "string", "text"
"max_length": "50", // максимальная длина, доступно только для полей форматов "string", "text"
"is_required": "f", // обязательное ли поле: "t", "f"
"default_value": "РТ, г.Казань", // значение по умолчанию, доступно для всех форматов полей, за исключением формата "geometry",
// значение задается с соответствии с форматом поля (текст, число, дата, булево значение)
"visible": "f" // видимость данного поля при отображении полной информации по задаче: "t", "f"
}
Если поле не существует или логически удалено, клиенту возвращается статус 404.
При возникновении одной из следующих ситуаций клиенту возвращается статус 400:
- Передано поле possible_values, но формат настраиваемого поля не «list»;
- передано поле regexp, но формат не «string», «text», «int» или «float»;
- переданы поля min_length или max_length, но формат не «string» или «text»;
- передано поле default_value, но формат «geometry»;
- значение default_value (переданное или текущее)
- не соответствует формату поля (для форматов «bool», «int», «float», «date»);
- и/или не проходит валидацию по regexp/min_length/max_length;
- и/или не является одним из possible_values (для поля формата «list»).
Если массив «possible_values» не будет передан, то элементы списка не изменятся. При передаче массива «possible_values» все предыдущие значения списка будут удалены.
// OUT <---
{
"res": 1,
"resText": "",
"id": "123", // id нового поля
"name": "Адрес филиала организации", // название поля
"translit": "string",// транслитерация названия поля
"format": "text", // формат данных поля, возможные значения: "int", "float", "bool", "geometry", "string", "text", "list", "date"
"group_name": "Информация о филиалах организации", // название группы полей
"possible_values": ["первое значение", "второе значение", "третье значение"], // список возможных значений, доступно только для поля формата "list"
"regexp": "[0-9]{1,3}", // регулярное выражение, доступно только для полей форматов "string", "text", "int", "float"
"min_length": "5", // минимальная длина, доступно только для полей форматов "string", "text"
"max_length": "50", // максимальная длина, доступно только для полей форматов "string", "text"
"is_required": "f", // обязательное ли поле: "t", "f"
"default_value": "РТ, г.Казань", // значение по умолчанию, доступно для всех форматов полей, за исключением формата "geometry",
// значение задается с соответствии с форматом поля (текст, число, дата, булево значение)
"visible": "f", // видимость данного поля при отображении полной информации по задаче: "t", "f"
"is_for_all": "f", // доступно ли данное поле для всех типов новостей (видов работ): "t", "f"
"news_type_ids": "["1", "2"]", //массив id типов новостей, для которых поле доступно, если оно не доступно всем типам новостей
"order": "10" // номер данного поля для отображения в списке настраиваемых полей
}
[AI] DELETE /custom_field/:id
Логическое удаление настраиваемого поля.
Если поле не существует или логически удалено, клиенту возвращается статус 404.
// OUT <---
{
"res": 1,
"resText": ""
}
[AI] POST /custom_field/sort
Ручная сортировка настраиваемых полей.
Сортировке подлежат только неудаленные настраиваемые поля.
Отсортированный список будет сохраняться в БД и отдаваться клиентам при последующих запросах списка (в ответе к данному запросу, а также в ответе на GET-запрос /news/custom_fields).
1. Сортировка ведется по полю order типа integer.
2. Для ручной сортировки будет добавлен POST-запрос /custom_field/sort, который можно будет выполнить неоднократно.
3. В теле POST-запроса /custom_field/sort клиент должен будет передать id-шники настраиваемых полей в отсортированном им порядке:
// IN --->
{ "ids": [4, 1, 3, 6, 2, 5]
}
Если переданный список id-шников будет некорректным, в ответе будет выдан BadRequest.
Корректность списка id-шников проверяется по следующим пунктам:
- неверный формат переданных данных,
- передача несуществующих id-шников,
- передача дублирующихся id-шников,
- передача id-шников удаленных настраиваемых полей,
- передача неверного количества id-шников (должны быть переданы все существующие в БД id-шники).
4. В БД будет произведен UPDATE: порядок полученных id-шников будет занесен в таблицу issues.custom_fields в столбец order.
5. Пользователю в ответ на POST-запрос /custom_field/sort, а также в ответ на GET-запрос /news/custom_fields будет выдаваться список настраиваемых полей, отсортированный в указанном порядке.
6. Для новых настраиваемых полей order будет назначаться равным 0. В БД также имеются настраиваемые поля с order = null (созданные до ввода дефолтного значения order = 0).
Настраиваемые поля с order , равным 0 или null, будут располагаться в списке после отсортированных по order полей, и они будут отсортированы по полю id.
// OUT <---
{
"res": 1,
"resText": "",
"custom_fields": [
{
"id": "19",
"name": "Знак зодиака (string, len<=8)",
"translit": "Znak_zodiaka__string__len<=8_",
"format": "string",
"group_name": "",
"possible_values": null,
"regexp": "",
"min_length": "0",
"max_length": "8",
"is_required": "f",
"default_value": "",
"visible": "t",
"is_for_all": "t",
"order": "1",
"news_type_ids": [
"14"
]
},
{
"id": "9",
"name": "Доп.поле для тестов (5-10)",
"translit": "Dop_pole_dlya_testov",
"format": "text",
"group_name": "",
"possible_values": null,
"regexp": "",
"min_length": "5",
"max_length": "10",
"is_required": "f",
"default_value": "12345",
"visible": "t",
"is_for_all": "t",
"order": "2",
"news_type_ids": []
},
...
]
}
Cerebellum-Issue-type-groups
Группировка видов работ
У некоторых клиентов в базе существует очень большое количество видов работ — несколько десятков и более. Из-за этого трудно выбрать какой-то конкретный вид из выпадающего списка при, скажем, создании задачи. Для решения проблемы предлагается организовать группировку видов работ. Группа — это новая сущность в БД и REST, которая характеризуется только id и именем. Каждый вид работ может принадлежать ровно одной группе либо не принадлежать ни одной из них. Клиентские программы при старте помимо списка видов работ будут запрашивать список групп и самостоятельно отражать группировку в своем интерфейсе так, как это будет удобно пользователю.
Т.к. группировка является необязательной (вид работ может не входить ни в одну из групп), то при создании и редактировании вида работ id группы может опускаться. Этим достигается совместимость с более ранними версиями клиентов.
Настоятельных требований по вложенности групп в группы не поступало, поэтому такую задачу мы не выполняем. Срочной необходимости сделать группы «назначаемыми» (т.е. чтобы группы также были и видами работ) тоже нет. Реализация этого потребовала бы использовать для групп ту же самую таблицу в БД, что и для видов работ. Можно предположить, что в дальнейшем потребовалось бы сделать «назначаемыми» не все группы, но только некоторые из них. Возникает возня с флагами назначения и проч. Но самой большой проблемой будет наличие устаревших клиентов, которые воспримут неназначаемые группы как самостоятельные виды работ. Чтобы избежать таких проблем, группы реализуются как отдельная сущность.
База данных
Таблица issues.type_groups, связана с issues.types по fk issues.types.group_id.
Название колонки | Тип | NULL?
------------------------+----------+------
id | int | f
name | varchar| f
Модели
Добавляется новая модель models.Group с двумя свойствами — id и name.
В models.Type добавляется поле Group group и соответствующие getter и setter. Поле связывается с БД через аннотацию @ManyToOne
. Getter помечается как @JsonIgnore
, чтобы предотвратить полную выгрузку группы на клиент. Вместо всей группы будет выгружаться только её id; для этого создается метод getGroupId()
. В getter’е нужно предусмотреть, чтобы при отсутствии группы не возникал NPE.
REST
В запрос GET /newstype добавляется поле group, содержащее информацию о группе, в которую попадает данный вид работ. Это происходит автоматически за счет добавления getter’а getGroupId() в модель models.Type
// ...
"group_id": "1" // или null в случае, если вид работ не привязан к группе
// ...
Запросы POST /newstype и PUT /newstype должны позволять задавать группу, к которой привязан вид работ. Для этого в form.TypeIn и form.TypeUpdate добавляются поля Integer group_id:
- значение null (либо отсутствие поля в JSON) означает, что нужно оставить текущее значение;
- значение 0 означает, что нужно удалить этот вид работ из текущей группы;
- положительные значения трактуются как id группы, к которой нужно привязать этот вид работ;
- прочие значения являются некорректными.
Например:
// PUT /newstype/5
{
"group_id": 2
}
// ответ сервера
{
"res": "1", "resText": "",
"newstype": {
// ...
"group": {
"id": "2",
"name": "имя только назначенной группы видов работ"
}
// ,...
}
}
[AI] POST /newstype/group
Создать группу.
/* IN --> */ {
"name": "имя вида работ, обязательное поле"
}
/* OUT <-- */ {
"res": "1", "resText": "",
"group": {
"id": "1",
"name": "имя группы работ"
}
}
[AI] PUT /newstype/group/:id
Изменить группу
/* IN --> */ {
"name": "измененное имя вида работ"
}
/* OUT <-- */ {
"res": "1", "resText": "",
"group": {
"id": "1",
"name": "измененное имя группы работ"
}
}
[AI] GET /newstype/group/:id
Получить группу.
/* OUT <-- */ {
"res": "1", "resText": "",
"group": {
"id": "1",
"name": "имя группы работ"
}
}
[AI] DELETE /newstype/group/:id
Удалить группу.
/* OUT <-- */ {
"res": "1", "resText": "" // стандартный ответ
}
[AI] GET /newstype/group/list
Получить список всех групп.
/* OUT <-- */ {
"res": "1", "resText": "",
"groups": [
{
"id": "1",
"name": "имя группы работ"
}
// , ...
]
}
Изменить тип новости, добавив его в группу (при этом происходит проверка на существование данной группы):
/* IN --> */ {
"name":"новый тип","icon":"icon_158.png","icon3d":"icon3d_158.png","map_icon":"default_iconmap.png","map_icon_highlight":"default_iconmap_highlight.png",
"default_type":"f","period_of_review":"2","period_of_review_in_sec":"172800","deadline_type":"1","departments":[1,2,3],"group_id":"8"
}
/* OUT <-- */ {
"res":1,"resText":"","newstype":{"id":"8","name":"новый тип","icon":"icon_158.png","icon3d":"icon3d_158.png","map_icon":"default_iconmap.png",
"map_icon_highlight":"default_iconmap_highlight.png","map_icon_highlight_done":"default_iconmap_highlight.png","default_type":"f",
"period_of_review":"2","icon3d_done":"icon3d_done_155.png","icon_done":"icon_done_155.png","map_icon_done":"map_icon_done_155.png",
"iconmap":null,"iconmap_highlight":null,"iconmap_done":null,"iconmap_highlight_done":null,"period_of_review_in_sec":"172800",
"deadline_type":"AT_UPDATE","departments":["1","2","3"],"group_id":"8",
"news_type_id":"8","logo":"icon3d_158.png"}
}
Cerebellum_Type-sorting
Сортировка видов работ
Для удобства работы клиентов с видами работ предлагается организовать ручную сортировку видов работ.
Пользователи клиентских программ смогут сортировать вручную список видов работ.
Отсортированный список будет сохраняться в БД и отдаваться клиентам при последующих запросах списка (в ответе к данному запросу, а также в ответах на GET-запросы /newstype, /newstype/all).
Реализация
1. В БД в таблицу issues.types будет добавлена колонка order_key типа integer, которая по умолчанию примет значения колонки id для каждого элемента таблицы.
2. Для ручной сортировки будет добавлен POST-запрос /newstype/sort, который можно будет выполнить неоднократно.
3. Запрос будет доступен пользователям со следующими ролями: главный администратор, главный инспектор, администратор организации, инспектор организации.
4. В теле POST-запроса /newstype/sort клиент должен будет передать id-шники видов работ в отсортированном им порядке:
NewstypesSortJson.txt
{«ids»:[868,708,14,165,7,9,13,2,10,3,1,992,970,1330,1331,1009,1332,1334,1333,1329,1327,829,1328,608,649,8,749,1274,1279,1284,1289,1294,1299,809,
12,888,4,1030,11,5,908,909,1326,6,871,872,689]}
// IN --->
{ "ids": [4, 1, 3, 6, 2, 5]
}
Если переданный список id-шников будет некорректным, в ответе будет выдан BadRequest.
Корректность списка id-шников проверяется по следующим пунктам:
- неверный формат переданных данных,
- передача несуществующих id-шников,
- передача неверного количества id-шников (должны быть переданы все существующие в БД id-шники).
5. В БД будет произведен UPDATE: порядок полученных id-шников будет занесен в таблицу issues.types в столбец order_key.
6. Пользователю в ответ на POST-запрос /newstype/sort, а также в ответ на GET-запросы /newstype, /newstype/all будет выдаваться список видов работ, отсортированный в указанном порядке.
Ответ на POST-запрос /newstype/sort будет аналогичен ответу на GET /newstype/all.
// OUT <---
{
"res": 1,
"resText": "",
"newstype": [
{
"id": "4",
"name": "Аварии",
"icon": "1_icon_7.jpg",
"icon3d": "2.png",
"period_of_review": null,
"period_of_review_in_sec": null,
"deadline_type": "AT_CREATE",
"departments": [
"1",
"3"
],
"group_id": "7",
"order_key": "1",
...
},
{
"id": "1",
"name": "Неисправность коммуникаций",
"icon": "icon_149.png",
"icon3d": "icon3d_149.png",
"period_of_review": null,
"period_of_review_in_sec": null,
"deadline_type": "AT_CREATE",
"departments": [
"1",
"2"
],
"group_id": null,
"order_key": "2",
...
},
...
]
}
7. Для новых видов работ order_key будет назначаться равным id.
8. Сортировка внутри групп видов работ будет реализована на клиентах.
Cerebellum-Fast-issues-and-points
Быстрый запрос для получения задач и точек /news/points
Выгружаемые поля
В ответе к запросу /news/points будут выгружаться следующие поля:
"id", // id задачи
"title", // заголовок задачи
"assigned_status", // id параметра assigned_status
"lon", // longitude (долгота точки, привязанной к задаче)
"lat" // latitude (широта точки, привязанной к задаче)
Пример запроса (с параметрами limit, page):
/news/points?limit=3&page=1
Формат ответа:
{
"res": 1,
"resText": "",
"news_list": [
{
"id": "788975",
"title": "Тест",
"assigned_status": "1",
"lon": "61.2374578267761",
"lat": "55.6351020633081"
},
{
"id": "788974",
"title": "Тест",
"assigned_status": "1",
"lon": "49.0868144141876",
"lat": "55.8458252690369"
},
{
"id": "788953",
"title": "Задание",
"assigned_status": "4",
"lon": null,
"lat": null
}
],
"count_news": "43"
}
Параметры limit, page
В запросе /news/points могут быть указаны количественные параметры:
- limit — количество задач, отображаемых на одной странице (по умолчанию, limit=25),
- page — номер отображаемой страницы (по умолчанию, page=1)
Пример запроса:
/news/points?limit=5&page=4
Ответ:
{
"res": 1,
"resText": "",
"news_list": [
{
"id": "788662",
"title": "Тестовая задача",
"assigned_status": "3",
"lon": "55.56",
"lat": "46.67"
},
{
"id": "788653",
"title": "Test photo preview del",
"assigned_status": "2",
"lon": "49.1966755662001",
"lat": "55.8087218268519"
},
{
"id": "788627",
"title": "Тест загрузки файлов",
"assigned_status": "1",
"lon": "49.0868144141876",
"lat": "55.7591952658046"
},
{
"id": "788626",
"title": "Тест загрузки файлов",
"assigned_status": "1",
"lon": "49.1087866445901",
"lat": "55.7839664493374"
},
{
"id": "788625",
"title": "Тест загрузки файлов",
"assigned_status": "1",
"lon": "49.0648421837851",
"lat": "55.8334614039231"
}
],
"count_news": "43"
}
Фильтры
Для запроса /news/points доступны следующие параметры фильтрации:
- withAssigned — при значении withAssigned=true в список добавляются не новые и не закрытые новости, назначенные пользователю, либо его ведомству (если он админ) новости
- withClosed — при значении withClosed=true в список добавляются новости со статусом выполнено, назначенные пользователю, либо его ведомству (если он админ)
- withArchive — при значении withArchive=true, в список добавляются новости, которые в архиве (по умолчанию берутся текущие)
- onlyMy — при значении onlyMy=true, в списке отображаются только новости, созданные пользователем. Параметры withAssigned, withClosed, onlyStatus при этом игнорируются
- onlyStatus — отображаются новости с соответствующими статусами. Id статусов передаются через запятую. Например, onlyStatus=2,3
- onlyStates — отображаются новости, которые находятся в соответствующих состояниях. Id статусов передаются через запятую. Например, onlyStates=6,11
- onlyAssigned — при значении onlyAssigned=true отображаются новости, которые не новые и не выполнены, но назначены.
- category_id — фильтр по категориям новостей. Id категорий передаются через запятую. Например, category_id=1,2
- type_id — фильтр по типам новостей. Id типов передаются через запятую. Например, Например, type_id=3,4,5
- gtUpdateDate — отображаются новости, дата обновления которых больше указанной даты (дата указывается в Timestamp, например, gtUpdateDate=1440835402).
- ltUpdateDate — отображаются новости, дата обновления которых меньше указанной даты (дата указывается в Timestamp, например, ltUpdateDate=1440835402).
- gtCreateDate — отображаются новости, дата создания которых больше указанной даты (дата указывается в Timestamp, например, gtCreateDate=1440835402).
- ltCreateDate — отображаются новости, дата создания которых меньше указанной даты (дата указывается в Timestamp, например, ltCreateDate=1440835402).
- gtDeadline — отображаются новости, параметр deadline которых больше указанной даты (дата указывается в Timestamp, например, gtDeadline =1440835402).
- ltDeadline — отображаются новости, параметр deadline которых меньше указанной даты (дата указывается в Timestamp, например, ltDeadline =1440835402).
- assigned_organization_id — отображаются новости, которые назначены на указанные организации. Id организаций передаются через запятую. Например, assigned_organization_id=1,2,292
- assigned_user_id — отображаются новости, которые назначены на указанных пользователей. Id пользователей передаются через запятую. Например, assigned_user_id=616,618
- user_id — отображаются новости, созданные указанными пользователями. Id пользователей передаются через запятую. Например, user_id=616,618
- confirmed — отображаются новости, которые имеют указанное значение параметра confirmed. Например, confirmed=1
- search — отображаются новости, удовлетворяющие текстовому поиску указанного значения по значениям параметров id, text, title. Например, search=7891
- customFields — отображаются новости, отфильтрованные по значениям кастомных полей. Например, customFields=[{«name»:»Dop_pole_dlya_testov»,»op»:»EQ»,»value»:»12345″},{«name»:»Telefon__int__88432000555__»,»op»:»NOT NULL»}].
Более подробно фильтрация по кастомным полям описана в разделе Фильтрация задач по custom-полям - expired — при значении expired=true отображаются непросроченные новости (значение параметра deadline меньше текущей даты и параметр confirmed=1), при значении expired=false отображаются просроченные новости (значение параметра deadline больше текущей даты или значение параметра confirmed отлично от 1)
Примеры:
/news/points?limit=10&page=1&withAssigned=true&withArchive=true&onlyStatus=2,3&onlyStates=6,11&category_id=1,2
/news/points?limit=10&page=1>UpdateDate=1440835402<UpdateDate=1443513802>CreateDate=1438157002<CreateDate=1443513802&expired=false
/news/points?limit=10&page=1&assigned_organization_id=2,292&assigned_user_id=618,625&user_id=6&confirmed=1
/news/points?limit=10&page=1&search=тест&customFields=[{"name":"Dop_pole_dlya_testov","op":"EQ","value":"12345"},{"name":"Telefon__int__88432000555__","op":"NOT NULL"}]
Сортировки запроса
Для запроса /news/points можно задать следующие параметры для сортировки списка заданий:
- sortBy — поле, по которому осуществляется сортировка. По умолчанию сортировка ведется по полю news_date.
Допустимые для сортировки поля:
- id,
- news_date,
- update_date,
- create_date,
- deadline,
- assigned_organization_id,
- assigned_user_id,
- user_id,
- news_type_id,
- category_id,
- confirmed
- sortDirection — направление сортировки. По умолчанию — DESC.
Допустимые варианты: ASC, DESC
Пример:
/news/points?limit=5&page=1&sortBy=create_date&sortDirection=ASC
Cerebellum_Фильтрация_задач_по_custom-полям
Фильтрация задач по custom-полям
В запрос GET /listAfterId для фильтрации по настраиваемым полям добавляется новый параметр customFields. Значение содержит JSON-массив с объектами, каждый из которых содержит имя поля, тип операции и значение. Пример:
http://...?customFields=[{"name":"Dop_pole_dlya_testov","op":"EQ","value":"12345"},{"name":"Telefon__int__88432000555__","op":"NOT NULL"}]
Список возможных операций:
- EQ («равно»)
- NE («не равно»)
- GT («больше»)
- LT («меньше»)
- GE («больше или равно»)
- LE («меньше или равно»)
- CONTAINS («содержит»)
- BEGINS («начинается с»)
- ENDS («заканчивается на»)
- NULL (не требует value)
- NOT NULL (не требует value)
- EMPTY (не требует value)
- NOT EMPTY (не требует value)
Заметки по реализации
Про синтаксис вытаскивания значений из JSON в Postgres можно почитать здесь: http://www.postgresql.org/docs/9.3/static/functions-json.html
Пример запроса на базе trust:
select * from issues.issues where issues.custom_fields->'Dop_pole_dlya_testov'->>'value' = '12345'
В коде Cerebellum должна использоваться примерно следующая конструкция:
.from("customFields").as(value -> {
JsonNode values = gs.Json.parse((String) value);
ConditionSet set = new ConditionSet();
// перебираем все значения в values,
// создаем новый Condition на основе переданных
// операции, колонки и значения, и
// добавляем в set
// ...
// объединяем все условия на настраиваемые поля
// логическим И.
return set.and();
})
cerebellum-rest-auth
Авторизация и регистрация
Регистрация пользователей и связанные запросы
[gt] POST /registration
Добавление пользователя.
// IN --->
{
"login": "login", //логин
"paswd": "12345", //пароль
"email" : "test@gradoservice.ru", //email
"status": 2, //правовой статус: 1 - юридическое лицо, 2 - физическое лицо
"fio": "Иванов И.И.", //ФИО физического лица или представителя юридического лица
"phone": "8432000555", //телефон физического лица, необязательный параметр
"address": "г.Казань, ул.Назарбаева, д.25, кв.125", //адрес физического лица, необязательный параметр
"fax": "8432000555", //факс физического лица, необязательный параметр
"inn": 161111111111, //ИНН физического лица, необязательный параметр
"passport": "9212 111111", //паспортные данные физического лица, необязательный параметр
"ur_fio": "ООО Градосервис", //название организации (юридического лица), необязательный параметр
"ur_address": "г.Казань, ул.Назарбаева, д.27, офис 6-12", //адрес организации (юридического лица), необязательный параметр
"ur_phone": "8432000555", //телефон организации (юридического лица), необязательный параметр
"ur_fax": "8432000555", //факс организации (юридического лица), необязательный параметр
"ur_inn": 1611111111, //ИНН организации (юридического лица), необязательный параметр
"ur_kpp": 160011111, //КПП организации (юридического лица), необязательный параметр
"bank": "Сбербанк", //наименование, реквизиты банка организации (юридического лица), необязательный параметр
"bank_kpp": 775003035, //КПП организации (юридического лица), необязательный параметр
"bank_bik": 044525225, //БИК организации (юридического лица), необязательный параметр
"bank_schet": "12345678901234567890", //номер счета в банке (юридического лица), необязательный параметр
"department_id": 1 //id организации, необязательный параметр
}
// OUT <---
{
"res": 1,
"resText": "",
"id": "6923", //id пользователя
"login": "login", //логин пользователя
"fio": "ООО Градосервис", //ФИО физического лица или название организации (юридического лица)
"uvd_department_id": "62", //id ведомства, задания которого будут отображаться в интерфейсе map3d_mcs для AРМ Губернатора
"users_site_type": "2", //принадлежность пользователя ведомству ("1") или организации ("2")
"satellites_view": "t", "t", //видимость спутников в АРМ Губернатора: "t" или "f"
"email": "kzn.alina@gmail.com", //email
"role_id": "10",
"matrix": "(-0.756602,0.653875,0.00069758),(0.21426,0.246913,0.945054),(0.617775,0.715179,-0.326914),(2.34475e+06,2.7075e+06,5.26909e+06)",
//матрица перелета для АРМ Губернатора
"department_id": "514" //id ведомства/организации
}
[gt] POST /registration/checklogin
Проверка логина на существование в системе.
Проверка доступности логина для использования.
// IN <---
{
"login":"user_test" //логин пользователя
}
// OUT --->
{
"res": 1,
"resText": "",
"check": "f" //true - логин не существует в системе, и он доступен для использования; false - логин существует в системе, и он не доступен для использования;
}
[gt] GET /registration/form
Список полей регистрационной формы.
// OUT --->
{
"res": 1,
"resText": "",
"fields": { //поля
"general": [ //общие поля
{
"values": "", //значения, которые может принимать поле
"name": "login", //английское название параметра
"rusName": "Логин", //русское название параметра
"required": "t" //обязательное поле или нет: true, false
},
{
"values": "",
"name": "paswd",
"rusName": "Пароль",
"required": "t"
},
{
"values": "",
"name": "email",
"rusName": "E-mail",
"required": "t"
},
{
"values": [
{
"value": "1",
"rusName": "Юридическое лицо"
},
{
"value": "2",
"rusName": "Физическое лицо"
}
],
"name": "status",
"rusName": "Правовой статус",
"required": "t"
}
],
"physical_person": [ //поля для физических лиц
{
"values": "",
"name": "fio",
"rusName": "ФИО",
"required": "t"
},
{
"values": "",
"name": "address",
"rusName": "Почтовый адрес",
"required": "t"
},
{
"values": "",
"name": "phone",
"rusName": "Телефон",
"required": "f"
},
{
"values": "",
"name": "fax",
"rusName": "Факс",
"required": "f"
},
{
"values": "",
"name": "inn",
"rusName": "ИНН",
"required": "f"
},
{
"values": "",
"name": "passport",
"rusName": "Паспортные данные",
"required": "f"
}
],
"legal_person": [ //поля для юридических лиц
{
"values": "",
"name": "ur_fio",
"rusName": "Полное наименование организации с указанием организационно-правовой формы",
"required": "t"
},
{
"values": "",
"name": "ur_address",
"rusName": "Почтовый адрес",
"required": "t"
},
{
"values": "",
"name": "ur_phone",
"rusName": "Телефон",
"required": "f"
},
{
"values": "",
"name": "ur_fax",
"rusName": "Факс",
"required": "f"
},
{
"values": "",
"name": "ur_inn",
"rusName": "ИНН",
"required": "f"
},
{
"values": "",
"name": "kpp",
"rusName": "КПП",
"required": "f"
},
{
"values": "",
"name": "bank",
"rusName": "Название банка",
"required": "f"
},
{
"values": "",
"name": "bank_kpp",
"rusName": "КПП банка",
"required": "f"
},
{
"values": "",
"name": "kpp",
"rusName": "КПП",
"required": "f"
},
{
"values": "",
"name": "bank_bik",
"rusName": "БИК банка",
"required": "f"
},
{
"values": "",
"name": "bank_schet",
"rusName": "Расчетный счет",
"required": "f"
}
]
},
"url": "/rest/registration" //URL для отправки полей на регистрацию
}
[A] POST /users
Служебный запрос. Упрощенная схема регистрации пользователей для тестов.
// IN --->
{
"login": "login", //логин
"paswd": "12345", //пароль
"email" : "test@gradoservice.ru", //email, необязательный параметр
"phone": "8432000555", //телефон, необязательный параметр
"ur_fio": "Иванов и КО", //название юр.лица, , необязательный параметр
"ur_address": "Казань", //адрес юр.лица, необязательный параметр
"status": 2, //правовой статус: "1" - юридическое лицо, "2" - физическое лицо, необязательный параметр
"organization_id": 1, //id организации, необязательный параметр
"role_id": 7, //id роли пользователя, необязательный параметр: "6", "7" - обычный пользователь, "10" - админ ведомства, "8" - администратор всех ведомств
"fio": "Иванов И.И." //ФИО пользователя, необязательный параметр
}
// OUT <---
{
"res": 1,
"resText": "",
"user": {
"id": "6391",
"login": "login",
"fio": "Иванов И.И.",
"uvd_department_id": "62", //id ведомства, задания которого будут отображаться в интерфейсе map3d_mcs для AРМ Губернатора
"users_site_type": "2", //принадлежность пользователя ведомству ("1") или организации ("2")
"satellites_view": "t", //видимость спутников в АРМ Губернатора: "t" или "f"
"role_id": "7", //id роли пользователя: "6", "7" - обычный пользователь, "10" - админ ведомства, "8" - администратор всех ведомств
"matrix": "(-0.756602,0.653875,0.00069758),(0.21426,0.246913,0.945054),(0.617775,0.715179,-0.326914),(2.34475e+06,2.7075e+06,5.26909e+06)",
//матрица перелета для АРМ Губернатора
"department_id": "1" //id ведомства/организации
}
}
[A] DELETE /users/:id
Удаление пользователя (логическое удаление).
// OUT <---
{
"res": 1,
"resText": ""
}
[A] DELETE /users/:id/hard
Удаление пользователя (физическое удаление для тестов).
// OUT <---
{
"res": 1,
"resText": ""
}
[t] POST /mobile/register
Запрос на регистрацию для получения PUSH-сообщений. Запрос поступает с мобильного устройства.
// IN --->
{ //уникальный адрес устройства для получения PUSH-сообщений, генерируется при установке приложения
"regId":"APA91bGmD0VObEd-KKuJ9J826c4o4VaxKL9VhvBQaecj3bY0RmrSp2aVmpsujTRPvYRDTvZDhVB9kxke4Q0pcivIM61PsPDd_Eh3k-0DUVdSSpXmgFAM4lsvxpuW1Re9dfQ2mSWMLiCr",
//полное имя приложения
"fqn":"android://ru.gs.mapmobile"
}
// OUT <---
{
"res": 1,
"resText": ""
}
[t] POST /mobile/unregister
Запрос на отмену регистрации для получения PUSH-сообщений. Запрос поступает с мобильного устройства.
// IN --->
{ //уникальный адрес устройства для получения PUSH-сообщений, генерируется при установке приложения
"regId":"APA91bGmD0VObEd-KKuJ9J826c4o4VaxKL9VhvBQaecj3bY0RmrSp2aVmpsujTRPvYRDTvZDhVB9kxke4Q0pcivIM61PsPDd_Eh3k-0DUVdSSpXmgFAM4lsvxpuW1Re9dfQ2mSWMLiCr",
//полное имя приложения
"fqn":"android://ru.gs.mapmobile"
}
// OUT <---
{
"res": 1,
"resText": ""
}
Авторизация пользователей
[gt] POST /authentication
Запрос на авторизацию.
// IN --->
{
"action": "post", //необходимо явно указать тип запроса "post" для соответствия с MapAdmin
"login": "login", //логин
"password": "password", //пароль
"rememberme": "1" //настройка сохранения параметров авторизации: "1" - сохранить, "0" - не сохранять
}
// OUT <---
{
"res": 1,
"resText": "",
"id":"6", //id пользователя
"login":"login", //логин пользователя
"fio":"ФИО", //имя пользователя
"uvd_department_id":"62", //id ведомства, задачи которого будут отображаться в интерфейсе map3d_mcs для AРМ Губернатора
"users_site_type":"2", //принадлежность пользователя ведомству ("1") или организации ("2")
"satellites_view":"t", //видимость спутников в АРМ Губернатора: "t" или "f"
"role_id":"8", //id роли пользователя
"email": "test@gmail.com", //email пользователя
"matrix":"(-0.756602,0.653875,0.00069758),(0.21426,0.246913,0.945054),(0.617775,0.715179,-0.326914),(2.34475e+06,2.7075e+06,5.26909e+06)",
//матрица перелета для АРМ Губернатора
"department_id":null, //id ведомства
"map_extent": [ //координаты положения карты: ["min lon","min lat","max lon","max lat"]
"46.0927078887718",
"53.9919087034184",
"55.2997131017069",
"56.6837870890742"
],
"token":"87e3d7ae036b752cc90bd093bbfa1634" //token
}
cerebellum-rest-requests
Вспомогательные запросы
[t] POST /login
Авторизация в системе.
// IN --->
{
"login": "login", //логин
"password": "password" //пароль
}
В ответе на запрос отображается сообщение об успешной авторизации.
[t] GET /login
Авторизация через браузер.
В ответе на запрос отображается форма для ввода регистрационных данных.
[t] POST /logout
Выход из системы.
В ответе на запрос отображается сообщение об успешном выходе.
[t] GET /loginRest
Служебный запрос для получения token’а через браузер.
В браузере после ввода логина
и пароля
можно будет получить token.
// OUT <---
{
"res": 1,
"resText": "",
"id":"6", //id пользователя
"login":"login", //логин пользователя
"fio":"ФИО", //имя пользователя
"uvd_department_id":"62", //id ведомства, новости которого будут отображаться в интерфейсе map3d_mcs для AРМ Губернатора
"users_site_type":"2", //принадлежность пользователя ведомству ("1") или организации ("2")
"satellites_view":"t", //видимость спутников в АРМ Губернатора: "t" или "f"
"role_id":"8", //id роли пользователя
"matrix":"(-0.756602,0.653875,0.00069758),(0.21426,0.246913,0.945054),(0.617775,0.715179,-0.326914),(2.34475e+06,2.7075e+06,5.26909e+06)", //матрица перелета для АРМ Губернатора
"department_id":null, //id ведомства
"map_extent": [ //координаты положения карты: ["min lon","min lat","max lon","max lat"]
"46.0927078887718",
"53.9919087034184",
"55.2997131017069",
"56.6837870890742"
],
"token":"87e3d7ae036b752cc90bd093bbfa1634" //token
}
[t] GET /hi
Приветственное сообщение.
// OUT <---
{
"res": 1,
"resText": "Hello, I am Cerebellum"
}
cerebellum-rest-configuration
Получение информации о настройках конфигурации: /configuration
/configuration
[t] GET /configuration
Получение информации о настройках конфигурации.
// OUT <---
{
"res": 1,
"resText": "",
"configuration": {
"onlyMyOrganization": false, //в системе отображается только организация текущего пользователя
//(значение параметра берется из конфигурационного файла application.conf)
"-Dfiles.localStorage": "c:/work/tmp", //локальное хранилище для загружаемых файлов (значение параметра берется из "VM Options")
"filesLocalStorage": "c:/work/tmp" //локальное хранилище для загружаемых файлов (если значение параметра не прописано в "VM Options",
//тогда оно берется из конфигурационного файла application.conf)
}
}
cerebellum-rest-version
Получение служебной информации о программе: /version
/version
[g] GET /version
Получение служебной информации о программе.
// OUT <---
{
"res": 1,
"resText": "",
"appname": "ActiveMap GS", //имя приложения
"build": "", //номер сборки
"timezone": "Europe/Moscow", //таймзона пользователя
"commit": "", //номер коммита
"link": "", //ссылка на сборку проекта в системе сборок
"version": "1.7.2", //версия MapAdmin
"branch": "", //имя ветки
"cerebellum": "0.10.0" //версия Cerebellum
}
cerebellum-rest-geo4me
Интеграция с Geo4me
[IA] POST /geo4me/organization
Создает в базе Cerebellum запись об организации в Geo4Me.
В реализацию запроса заложена проверка на реальное существование организации пользователя в Geo4me.
// IN --->
{
"login": "admin123", // логин админа для входа под этой организацией в Geo4Me
"password": "pass456" // пароль админа для входа под этой организацией в Geo4Me
}
// OUT <---
// в случае успеха
{
"res": 1, "resText": ""
}
- 400, если организация с таким id уже существует;
- 401, необходима авторизация в системе Geo4me;
- 403, ошибка авторизации в системе Geo4me;
- 400, неверный запрос в систему Geo4me;
- 404, ответ на запрос на сервере Geo4me не найден;
- 500, внутренняя ошибка сервера Geo4me.
[IA] POST /geo4me/organization/:geo4me-id/link/:active-map-id
Связать организацию Geo4Me с организацией ActiveMap по схеме один-ко-многим (одной организации в Geo4Me может соответствовать множество организаций в ActiveMap).
- geo4me-id — id «родительской» организации в Geo4Me;
- active-map-id — id «дочерней» организации в ActiveMap.
// OUT <---
// в случае успеха
{
"res": 1, "resText": ""
}
- 404, если организация с таким geo4me-id не существует (не была зарегистрирована в Cerebellum через POST /geo4me/organization);
- 404, если организация с таким active-map-id не существует;
- 400, если организация с active-map-id уже связана с другой организацией из Geo4me;
- если организация с geo4me-id уже привязана к организации с active-map-id, ошибки не происходит.
[IA] DELETE /geo4me/organization/:geo4me-id/link/:active-map-id
Удалить связь между организацией Geo4Me и организацией ActiveMap.
- geo4me-id — id «родительской» организации в Geo4Me;
- active-map-id — id «дочерней» организации в ActiveMap.
// OUT <---
// в случае успеха
{
"res": 1, "resText": ""
}
- 404, если организация с таким geo4me-id не существует (не была зарегистрирована в Cerebellum через POST /geo4me/organization);
- 404, если организация с таким active-map-id не существует;
- 400, если организации не связаны друг с другом.
[IA] GET/geo4me/organization/:geo4me-id/user
Список пользователей указанной организации Geo4me.
Организация Geo4me должна быть зарегистрирована в Cerebellum (через POST /geo4me/organization).
В списке выдаются пользователи Geo4me, имеющие связь с пользователями ActiveMap.
- geo4me-id — id организации в Geo4Me.
// OUT <---
{
"res": 1,
"resText": "",
"geo4me_users": [ //список пользователей Geo4me
{
"id": "1938",//id пользователя Geo4me
"active_map_user": { //данные о пользователе ActiveMap
"id": "616", //id пользователя ActiveMap
"login": "tadm", //логин пользователя ActiveMap
"fio": "Администратор Отдела Тестирования T", //ФИО пользователя ActiveMap
"role_id": "10", //id роли пользователя ActiveMap
"department_id": "2" //id организации пользователя ActiveMap
}
},
... // следующие элементы списка пользователей Geo4me
]
}
- 404, если организация с таким geo4me-id не существует (не была зарегистрирована в Cerebellum через POST /geo4me/organization).
[IA] GET/departments/:active-map-id/geo4me
Получить организацию Geo4me, привязанную к организации ActiveMap с указанным active-map-id или null, если связанной организации не существует.
- active-map-id — id организации в ActiveMap.
// OUT <---
{
"res": 1,
"resText": "",
"geo4me_organization": {
"id": "941", //id организации Geo4me
"name": "Geo4me org" //название организации Geo4me
}
}
- 404, если организация с таким active-map-id не существует.
[IA] GET/geo4me/organization
Список организаций из Geo4me, зарегистрированных в Cerebellum (через POST /geo4me/organization).
// OUT <---
{
"res": 1,
"resText": "",
"geo4me_organizations": [ //список организаций Geo4me
{
"id": "99", //id организации Geo4me
"name": "Виноградники Краснодарского края" //название организации Geo4me
},
{
"id": "941",
"name": "Geo4me org"
},
... // следующие элементы списка организаций
]
}
[IA] PUT /geo4me/user/mapping
Задать соответствие между пользователями Geo4Me и пользователями ActiveMap.
Важно: при выполнении этого запроса существующее соответствие между пользователями Geo4Me и ActiveMap стирается!
Если не существует хотя бы одного пользователя Geo4me с указанным geo4me_user_id, такой пользователь создается в Cerebellum.
Проверка на реальное существование пользователя в системе Geo4me с указанным geo4me_user_id не реализована.
// IN --->
// массив объектов, каждый из которых задаёт соответствие
// один-к-одному.
[
// поставить в соответствие пользователю geo4me
// с id=15 пользователя activeMap с id=23.
{ "geo4me_user_id": 15,
"active_map_user_id": 23 },
// ...
]
// OUT <---
// в случае успеха
{
"res": 1, "resText": ""
}
- 404, если не существует хотя бы одного пользователя ActiveMap с указанным active_map_user_id;
- 400, неверный формат передаваемых данных для связи пользователей Geo4me и ActiveMap;
- 400, если хотя бы один geo4me-user-id указан дважды;
- 400, если хотя бы один active-map-user-id указан дважды.
[IA] POST /geo4me/user/:geo4me-user-id/link/:active-map-user-id
Связать пользователя Geo4Me с пользователя ActiveMap по схеме один-к-одному (одному пользователю в Geo4Me может соответствовать один пользователь в ActiveMap).
Если не существует пользователя Geo4me с указанным geo4me_user_id, такой пользователь создается в Cerebellum.
Проверка на реальное существование пользователя в системе Geo4me с указанным geo4me_user_id не реализована.
- geo4me-user-id — id пользователя в Geo4Me;
- active-map-user-id — id пользователя в ActiveMap.
// OUT <---
// в случае успеха
{
"res": 1, "resText": ""
}
- 404, если пользователь с таким active-map-user-id не существует;
- 400, если пользователь с таким geo4me-user-id уже привязан к другому пользователю ActiveMap;
- 400, если пользователь с таким active-map-user-id уже привязан к другому пользователю Geo4me;
- если привязка пользователя с geo4me-user-id к пользователю с active-map-user-id уже была произведена ранее, ошибки не происходит.
[IA] DELETE /geo4me/user/:geo4me-user-id/link/:active-map-user-id
Удалить связь между пользователем Geo4Me и пользователем ActiveMap.
Проверка на реальное существование пользователя в системе Geo4me с указанным geo4me_user_id не реализована.
- geo4me-user-id — id пользователя в Geo4Me;
- active-map-user-id — id пользователя в ActiveMap.
// OUT <---
// в случае успеха
{
"res": 1, "resText": ""
}
- 404, если пользователь с таким active-map-user-id не существует;
- 404, если пользователь с таким geo4me-user-id не существует (пользователь не был зарегистрирован в Cerebellum);
- 400, если пользователи не связаны.
[t] GET /geo4me/points
Получить точки всех пользователей в организации Geo4Me, к которой принадлежит текущий пользователь (на основе связки его организации в ActiveMap с организацией в Geo4Me).
// OUT <---
{
"res": 1, "resText": "",
"users": [
{ "id": 999, // id пользователя ActiveMap
"point": { // координаты местоположения пользователя
"lon": 50.0001, //координата longitude (долгота)
"lat": 50.0002 // координата latitude (широта)
}
}
]
}
- 400, если у текущего пользователя нет организации;
- 400, если организация текущего пользователя в ActiveMap не привязана к организации в Geo4Me;
- 401, необходима авторизация в системе Geo4me;
- 403, ошибка авторизации в системе Geo4me;
- 400, неверный запрос в систему Geo4me;
- 404, ответ на запрос на сервере Geo4me не найден;
- 500, внутренняя ошибка сервера Geo4me.
[t] GET /users/:active-map-user-id/geo4me
Получить пользователя Geo4me, связанного с пользователем ActiveMap с указанным active-map-user-id или null,
если связанного пользователя не существует.
Будет выдан пользователь Geo4me, зарегистрированный в Cerebellum.
Проверка на реальное существование пользователя в системе Geo4me не реализована.
- active-map-user-id — id пользователя в ActiveMap.
// OUT <---
{
"res": 1,
"resText": "",
"geo4me_user": {
"id": "1938", //id пользователя Geo4me
"active_map_user": { //данные пользователя ActiveMap
"id": "616", //id пользователя ActiveMap
"login": "tadm", //логин пользователя ActiveMap
"fio": "Администратор Отдела Тестирования T", //ФИО пользователя ActiveMap
"role_id": "10", //id роли пользователя ActiveMap
"department_id": "2" //id организации пользователя ActiveMap
}
}
}
- 404, если указанный пользователь ActiveMap не существует.