226 lines
10 KiB
Diff
226 lines
10 KiB
Diff
diff --git a/assets/components/misSession.js b/assets/components/misSession.js
|
|
new file mode 100644
|
|
index 0000000..45088ef
|
|
--- /dev/null
|
|
+++ b/assets/components/misSession.js
|
|
@@ -0,0 +1,118 @@
|
|
+/**
|
|
+ * MIS (webSDK / widget.sovamed.ru) session helpers.
|
|
+ * Symfony login (ROLE_USER) and MIS session are independent.
|
|
+ */
|
|
+
|
|
+function MisSessionError() {
|
|
+ this.name = 'MisSessionError';
|
|
+ this.message = 'MIS session is not authenticated';
|
|
+}
|
|
+
|
|
+function isAuthenticated(webSDK) {
|
|
+ return Boolean(webSDK?.data?.user?.authenticated);
|
|
+}
|
|
+
|
|
+function ensureAuthenticated(webSDK) {
|
|
+ return new Promise(function(resolve, reject) {
|
|
+ if (isAuthenticated(webSDK)) {
|
|
+ resolve(webSDK);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (typeof webSDK?.isLoggedIn === 'function') {
|
|
+ webSDK.isLoggedIn(webSDK.sdkOrigin).then(function(result) {
|
|
+ if (result?.authenticated) {
|
|
+ resolve(webSDK);
|
|
+ return;
|
|
+ }
|
|
+ reject(new MisSessionError());
|
|
+ }).catch(function() {
|
|
+ reject(new MisSessionError());
|
|
+ });
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ reject(new MisSessionError());
|
|
+ });
|
|
+}
|
|
+
|
|
+function removeSdkOverlayModals() {
|
|
+ document.querySelectorAll('.wr-sdk-widget-modal').forEach(function(modal) {
|
|
+ modal.remove();
|
|
+ });
|
|
+}
|
|
+
|
|
+/**
|
|
+ * Move #iframeProtocol from SDK overlay into cabinet bootstrap popup.
|
|
+ * openConference() must be called without container (SDK applies Guest URL fix).
|
|
+ */
|
|
+function mountConferenceInPopup(popup) {
|
|
+ var iframe = document.getElementById('iframeProtocol');
|
|
+ var popupBody = popup?.querySelector('#popup-body');
|
|
+
|
|
+ if (!iframe || !popupBody) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ removeSdkOverlayModals();
|
|
+ popupBody.innerHTML = '';
|
|
+ popupBody.appendChild(iframe);
|
|
+ iframe.style.width = '100%';
|
|
+ iframe.style.border = 'none';
|
|
+ iframe.style.height = (window.innerHeight - 100) + 'px';
|
|
+
|
|
+ var fullScreenBtn = popup.querySelector('.full-scren-modal');
|
|
+ if (fullScreenBtn) {
|
|
+ fullScreenBtn.classList.remove('d-none');
|
|
+ }
|
|
+
|
|
+ popup.querySelector('.modal-dialog').classList = 'modal-dialog';
|
|
+ popup.querySelector('.modal-content').classList = 'modal-content';
|
|
+ popup.querySelector('.modal-title').innerHTML = 'Онлайн консультация';
|
|
+
|
|
+ if (typeof $ !== 'undefined' && typeof $(popup).modal === 'function') {
|
|
+ $(popup).modal('show');
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+function showMisSessionExpired(popup) {
|
|
+ if (!popup) {
|
|
+ window.location.pathname = '/logout';
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ popup.querySelector('.modal-dialog').classList = 'modal-dialog';
|
|
+ popup.querySelector('.modal-title').innerHTML = 'Сессия виджета истекла';
|
|
+ popup.querySelector('#popup-body').innerHTML =
|
|
+ '<p class="mb-3">Личный кабинет открыт, но сессия виджета записи (MIS) истекла. ' +
|
|
+ 'Для оплаты и онлайн-приёма нужно войти снова — повторная авторизация в iframe не требуется.</p>' +
|
|
+ '<button type="button" class="btn btn-outline-secondary w-100" id="mis-session-relogin">Войти снова</button>';
|
|
+
|
|
+ popup.querySelector('#mis-session-relogin').addEventListener('click', function() {
|
|
+ window.location.pathname = '/logout';
|
|
+ });
|
|
+
|
|
+ if (typeof $ !== 'undefined' && typeof $(popup).modal === 'function') {
|
|
+ $(popup).modal('show');
|
|
+ }
|
|
+}
|
|
+
|
|
+function handleMisSessionFailure(popup, error, logContext) {
|
|
+ if (error instanceof MisSessionError || error?.name === 'MisSessionError') {
|
|
+ showMisSessionExpired(popup);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
+module.exports = {
|
|
+ MisSessionError: MisSessionError,
|
|
+ isAuthenticated: isAuthenticated,
|
|
+ ensureAuthenticated: ensureAuthenticated,
|
|
+ mountConferenceInPopup: mountConferenceInPopup,
|
|
+ showMisSessionExpired: showMisSessionExpired,
|
|
+ handleMisSessionFailure: handleMisSessionFailure,
|
|
+};
|
|
diff --git a/assets/controllers/caseHistory_controller.js b/assets/controllers/caseHistory_controller.js
|
|
index 735c13c..aabafb1 100644
|
|
--- a/assets/controllers/caseHistory_controller.js
|
|
+++ b/assets/controllers/caseHistory_controller.js
|
|
@@ -2,6 +2,7 @@ import { Controller } from 'stimulus';
|
|
import Cookies from 'js-cookie';
|
|
const loader = require("./../components/loader.js");
|
|
const helper = require("./../components/helper.js");
|
|
+const misSession = require("./../components/misSession.js");
|
|
|
|
/*
|
|
* This is an example Stimulus controller!
|
|
@@ -248,20 +249,23 @@ export default class extends Controller {
|
|
btnConfirence.setAttribute('data-filial' , data.filial)
|
|
btnConfirence.addEventListener('click', function () {
|
|
popup.querySelector('#popup-body').innerHTML = '';
|
|
-
|
|
- webSDK.openConference({
|
|
- schedid: btnConfirence.dataset.id,
|
|
- container: popup.querySelector('#popup-body')
|
|
- }).then(function () {
|
|
- popup.querySelector('.full-scren-modal').classList.remove('d-none');
|
|
- document.getElementById('iframeProtocol').style.height = (window.innerHeight - 100) + 'px';
|
|
- popup.querySelector('.modal-dialog').classList = 'modal-dialog';
|
|
- popup.querySelector('.modal-content').classList = 'modal-content';
|
|
- popup.querySelector('.modal-content').classList = 'modal-content';
|
|
- popup.querySelector('.modal-title').innerHTML = 'Онлайн консультация';
|
|
|
|
- $(popup).modal('show');
|
|
+ misSession.ensureAuthenticated(webSDK).then(function() {
|
|
+ return webSDK.openConference({
|
|
+ schedid: btnConfirence.dataset.id
|
|
+ });
|
|
+ }).then(function () {
|
|
+ if (!misSession.mountConferenceInPopup(popup)) {
|
|
+ throw { data: { message: 'Не удалось открыть окно онлайн-консультации.' } };
|
|
+ }
|
|
}).catch(function (e) {
|
|
+ if (misSession.handleMisSessionFailure(popup, e)) {
|
|
+ helper.sendRequest({
|
|
+ data: {'error': e, method: 'openConference', reason: 'mis_session_expired'}
|
|
+ }, helper.getHostname() + '/api/log', "POST", "json", true, "application/json");
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (typeof e.data?.message !== 'undefined') {
|
|
var msg = e.data.message.replace('UTC+3', 'UTC+3 (московское время)');
|
|
popup.querySelector('#popup-body').innerHTML = msg;
|
|
@@ -272,9 +276,9 @@ export default class extends Controller {
|
|
}
|
|
|
|
helper.sendRequest({
|
|
- data: {'error': e, method: 'openConference'}
|
|
- }, helper.getHostname() + '/api/log', "POST", "json", true, "application/json");
|
|
- });
|
|
+ data: {'error': e, method: 'openConference'}
|
|
+ }, helper.getHostname() + '/api/log', "POST", "json", true, "application/json");
|
|
+ });
|
|
});
|
|
|
|
} else {
|
|
@@ -376,7 +380,6 @@ export default class extends Controller {
|
|
btnPayment.setAttribute('data-amt' , data.payment.amt);
|
|
btnPayment.setAttribute('data-payprofileid' , data.payment.magazineId);
|
|
btnPayment.addEventListener('click', function () {
|
|
-
|
|
var params = {
|
|
'orderid': Number(btnPayment.dataset.id) ,
|
|
'payprofileid': btnPayment.dataset.payprofileid,
|
|
@@ -386,14 +389,26 @@ export default class extends Controller {
|
|
'pcode': webSDK.data.user.id,
|
|
'successurl': document.location.origin + '/case-history#pay-success',
|
|
'errorurl': document.location.origin + '/case-history#error',
|
|
- 'containerId': 'popup-body',
|
|
+ 'containerId': 'popup-body',
|
|
};
|
|
|
|
- webSDK.loadPaymentView(params);
|
|
+ misSession.ensureAuthenticated(webSDK).then(function() {
|
|
+ webSDK.loadPaymentView(params);
|
|
+ popup.querySelector('#popup-body').innerHTML = '';
|
|
+ popup.querySelector('.modal-title').innerHTML = 'Оплата';
|
|
+ $(popup).modal('show');
|
|
+ }).catch(function(e) {
|
|
+ if (misSession.handleMisSessionFailure(popup, e)) {
|
|
+ helper.sendRequest({
|
|
+ data: {'error': e, method: 'loadPaymentView', reason: 'mis_session_expired'}
|
|
+ }, helper.getHostname() + '/api/log', "POST", "json", true, "application/json");
|
|
+ return;
|
|
+ }
|
|
|
|
- popup.querySelector('#popup-body').innerHTML = '';
|
|
- popup.querySelector('.modal-title').innerHTML = 'Оплата';
|
|
- $(popup).modal('show');
|
|
+ helper.sendRequest({
|
|
+ data: {'error': e, method: 'loadPaymentView'}
|
|
+ }, helper.getHostname() + '/api/log', "POST", "json", true, "application/json");
|
|
+ });
|
|
});
|
|
} else {
|
|
btnPayment.classList.add('d-none');
|