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; return section;
} }
async function fetchClientNote(client) { async function _fetchWithTimeout(url, body, timeoutMs = 15000) {
const res = await fetch(`${BACKEND_URL}/api/client_note`, { const ctrl = new AbortController();
const timer = setTimeout(() => ctrl.abort(), timeoutMs);
try {
const res = await fetch(url, {
method: "POST", 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 || "", initData: tg?.initData || "",
initDataUnsafe: tg?.initDataUnsafe || null, initDataUnsafe: tg?.initDataUnsafe || null,
client_name: client.client_name || "", client_name: client.client_name || "",
client_phone: client.client_phone || "", client_phone: client.client_phone || "",
}),
}); });
return await res.json();
} }
async function saveClientNote(client, note) { async function saveClientNote(client, note) {
const res = await fetch(`${BACKEND_URL}/api/client_note`, { return _fetchWithTimeout(`${BACKEND_URL}/api/client_note`, {
method: "POST",
body: JSON.stringify({
initData: tg?.initData || "", initData: tg?.initData || "",
initDataUnsafe: tg?.initDataUnsafe || null, initDataUnsafe: tg?.initDataUnsafe || null,
client_name: client.client_name || "", client_name: client.client_name || "",
client_phone: client.client_phone || "", client_phone: client.client_phone || "",
note: note || "", note: note || "",
}),
}); });
return await res.json();
} }
function setupVoiceInput(micBtn, textarea, status) { function setupVoiceInput(micBtn, textarea, status) {
@ -1825,14 +1835,10 @@ const Clients = (function () {
async function fetchClients() { async function fetchClients() {
if (!BACKEND_URL) throw new Error("BACKEND_URL не задан"); if (!BACKEND_URL) throw new Error("BACKEND_URL не задан");
const res = await fetch(`${BACKEND_URL}/api/clients`, { return _fetchWithTimeout(`${BACKEND_URL}/api/clients`, {
method: "POST",
body: JSON.stringify({
initData: tg?.initData || "", initData: tg?.initData || "",
initDataUnsafe: tg?.initDataUnsafe || null, initDataUnsafe: tg?.initDataUnsafe || null,
}),
}); });
return await res.json();
} }
async function fetchLead(leadId) { async function fetchLead(leadId) {
@ -1846,11 +1852,10 @@ const Clients = (function () {
async function fetchMeasurements(filters = {}) { async function fetchMeasurements(filters = {}) {
if (!BACKEND_URL) throw new Error("BACKEND_URL не задан"); if (!BACKEND_URL) throw new Error("BACKEND_URL не задан");
const res = await fetch(`${BACKEND_URL}/api/measurements`, { return _fetchWithTimeout(`${BACKEND_URL}/api/measurements`, {
method: "POST", initData: tg?.initData || "",
body: JSON.stringify({ initData: tg?.initData || "", ...filters }), ...filters,
}); });
return await res.json();
} }
function initial(name) { function initial(name) {

View File

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