Веб-модули — это особый механизм интеграции серверной платформы Melbis с её Windows-клиентом Melbis Shop. Суть механизма: внутри программы встроен полноценный браузер на базе Chromium, который умеет открывать страницы сайта прямо внутри окон программы и общаться с ними в обе стороны — передавать контекст текущей работы менеджера на сервер и получать обратно результат. Разработчик создаёт обычный Melbis-модуль, а программа открывает его внутри своего окна.
Это позволяет расширять функциональность программы без изменения её кода: аналитика, отчёты, инструменты управления — всё это можно реализовать на PHP и подключить через настройки.
Встроенные модули работают прямо внутри рабочих окон программы —
«Товары / Цены», «Бизнес / Покупатели», «Бизнес / Заказы». Чтобы открыть
встроенный веб-модуль в любом из этих окон, нажмите Ctrl+W
— появится панель со встроенным браузером.
Ключевая особенность: когда менеджер перемещается по записям (выбирает товар, открывает заказ, переходит к покупателю), программа автоматически отправляет POST-запрос в модуль с контекстом текущего окна. Модуль всегда знает, с каким объектом сейчас работает менеджер, и может показать релевантную информацию — без каких-либо дополнительных действий с его стороны.
Этих модулей может быть несколько для каждого раздела — они переключаются вкладками. Для каждого модуля можно задать права доступа: какие группы пользователей его видят.
Примеры встроенных модулей для раздела «Товары / Цены»:
Примеры для раздела «Бизнес / Заказы» и «Бизнес / Покупатели»:
Встроенные модули настраиваются в программе: «Проектирование → Модули и опции», закладка «Встроенные модули». Выберите группу («Товары», «Покупатель», «Заказы») и добавьте модуль со следующими параметрами:
http://my-shop.com/?mod=melbis_web_sample.melbis_web_sample). Используется для проверки прав
доступа.login
и pass_code (MD5-хэш пароля). Это позволяет модулю
авторизовать пользователя и проверить его права.При каждом обращении к встроенному модулю программа отправляет POST-запрос с контекстом текущего окна. Ниже — полный набор параметров для раздела «Заказы»:
// $mVars в модуле:
[
'get' => ['mod' => 'melbis_web_sample'],
'post' => [
'order_id' => '1',
'order_version_id' => '2',
'order_version_client_id' => '1',
'order_version_user_id' => '1',
'order_client_field_id' => '3',
'order_store_id' => '2',
'order_option_id' => '3',
'login' => 'admin',
'pass_code' => '21232f297a57a5a743894a0e4a801fc3',
]
]В разделе «Товары» передаётся store_id выбранного
товара. В разделе «Покупатели» — идентификатор клиента. Пароль
передаётся в виде MD5-хэша.
Для веб-модулей в стандартную поставку демо-магазина включена
библиотека melbis_inc_auth. Она берёт на себя весь рутинный
код: авторизацию пользователя по login +
pass_code, хранение состояния авторизации в PHP-сессии,
проверку прав доступа к модулю и маршрутизацию POST-вызовов между
функциями модуля.
Центральная функция —
MELBIS_INC_AUTH_router($module, $mVars) —
выполняет следующее по порядку:
logout в POST).login +
pass_code из POST, или по ранее сохранённой сессии.GlobalAssign('page', [...]) глобальные
переменные, доступные во всех шаблонах: статус авторизации
(auth), user_id и mod — URL
текущего модуля. Переменная {PAGE:MOD} используется в
шаблонах как базовый URL для AJAX-запросов.func
— вызывает функцию ИМЯ_МОДУЛЯ_func($userId, $mVars), иначе
вызывает ИМЯ_МОДУЛЯ_default($userId, $mVars).Благодаря этому вся главная функция модуля сводится к одной строке:
function MELBIS_WEB_SAMPLE($mVars)
{
return MELBIS_INC_AUTH_router(MELBIS()->UnitName(), $mVars);
}MELBIS()->UnitName() возвращает имя текущего модуля —
оно передаётся в маршрутизатор для проверки прав и построения имён
дочерних функций.
Функция _default — точка входа при первом открытии
модуля. Она получает $mUserId (или null если
авторизация не прошла) и полный массив $mVars.
function MELBIS_WEB_SAMPLE_default($mUserId, $mVars)
{
$tpl = MELBIS()->TplCreate();
if ( $mUserId > 0 )
{
// Подготовить кэш прав пользователя для работы с web_key
MELBIS_INC_AUTH_web_key_prepare($mUserId);
// Передать входные переменные в шаблон
MELBIS()->TplAssign($tpl, 'VARS', var_export($mVars, true));
// Передать данные заказа для механизма обратной передачи
MELBIS()->TplAssign($tpl, 'ORDER', $mVars['post']['order'] ?? '{}');
MELBIS()->TplParse($tpl, 'SCRIPTS', 'scripts');
MELBIS()->TplParse($tpl, 'CONTENT', 'page');
}
else
{
// Пользователь не авторизован — показать форму входа
MELBIS()->TplParse($tpl, 'CONTENT', 'auth');
}
MELBIS()->GlobalAppend('page', ['title' => 'Sample Web module']);
return MELBIS()->TplFinal($tpl, 'main');
}Шаблон auth.htm содержит вызов модуля
melbis_web_auth — он выводит форму логина. После отправки
формы MELBIS_INC_AUTH_router снова обрабатывает POST,
авторизует пользователя и на этот раз возвращает основной шаблон
page.htm.
Для интерактивных действий внутри модуля JavaScript передаёт параметр
func в POST. Маршрутизатор найдёт и вызовет соответствующую
функцию — при условии что пользователь авторизован и имеет доступ к
модулю.
В шаблоне переменная {PAGE:MOD} содержит готовый URL
текущего модуля (/?mod=melbis_web_sample) — его удобно
использовать как точку для всех AJAX-запросов:
$('#melbis_table_cataloge').bootstrapTable({
url: '{PAGE:MOD}',
method: 'post',
queryParams: function(params) {
params.func = 'get_cataloge'; // маршрутизатор вызовет MELBIS_WEB_SAMPLE_get_cataloge
return params;
},
pagination: true,
sidePagination: 'server',
pageSize: 20,
sortName: 'absindex',
sortOrder: 'asc'
});На стороне PHP функция получает управление только если пользователь авторизован, выполняет запрос и возвращает JSON:
function MELBIS_WEB_SAMPLE_get_cataloge($mUserId, $mVars)
{
$limit = (int) $mVars['post']['limit'];
$offset = (int) $mVars['post']['offset'];
$sort = preg_replace('/[^a-z_]/', '', $mVars['post']['sort']);
$sort .= ($mVars['post']['order'] == 'asc') ? ' ASC' : ' DESC';
$command = "SELECT t.id, t.name, t.tlevel, COUNT(ts.id) AS amount
FROM {DBNICK}_topic t
LEFT JOIN {DBNICK}_topic_store ts ON t.id = ts.topic_id
GROUP BY t.id
ORDER BY $sort";
$data = MELBIS()->SqlSelectLimit(__LINE__, $command, $offset, $limit);
return json_encode($data);
}Такой же принцип применяется для любых других функций модуля — поиска, фильтрации, сохранения данных в БД, отправки уведомлений и т.п.
Наиболее уникальная возможность встроенных веб-модулей — передача данных из браузера обратно в Windows-программу без дополнительных HTTP-запросов.
Это реализовано через console.log со специальным ключом.
Программа перехватывает вывод консоли браузера и при обнаружении ключа
MELBIS_ORDER_UPDATE применяет полученные данные к
редактируемому заказу.
Механизм работает только в окне редактирования заказа, пока заказ ещё не сохранён. В остальных разделах (товары, покупатели) веб-модуль при необходимости пишет изменения напрямую в базу данных через обычные SQL-методы парсера.
Практический пример: модуль получает от программы все данные открытого заказа в JSON-формате, отображает их в интерактивных таблицах, и позволяет менеджеру редактировать отдельные поля прямо в браузере.
// PHP: получить данные заказа, переданные программой, и отдать в шаблон
MELBIS()->TplAssign($tpl, 'ORDER', $mVars['post']['order'] ?? '{}');// Шаблон: распарсить JSON и построить таблицы
var melbis_order = {ORDER};
function melbis_init_back() {
for (var table in melbis_order) {
var data = melbis_order[table];
var columns = [];
for (var c in data[0]) {
columns.push({field: c, title: c});
}
$('.melbis_table_order[data-table="' + table + '"]').bootstrapTable({
columns: columns,
data: data
});
}
}
// Клик по ячейке — диалог редактирования
$('.melbis_table_order').on('click-cell.bs.table', function(event, field, value, row) {
var table = event.target.dataset.table;
bootbox.prompt({
title: 'Edit value of "' + field + '"',
value: value,
callback: function(result) {
if (result != null) {
var update = {};
update[table] = [{id: row.id, [field]: result}];
// Передать изменение в программу через консоль
console.log('MELBIS_ORDER_UPDATE' + JSON.stringify(update));
}
}
});
});Программа считывает вывод консоли, распознаёт ключ
MELBIS_ORDER_UPDATE и применяет изменения к полям заказа в
своём интерфейсе.
Внешние модули отличаются от встроенных принципиально одним: они не
привязаны к конкретному окну программы и не получают контекст текущей
записи. Вместо этого при открытии из программы передаются только
параметры авторизации пользователя (login,
pass_code).
Доступ к внешним модулям открывается через раздел «Бизнес / Веб-модули» — здесь расположен браузер с каталогом всех доступных модулей в левой панели. Кроме того, любой из таких модулей можно открыть в обычном браузере на любом устройстве — планшете, смартфоне, рабочем месте без программы.
Это делает внешние модули универсальным инструментом для дашбордов, аналитических отчётов и административных панелей — всего, что не требует привязки к конкретному товару или заказу. На скриншоте выше — пример реального внешнего модуля с аналитикой продаж, финансовым учётом, складским анализом и инструментами управления, встроенными прямо в программу.
Настройка внешних модулей — «Проектирование → Модули и опции», закладка «Внешние веб-модули»: задаётся название, URL и символьный ключ каждого модуля, а также права доступа по группам пользователей.
Поскольку внешние модули открываются в том числе из обычного браузера, авторизация здесь работает в двух режимах автоматически:
При открытии из программы — Melbis Shop передаёт
login и pass_code в POST.
MELBIS_INC_AUTH_router авторизует пользователя без участия
формы и сразу показывает содержимое.
При открытии в браузере напрямую — POST не содержит
учётных данных, маршрутизатор возвращает $mUserId = null, и
функция _default подставляет шаблон формы авторизации.
После успешного входа данные сохраняются в PHP-сессии, и при последующих
запросах форма больше не показывается.
Один и тот же код модуля работает в обоих случаях — разветвление
происходит полностью автоматически внутри библиотеки
melbis_inc_auth. Разработчику достаточно корректно
обработать случай $mUserId == null в функции
_default.
Windows Melbis Shop
│
│ POST: store_id / order_id / login / pass_code
▼
index.php → Run('melbis_web_sample')
│
▼
MELBIS_WEB_SAMPLE($mVars)
│
▼
MELBIS_INC_AUTH_router(...)
├─ авторизация + проверка прав
├─ func = 'default' → MELBIS_WEB_SAMPLE_default($userId, $mVars) → HTML
├─ func = 'get_cataloge' → MELBIS_WEB_SAMPLE_get_cataloge($userId, $mVars) → JSON
└─ func = 'get_goods' → MELBIS_WEB_SAMPLE_get_goods($userId, $mVars) → JSON
HTML-страница в браузере программы
│ (только для окна редактирования заказа)
▼
console.log('MELBIS_ORDER_UPDATE{"version":[...]}')
│
▼
Windows Melbis Shop — применяет изменения к заказу