В мобильном приложении настроить доступ к сервису, который возвращает pdf файл
Добрый день. Есть созданый нами сервис (по образцу базового ReportService), который возвращает по записи детали объекта pdf-файл. На десктопной версии креатио работа с ним настроена, возникли сложности с реализацией аналогичного в мобильном приложении.
По подробностям: на десктопе сервис на странице записи детали по нажатию кнопки получает значение поля и в ответ открывает файл на новой странице. Как именно что-то подобное сделать для записей детали на мобильном приложении? Есть ли какие-то нюансы с открытием pdf в мобильном приложении креатио?
Нравится
Добрый день!
Позвольте привести пример скачивания и автоматического открытия файла с использованием базового FileService/GetFile (сервис и метод, которые триггерятся если в декстопной версии из детали с файлами выгрузить какой-либо файл) в мобильном приложении. Для этого:
1) Была создана кастомная кнопка в действиях на странице контакта в мобильном приложении
2) Был создан обработчик для нажатия на эту кнопку
Как это было достигнуто:
1) В конфигурации создать модуль UsrMyAction с кодом
Ext.define("Terrasoft.MyAction", {
extend: "Terrasoft.ActionBase",
config: {
useMask: false,
title: "MyActionTitle",
iconCls: Terrasoft.ActionIcons.Copy
},
execute: function(record) {
this.callParent(arguments);
var config = {
url: 'https://1168222internal-demo.creatio.com/0/rest/FileService/GetFile/e9eafee9-c4e4-4793-ad0a-003bd2c6a9b4/3bbbd5a8-8f8d-4570-8526-0488eb37da28',
success: function(fullPath, relativePath) {
Terrasoft.FileIntent.open({
path: relativePath
});
},
name: "Test_" + new Date().toDateString() + ".png"
};
Terrasoft.RequestManager.issueRequest({
requestFn: Terrasoft.FileTransfer.download,
requestFnConfig: config,
responseToStatusCodeFn: Terrasoft.FileTransfer.getStatusCodeFromException,
loginFailure: function(exception) {
Ext.callback(config.failure, config.scope, [exception]);
},
suppressRequestEvents: config.suppressRequestEvents,
scope: Terrasoft.FileTransfer
});
this.executionEnd(true);
}
});
В нем создать локал.строку с кодом MyActionTitle и каким-то значением для этой локал.строки (например "Call custom service").
2) В конфигурации создать модуль UsrMobileContactModuleConfig с кодом
Terrasoft.sdk.Actions.add("Contact", {
name: "myAction",
actionClassName: "Terrasoft.MyAction"
});
3) В манифесте мобильного приложения добавить:
"CustomSchemas": [
"UsrMyAction"
],
...
"Models": {
...
"Contact": {
...
"PagesExtensions": [
"UsrMobileContactModuleConfig"
]
Пример манифеста из демо сайта для тестов, где тестировалась логика – файл MobileApplicationManifestDefaultWorkplace.txt ниже:
{
"CustomSchemas": [
"UsrMyAction"
],
"SyncOptions": {
"SysSettingsImportConfig": [
"DefaultMessageLanguage"
],
"ModelDataImportConfig": [
{
"Name": "Contact",
"SyncColumns": []
},
{
"Name": "SysLanguage",
"SyncColumns": []
},
{
"Name": "ContactFile",
"SyncColumns": [
"Contact",
"CreatedOn",
"CreatedBy",
"Name",
"Data",
"Type",
"Size"
]
},
{
"Name": "FileGroup",
"SyncColumns": []
},
{
"Name": "ContactCommunication",
"SyncColumns": [
"CommunicationType",
"Number",
"Contact"
]
},
{
"Name": "CommunicationType",
"SyncColumns": []
},
{
"Name": "ContactAddress",
"SyncColumns": [
"AddressType",
"Country",
"Region",
"City",
"Address",
"Zip",
"Contact"
]
},
{
"Name": "AddressType",
"SyncColumns": []
},
{
"Name": "Country",
"SyncColumns": []
},
{
"Name": "Region",
"SyncColumns": []
},
{
"Name": "City",
"SyncColumns": []
},
{
"Name": "ContactAnniversary",
"SyncColumns": [
"Date",
"AnniversaryType",
"Contact"
]
},
{
"Name": "AnniversaryType",
"SyncColumns": []
},
{
"Name": "FileType",
"SyncColumns": []
},
{
"Name": "SocialMessage",
"SyncColumns": [
"EntityId"
]
}
]
},
"Modules": {},
"Models": {
"ContactFile": {
"RequiredModels": [
"ContactFile",
"FileGroup",
"SocialMessage"
],
"ModelExtensions": [],
"PagesExtensions": [
"UsrMobileContactFileActionsSettingsDefaultWorkplace",
"UsrMobileContactFileGridPageSettingsDefaultWorkplace",
"UsrMobileContactFileRecordPageSettingsDefaultWorkplace"
]
},
"SocialMessage": {
"RequiredModels": [],
"ModelExtensions": [],
"PagesExtensions": []
},
"Contact": {
"RequiredModels": [
"Contact",
"SysLanguage",
"ContactFile",
"FileGroup",
"ContactCommunication",
"CommunicationType",
"ContactAddress",
"AddressType",
"Country",
"Region",
"City",
"ContactAnniversary",
"AnniversaryType",
"FileType"
],
"ModelExtensions": [],
"PagesExtensions": [
"UsrMobileContactModuleConfig"
]
}
},
"ModuleGroups": {
"main": {}
},
"UseUTC": true
}
4) Обязательно выполнить рисайкл пула приложения (не перезапуск сайта в IIS, а именно рисайкл пула).
Сама логика скачивания файла и его открытие реализована в модуле UsrMyAction:
var config = {
url: 'https://1168222internal-demo.creatio.com/0/rest/FileService/GetFile/e9e…
success: function(fullPath, relativePath) {
Terrasoft.FileIntent.open({
path: relativePath
});
},
name: "Test_" + new Date().toDateString() + ".png"
};
Terrasoft.RequestManager.issueRequest({
requestFn: Terrasoft.FileTransfer.download,
requestFnConfig: config,
responseToStatusCodeFn: Terrasoft.FileTransfer.getStatusCodeFromException,
loginFailure: function(exception) {
Ext.callback(config.failure, config.scope, [exception]);
},
suppressRequestEvents: config.suppressRequestEvents,
scope: Terrasoft.FileTransfer
});
Какие здесь ключевые моменты:
1) https://1168222internal-demo.creatio.com/0/rest/FileService/GetFile/e9e… получить файл (кстати, здесь можно немного заменить код на следующий:
var config = {
url: Terrasoft.CurrentUserInfo.serverUrl + '0/rest/FileService/GetFile/e9eafee9-c4e4-4793-ad0a-003bd2c6a9b4/3bbbd5a8-8f8d-4570-8526-0488
и результат будет тот же, просто не будет использоваться явная ссылка на корень приложения). Здесь нужно будет заменить его на URL к кастомному сервису.
2) "Test_" + new Date().toDateString() + ".png" - это название файла, который будет подгружен и автоматически открыт. Здесь важно еще контролировать расширение скачиваемого файла, но если в 100% случаев будет скачиваться PDF, то можно здесь просто захардкодировать расширение .pdf.
3) За подгрузку файла отвечает метод Terrasoft.RequestManager.issueRequest, в который мы передаем в config ссылку откуда нам нужно получить файл и что делать в случае успешного выполнения метода issueRequest (здесь можно добавить и failure обработчик).
4) На success п.3 запускается метод Terrasoft.FileIntent.open который и отвечает за автоматическое открытие файла.
Почему сделано так: при загрузке файла через Terrasoft.RequestManager.issueRequest сохранение происходит не в хранилище мобильного телефона, а в локальный кэш мобильного приложения и файл автоматически открывается, чтобы была возможность его сохранить уже в хранилище самого мобильного устройства. У нас нет встроенного метода, который позволил бы загрузить файл напрямую в мобильное устройство, только ручное хранение.
Ограничение: сервис по получению файла должен быть доступен через метод GET. Если сейчас у Вас он реализован через POST, то создайте рядом еще один метод специально для мобильного приложения и вызывайте в коде его (в URL вызова можно передавать значение аргументов для метода (например, ID записей файлов или т.д.)).
Что нужно заменить:
1) Кастомную кнопку с действием я добавлял на карточку контакта. Вы же можете ее добавить в карту детали с файлами (подход тот же, только вместо Contact – название объекта детали). Ну или можете динамически вычитывать записи из детали и выбирать подходящую.
2) Продумать как реализовать названия файлов (опять же, можно считывать оригинальный файл из детали, брать его название и вставлять в параметр name).
Результат (тестировал и на iOS физическом девайсе и в эмуляторе в Android studio):
1) Сама кнопка:

2) Нажатие на кнопку:

Далее файл можно сохранить:

потестируйте и продолжайте кастомизировать под Ваш сервис.