From 1a3104e15eeb02054a57fbc70e3ec6498f67f18d Mon Sep 17 00:00:00 2001 From: TraceLumen Date: Sat, 19 Sep 2026 17:36:33 +0300 Subject: [PATCH] v1.1.0 upd connections instruct and checkup --- src/lib/common/services/network.service.js | 93 +++--------- src/lib/common/ui/NetworkGate.svelte | 169 ++++++++++++--------- src/lib/pages/main/MainMenu.svelte | 2 +- src/lib/pages/print/PrintMenu.svelte | 40 ++--- 4 files changed, 139 insertions(+), 165 deletions(-) diff --git a/src/lib/common/services/network.service.js b/src/lib/common/services/network.service.js index cfaacbc..361b600 100644 --- a/src/lib/common/services/network.service.js +++ b/src/lib/common/services/network.service.js @@ -1,88 +1,45 @@ // lib/common/services/network.service.js // -// Проверка подключения через эндпоинты бэкенда: +// Определение сети, в которой находится устройство. // -// - /api/is_server — публичный сервер unitprint.ru. -// Отвечает {"is_server":true} → интернет есть, скан доступен; -// - local.unitprint.ru/api/is_local — локальный сервер печати. -// Отвечает {"is_local":true} → устройство в Wi-Fi принтера (UnitPrintLocal), -// печать доступна. +// - внутри локальной сети принтера (Wi-Fi UnitPrintLocal) +// домен unitprint.ru резолвится на 192.168.20.1 — локальный сервер печати; +// - из интернета домен отвечает публичным адресом 95.165.135.233. // -// Сайт всегда отдаётся с unitprint.ru, поэтому проверка локалки ходит -// на отдельный хост local.unitprint.ru: вне локальной сети принтера -// он просто недоступен. -// -// Скан работает только через интернет, печать — только через локальную сеть. +// Клиент не может сам отличить эти случаи по IP (сертификаты, mixed content), +// поэтому спрашиваем сам сервер: GET /api/is_local → { "is_local": true|false }. +// Эндпоинт обязан быть на обоих инстансах: +// локальный → { "is_local": true } +// публичный → { "is_local": false } -export const LOCAL_HOST = 'local.unitprint.ru'; +export const DOMAIN = 'unitprint.ru'; +export const PUBLIC_IP = '95.165.135.233'; +export const LOCAL_IP = '192.168.20.1'; export const LOCAL_WIFI_NAME = 'UnitPrintLocal'; /** - * GET с таймаутом, читаем JSON. - * @returns {Promise} null — если хост недоступен или ошибка. + * Определяет текущий режим сети. + * @returns {Promise<'local' | 'internet' | 'offline'>} + * - 'local' → отвечающий сервер — локальный (домен → 192.168.20.1) + * - 'internet' → отвечающий сервер — публичный (домен → 95.165.135.233) + * - 'offline' → сервер вообще не ответил */ -async function getJson(url, timeoutMs = 4000) { - if (typeof fetch === 'undefined') return null; +export async function detectNetwork(timeoutMs = 6000) { + if (typeof fetch === 'undefined') return 'offline'; const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeoutMs); try { - const res = await fetch(url, { - method: 'GET', + const res = await fetch('/api/is_local', { cache: 'no-store', signal: controller.signal, }); - if (!res.ok) return null; - return await res.json(); + if (!res.ok) return 'offline'; + const data = await res.json(); + if (typeof data?.is_local !== 'boolean') return 'offline'; + return data.is_local ? 'local' : 'internet'; } catch { - return null; + return 'offline'; } finally { clearTimeout(timer); } } - -/** - * Доступность хоста в режиме 'no-cors': CORS не мешает, важен сам факт ответа. - */ -async function canReach(url, timeoutMs = 4000) { - if (typeof fetch === 'undefined') return false; - const controller = new AbortController(); - const timer = setTimeout(() => controller.abort(), timeoutMs); - try { - await fetch(url, { - method: 'GET', - mode: 'no-cors', - cache: 'no-store', - signal: controller.signal, - }); - return true; - } catch { - return false; - } finally { - clearTimeout(timer); - } -} - -/** - * Устройство в локальной сети принтера: - * local.unitprint.ru/api/is_local отвечает {"is_local":true}. - */ -export async function isLocalNetwork() { - const ts = Date.now(); - const httpsUrl = `https://${LOCAL_HOST}/api/is_local?ping=${ts}`; - const httpUrl = `http://${LOCAL_HOST}/api/is_local?ping=${ts}`; - - const data = (await getJson(httpsUrl, 3000)) ?? (await getJson(httpUrl, 3000)); - if (data) return data.is_local === true; - - // JSON не читается (CORS / самоподписанный сертификат) —fallback: - // сам факт ответа local.unitprint.ru означает, что мы в локалке. - return canReach(httpsUrl, 3000); -} - -/** - * Есть интернет: публичный сервер отвечает на /api/is_server. - */ -export async function isServerReachable() { - const data = await getJson(`/api/is_server?ping=${Date.now()}`, 5000); - return data?.is_server === true; -} diff --git a/src/lib/common/ui/NetworkGate.svelte b/src/lib/common/ui/NetworkGate.svelte index cb419f5..3adf6a1 100644 --- a/src/lib/common/ui/NetworkGate.svelte +++ b/src/lib/common/ui/NetworkGate.svelte @@ -15,7 +15,7 @@ mode: mode, onReady = () => {}, onBack = () => {}, - pollMs = 3000, + pollMs = 700, } = $props(); let success = $state(false); @@ -69,76 +69,109 @@ mode: -
- {#if success} -
-
- -
-

{isLocalMode ? 'Принтер найден' : 'Интернет подключен'}

-

Продолжаем…

-
- {:else} -
- {#if isLocalMode} - - {:else} - - {/if} -
+
+ {#if status === 'success'} +
+
+ +
+

{isLocalMode ? 'Принтер найден' : 'Интернет подключен'}

+

Продолжаем…

+
+ {:else} + +
+ {#if isLocalMode} + + {:else} + + {/if} +
-
- {#if isLocalMode} -

Подключитесь к принтеру

-

Печать доступна только в локальной сети принтера. Подключите устройство к сети:

- {:else} -

Необходимо подключение к интернету

-

Сканирование доступно только онлайн

- {/if} -
+
+ {#if isLocalMode} +

Нет связи с принтером

+

Печать доступна только в локальной сети принтера. Подключите устройство к сети:

+ {:else} +

Необходимо подключение к интернету

+

Убедитесь, что вы отключены от локальной сети Wi-Fi принтера.

+ {/if} +
- {#if isLocalMode} -
-
- 1 - - Подключитесь к Wi-Fi - - - {LOCAL_WIFI_NAME} - - -
-
- 2 - Отключите мобильный интернет -
-
- 3 - Отключите VPN -
-
- {/if} +
+ {#if isLocalMode} +
+ 1 +
+ Подключитесь к Wi-Fi +
+ + + {LOCAL_WIFI_NAME} + + +
+
+
+
+ 2 + Отключите мобильный интернет +
+
+ 3 + Отключите VPN +
+ {:else} +
+ 1 + Отключитесь от сети {LOCAL_WIFI_NAME} +
+
+ 2 + Включите мобильный интернет или подключитесь к другому Wi-Fi +
+ {/if} +
-
-
- Ожидание подключения… -
- {/if} -
+
+
+ + {#if status === 'checking'} + Проверка подключения… + {:else if isLocalMode} + Ожидание подключения к принтеру… + {:else} + Ожидание интернета… + {/if} + +
+

Как только подключение появится — продолжим автоматически

+ + + {/if} +