357 lines
11 KiB
JavaScript
357 lines
11 KiB
JavaScript
const Cookies = require('js-cookie');
|
|
|
|
function serializeFormData(obj, prefix = '') {
|
|
const str = [];
|
|
for (const key in obj) {
|
|
if (obj.hasOwnProperty(key)) {
|
|
const value = obj[key];
|
|
const newKey = prefix ? `${prefix}[${key}]` : key;
|
|
|
|
if (value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof File) && !(value instanceof Blob)) {
|
|
// Рекурсивно обрабатываем вложенные объекты
|
|
str.push(serializeFormData(value, newKey));
|
|
} else if (Array.isArray(value)) {
|
|
// Обрабатываем массивы
|
|
value.forEach((item, index) => {
|
|
if (typeof item === 'object' && item !== null && !(item instanceof File) && !(item instanceof Blob)) {
|
|
str.push(serializeFormData(item, `${newKey}[${index}]`));
|
|
} else {
|
|
str.push(encodeURIComponent(`${newKey}[${index}]`) + '=' + encodeURIComponent(item));
|
|
}
|
|
});
|
|
} else {
|
|
str.push(encodeURIComponent(newKey) + '=' + encodeURIComponent(value));
|
|
}
|
|
}
|
|
}
|
|
return str.join('&');
|
|
}
|
|
|
|
function sendRequest(data, url, method = "POST", dataType = "json", withCredentials = true, contentType = null) {
|
|
return new Promise(async (resolve, reject) => {
|
|
try {
|
|
const methodUpper = method.toUpperCase();
|
|
const isGetOrHead = methodUpper === "GET" || methodUpper === "HEAD";
|
|
|
|
// Для GET/HEAD перемещаем данные в URL
|
|
if (isGetOrHead && data) {
|
|
const params = new URLSearchParams(data);
|
|
url = `${url}${url.includes('?') ? '&' : '?'}${params}`;
|
|
}
|
|
|
|
// Автоматическое определение content-type для не-GET запросов
|
|
let finalContentType = contentType;
|
|
if (!finalContentType && !isGetOrHead) {
|
|
finalContentType = "application/x-www-form-urlencoded";
|
|
if (data && Object.values(data).some(value => value instanceof File || value instanceof Blob)) {
|
|
finalContentType = "multipart/form-data";
|
|
}
|
|
}
|
|
|
|
let body = null;
|
|
let headers = {};
|
|
|
|
// Подготовка тела только для не-GET запросов
|
|
if (!isGetOrHead && data) {
|
|
switch (finalContentType) {
|
|
case "application/json":
|
|
body = JSON.stringify(data);
|
|
headers["Content-Type"] = "application/json";
|
|
break;
|
|
|
|
case "multipart/form-data":
|
|
body = new FormData();
|
|
Object.entries(data).forEach(([key, value]) => {
|
|
body.append(key, value);
|
|
});
|
|
break;
|
|
|
|
default:
|
|
// Используем правильную сериализацию для вложенных объектов
|
|
body = serializeFormData(data);
|
|
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
|
}
|
|
}
|
|
|
|
const response = await fetch(url, {
|
|
method: methodUpper,
|
|
headers: headers,
|
|
credentials: withCredentials ? "include" : "same-origin",
|
|
body: body
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
|
|
}
|
|
|
|
const responseData = await response[dataType]();
|
|
resolve(responseData);
|
|
|
|
} catch (error) {
|
|
reject(error);
|
|
}
|
|
});
|
|
}
|
|
|
|
function isMobile() {
|
|
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function getCityId(address) {
|
|
const cityMap = new Map([
|
|
['Волгоград', 96],
|
|
['Воронеж', 98],
|
|
['Краснодар', 3018],
|
|
['Саратов', 94]
|
|
]);
|
|
|
|
for (const [cityName, cityId] of cityMap) {
|
|
if (address.includes(cityName)) {
|
|
return cityId;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function getCityCRM(region) {
|
|
switch (region) {
|
|
case '92': return 96; // Волгоград
|
|
case '93': return 98; // Воронеж
|
|
case '94': return 3018; // Краснодар
|
|
default: return 94; // Саратов
|
|
}
|
|
}
|
|
|
|
function getLicensePersonLink() {
|
|
if (/cabinet\.sovamed\.ru/m.test(location.hostname) || /cabinet\.wmtmed\.ru/m.test(location.hostname)) {
|
|
return 'https://cabinet.sovamed.ru/docs/soglasie-cabinet.pdf';
|
|
}
|
|
|
|
return 'https://cabinet.sovamed.ru/docs/soglasie-site.pdf';
|
|
}
|
|
|
|
function getLicenseLink(region) {
|
|
switch (region) {
|
|
case '92': // Волгоград
|
|
return 'https://volgograd.sovamed.ru/o-sove/dokumenty-i-licenzii/politika-konfidencialnosti/';
|
|
|
|
case '93': // Воронеж
|
|
return 'https://voronezh.sovamed.ru/o-sove/dokumenty-i-licenzii/politika-konfidencialnosti/';
|
|
|
|
case '94': // Краснодар
|
|
return 'https://wmtmed.ru/about/confidentiality_policy.php';
|
|
|
|
case '95': // Совенок
|
|
return 'https://sovenok.sovamed.ru/o-sove/dokumenty-i-licenzii/politika-konfidencialnosti/';
|
|
|
|
case '96': // Комфорт
|
|
return 'https://sovamed.ru/docs/comfort_politika.pdf';
|
|
|
|
default: // Саратов
|
|
return 'https://sovamed.ru/o-sove/dokumenty-i-licenzii/politika-konfidencialnosti/';
|
|
}
|
|
}
|
|
|
|
function renderCapcha(wrap) {
|
|
const elem = document.getElementById('smart-captcha');
|
|
|
|
if (elem) {
|
|
elem.parentNode.removeChild(elem);
|
|
}
|
|
|
|
wrap.innerHTML = '';
|
|
var recaptcha = document.createElement('div');
|
|
recaptcha.id = "smart-captcha";
|
|
recaptcha.dataset.controller = "smartCaptcha";
|
|
wrap.append(recaptcha);
|
|
|
|
var validRecaptcha = document.createElement('div');
|
|
validRecaptcha.classList = "msg-valid valid-captcha";
|
|
wrap.append(validRecaptcha);
|
|
|
|
return recaptcha;
|
|
}
|
|
|
|
function countDown(options) {
|
|
var timer,
|
|
instance = this,
|
|
seconds = options.seconds || 10,
|
|
updateStatus = options.onUpdateStatus || function () {},
|
|
counterEnd = options.onCounterEnd || function () {};
|
|
|
|
function decrementCounter() {
|
|
updateStatus(seconds);
|
|
|
|
if (seconds === 0) {
|
|
counterEnd();
|
|
instance.stop();
|
|
}
|
|
|
|
seconds--;
|
|
}
|
|
|
|
this.start = function () {
|
|
clearInterval(timer);
|
|
timer = 0;
|
|
seconds = options.seconds;
|
|
timer = setInterval(decrementCounter, 1000);
|
|
};
|
|
|
|
this.stop = function () {
|
|
clearInterval(timer);
|
|
};
|
|
}
|
|
|
|
function getApiHostname() {
|
|
if (/sovamed\.ru/m.test(location.hostname)) {
|
|
return 'https://api.sovamed.ru';
|
|
}
|
|
|
|
return 'https://api.wmtmed.ru';
|
|
}
|
|
|
|
function getHostname() {
|
|
if (/sovamed\.ru/m.test(location.hostname)) {
|
|
return 'https://cabinet.sovamed.ru';
|
|
}
|
|
|
|
return 'https://cabinet.wmtmed.ru';
|
|
}
|
|
|
|
function getRegionIdByHost() {
|
|
switch (location.host) {
|
|
case 'volgograd.sovamed.ru':
|
|
// Волгоград
|
|
var regionId = 92;
|
|
break;
|
|
|
|
case 'voronezh.sovamed.ru':
|
|
// Воронеж
|
|
var regionId = 93;
|
|
break;
|
|
|
|
case 'sovenok.sovamed.ru':
|
|
// Совенок
|
|
var regionId = 95;
|
|
break;
|
|
|
|
case 'comfort.sovamed.ru':
|
|
// Совенок
|
|
var regionId = 96;
|
|
break;
|
|
|
|
case 'wmtmed.ru':
|
|
// Краснодар
|
|
var regionId = 94;
|
|
break;
|
|
|
|
default:
|
|
// Саратов
|
|
var regionId = 91;
|
|
break;
|
|
};
|
|
|
|
return regionId;
|
|
}
|
|
|
|
const SESSION_ID_PARAM = '_ct_session_id';
|
|
|
|
function readSessionIdCookie() {
|
|
if (typeof document === 'undefined') {
|
|
return null;
|
|
}
|
|
const v = Cookies.get(SESSION_ID_PARAM);
|
|
if (v == null || String(v).trim() === '') {
|
|
return null;
|
|
}
|
|
return String(v).trim();
|
|
}
|
|
|
|
/**
|
|
* Если в query есть sessionId — пишет session-cookie (до закрытия браузера) и убирает параметр из URL.
|
|
*/
|
|
function syncSessionIdFromUrl() {
|
|
if (typeof window === 'undefined' || !window.location) {
|
|
return;
|
|
}
|
|
const url = new URL(window.location.href);
|
|
const raw = url.searchParams.get(SESSION_ID_PARAM);
|
|
if (raw === null) {
|
|
return;
|
|
}
|
|
const value = String(raw).trim();
|
|
if (!value) {
|
|
url.searchParams.delete(SESSION_ID_PARAM);
|
|
const next = url.pathname + url.search + url.hash;
|
|
if (next !== window.location.pathname + window.location.search + window.location.hash) {
|
|
window.location.replace(next);
|
|
}
|
|
return;
|
|
}
|
|
const secure = window.location.protocol === 'https:' ? '; Secure' : '';
|
|
document.cookie = `${SESSION_ID_PARAM}=${encodeURIComponent(value)}; path=/; SameSite=Lax${secure}`;
|
|
url.searchParams.delete(SESSION_ID_PARAM);
|
|
window.location.replace(url.pathname + url.search + url.hash);
|
|
}
|
|
|
|
function addAlert(msg, alertSystem, id, color = 'alert-danger') {
|
|
var alert = document.createElement('div');
|
|
alert.id = id;
|
|
alert.classList = 'alert alert-dismissible fade show';
|
|
alert.classList.add(color);
|
|
alert.setAttribute('role', 'alert');
|
|
|
|
var divMsg = document.createElement('div');
|
|
divMsg.classList = 'alert-msg';
|
|
divMsg.innerHTML = msg;
|
|
alert.append(divMsg);
|
|
|
|
alertSystem.prepend(alert);
|
|
}
|
|
|
|
function getSessionId() {
|
|
const fromCt = window.ct?.('calltracking_params')?.[0]?.sessionId;
|
|
if (fromCt != null && String(fromCt).trim() !== '') {
|
|
return String(fromCt).trim();
|
|
}
|
|
|
|
const fromCookie = readSessionIdCookie();
|
|
if (fromCookie) {
|
|
return fromCookie;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function addUrlParam(url, param, value) {
|
|
const urlObj = new URL(url);
|
|
|
|
if (!urlObj.searchParams.has(param)) {
|
|
urlObj.searchParams.set(param, value);
|
|
}
|
|
|
|
return urlObj.toString();
|
|
}
|
|
|
|
module.exports = {
|
|
addUrlParam: addUrlParam,
|
|
getSessionId: getSessionId,
|
|
syncSessionIdFromUrl: syncSessionIdFromUrl,
|
|
addAlert: addAlert,
|
|
getRegionIdByHost: getRegionIdByHost,
|
|
getApiHostname : getApiHostname,
|
|
getHostname: getHostname,
|
|
countDown: countDown,
|
|
isMobile: isMobile,
|
|
sendRequest: sendRequest,
|
|
getLicensePersonLink: getLicensePersonLink,
|
|
getLicenseLink: getLicenseLink,
|
|
getCityCRM: getCityCRM,
|
|
getCityId: getCityId,
|
|
renderCapcha: renderCapcha
|
|
}; |