fix: таймаут 15с на все fetch в clients.js — кнопки больше не висят

- _fetchWithTimeout() — единый fetch с AbortController
- saveClientNote, fetchClientNote, fetchClients, fetchMeasurements
  теперь через таймаут вместо бесконечного ожидания
- При таймауте показывает 'Сервер не отвечает — попробуйте ещё раз'
- Версия clients.js: 20260518e
This commit is contained in:
wasrusgen 2026-05-18 08:35:42 +03:00
parent a9aa704950
commit 6f74d05184
2 changed files with 36 additions and 31 deletions

View File

@ -1765,31 +1765,41 @@ const Clients = (function () {
return section;
}
async function fetchClientNote(client) {
const res = await fetch(`${BACKEND_URL}/api/client_note`, {
async function _fetchWithTimeout(url, body, timeoutMs = 15000) {
const ctrl = new AbortController();
const timer = setTimeout(() => ctrl.abort(), timeoutMs);
try {
const res = await fetch(url, {
method: "POST",
body: JSON.stringify({
signal: ctrl.signal,
body: JSON.stringify(body),
});
return await res.json();
} catch (e) {
if (e.name === "AbortError") throw new Error("Сервер не отвечает — попробуйте ещё раз");
throw e;
} finally {
clearTimeout(timer);
}
}
async function fetchClientNote(client) {
return _fetchWithTimeout(`${BACKEND_URL}/api/client_note`, {
initData: tg?.initData || "",
initDataUnsafe: tg?.initDataUnsafe || null,
client_name: client.client_name || "",
client_phone: client.client_phone || "",
}),
});
return await res.json();
}
async function saveClientNote(client, note) {
const res = await fetch(`${BACKEND_URL}/api/client_note`, {
method: "POST",
body: JSON.stringify({
return _fetchWithTimeout(`${BACKEND_URL}/api/client_note`, {
initData: tg?.initData || "",
initDataUnsafe: tg?.initDataUnsafe || null,
client_name: client.client_name || "",
client_phone: client.client_phone || "",
note: note || "",
}),
});
return await res.json();
}
function setupVoiceInput(micBtn, textarea, status) {
@ -1825,14 +1835,10 @@ const Clients = (function () {
async function fetchClients() {
if (!BACKEND_URL) throw new Error("BACKEND_URL не задан");
const res = await fetch(`${BACKEND_URL}/api/clients`, {
method: "POST",
body: JSON.stringify({
return _fetchWithTimeout(`${BACKEND_URL}/api/clients`, {
initData: tg?.initData || "",
initDataUnsafe: tg?.initDataUnsafe || null,
}),
});
return await res.json();
}
async function fetchLead(leadId) {
@ -1846,11 +1852,10 @@ const Clients = (function () {
async function fetchMeasurements(filters = {}) {
if (!BACKEND_URL) throw new Error("BACKEND_URL не задан");
const res = await fetch(`${BACKEND_URL}/api/measurements`, {
method: "POST",
body: JSON.stringify({ initData: tg?.initData || "", ...filters }),
return _fetchWithTimeout(`${BACKEND_URL}/api/measurements`, {
initData: tg?.initData || "",
...filters,
});
return await res.json();
}
function initial(name) {

View File

@ -39,7 +39,7 @@
<script src="assets/podbor.config.js?v=20260516h"></script>
<script src="assets/podbor.picts.js?v=20260516h"></script>
<script src="assets/podbor.js?v=20260517d"></script>
<script src="assets/clients.js?v=20260518d"></script>
<script src="assets/clients.js?v=20260518e"></script>
<script src="assets/zamer-picts.js?v=20260516h"></script>
<script src="assets/measurements.js?v=20260517d"></script>
<script src="assets/request.js?v=20260517d"></script>