Files
2026-05-28 12:09:28 +03:00

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
};