diff --git a/src/lib/common/services/network.service.js b/src/lib/common/services/network.service.js index fe7efe1..cfaacbc 100644 --- a/src/lib/common/services/network.service.js +++ b/src/lib/common/services/network.service.js @@ -1,22 +1,47 @@ // lib/common/services/network.service.js // -// Определение сети, в которой находится устройство. +// Проверка подключения через эндпоинты бэкенда: // -// - внутри локальной сети принтера (Wi-Fi UnitPrintLocal) -// домен unitprint.ru резолвится на 192.168.20.1 — локальный сервер печати; -// - из интернета домен отвечает публичным адресом 95.165.135.233. +// - /api/is_server — публичный сервер unitprint.ru. +// Отвечает {"is_server":true} → интернет есть, скан доступен; +// - local.unitprint.ru/api/is_local — локальный сервер печати. +// Отвечает {"is_local":true} → устройство в Wi-Fi принтера (UnitPrintLocal), +// печать доступна. +// +// Сайт всегда отдаётся с unitprint.ru, поэтому проверка локалки ходит +// на отдельный хост 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_HOST = 'local.unitprint.ru'; export const LOCAL_WIFI_NAME = 'UnitPrintLocal'; /** - * Сетевая доступность URL. - * mode: 'no-cors' — чтобы CORS не мешал: важен сам факт ответа сервера, - * а не содержимое ответа. Любой HTTP-ответ = хост доступен. + * GET с таймаутом, читаем JSON. + * @returns {Promise} null — если хост недоступен или ошибка. + */ +async function getJson(url, timeoutMs = 4000) { + if (typeof fetch === 'undefined') return null; + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), timeoutMs); + try { + const res = await fetch(url, { + method: 'GET', + cache: 'no-store', + signal: controller.signal, + }); + if (!res.ok) return null; + return await res.json(); + } catch { + return null; + } finally { + clearTimeout(timer); + } +} + +/** + * Доступность хоста в режиме 'no-cors': CORS не мешает, важен сам факт ответа. */ async function canReach(url, timeoutMs = 4000) { if (typeof fetch === 'undefined') return false; @@ -37,33 +62,27 @@ async function canReach(url, timeoutMs = 4000) { } } -/** Доступен ли локальный сервер печати (192.168.20.1) */ -export async function isLocalServerReachable() { +/** + * Устройство в локальной сети принтера: + * local.unitprint.ru/api/is_local отвечает {"is_local":true}. + */ +export async function isLocalNetwork() { const ts = Date.now(); - if (await canReach(`http://${LOCAL_IP}/api/version?ping=${ts}`, 3000)) return true; - return canReach(`https://${LOCAL_IP}/api/version?ping=${ts}`, 3000); -} + const httpsUrl = `https://${LOCAL_HOST}/api/is_local?ping=${ts}`; + const httpUrl = `http://${LOCAL_HOST}/api/is_local?ping=${ts}`; -/** Есть ли интернет (домен отвечает публичным сервером) */ -export function isInternetReachable() { - return canReach(`https://${DOMAIN}/api/version?ping=${Date.now()}`, 5000); + 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); } /** - * Определяет текущий режим сети. - * @returns {Promise<'local' | 'internet' | 'offline'>} - * - 'local' → устройство в сети принтера (домен → 192.168.20.1) - * - 'internet' → устройство в интернете (домен → 95.165.135.233) - * - 'offline' → нет ни того, ни другого + * Есть интернет: публичный сервер отвечает на /api/is_server. */ -export async function detectNetwork() { - const [local, internet] = await Promise.all([ - isLocalServerReachable(), - isInternetReachable(), - ]); - // Локальная сеть в приоритете: если 192.168.20.1 доступен, - // значит домен сейчас указывает на локальный сервер печати. - if (local) return 'local'; - if (internet) return 'internet'; - return 'offline'; +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 e64e467..cb419f5 100644 --- a/src/lib/common/ui/NetworkGate.svelte +++ b/src/lib/common/ui/NetworkGate.svelte @@ -1,127 +1,76 @@
-

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

- {#if status === 'checking'} -
-
-

Проверка подключения…

-

Определяем, в какой вы сети

-
- {:else if status === 'success'} + {#if success}
@@ -149,41 +98,29 @@ async function copyWifiName() {
{#if isLocalMode} -

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

+

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

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

{:else}

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

-

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

+

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

{/if}
-
- {#if isLocalMode} + {#if isLocalMode} +
1 -
+ Подключитесь к Wi-Fi -
- - - {LOCAL_WIFI_NAME} - - -
-
+ + + {LOCAL_WIFI_NAME} + +
2 @@ -193,252 +130,166 @@ async function copyWifiName() { 3 Отключите VPN
- {:else} -
- 1 - Отключитесь от сети {LOCAL_WIFI_NAME} -
-
- 2 - Включите мобильный интернет или подключитесь к другому Wi-Fi -
- {/if} -
+
+ {/if}
- {isLocalMode ? 'Ожидание подключения к принтеру…' : 'Ожидание интернета…'} + Ожидание подключения…
-

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

- - {/if}
diff --git a/src/lib/pages/main/MainMenu.svelte b/src/lib/pages/main/MainMenu.svelte index 7b6e884..ed99c38 100644 --- a/src/lib/pages/main/MainMenu.svelte +++ b/src/lib/pages/main/MainMenu.svelte @@ -205,5 +205,5 @@
v{backendVersion} - v1.0.8 + v1.0.9
diff --git a/src/lib/pages/print/PrintMenu.svelte b/src/lib/pages/print/PrintMenu.svelte index e0d9863..8faf99a 100644 --- a/src/lib/pages/print/PrintMenu.svelte +++ b/src/lib/pages/print/PrintMenu.svelte @@ -7,7 +7,7 @@ import PaymentPage from '$lib/common/ui/PaymentPage.svelte'; import { plFiles, plCopies } from '$lib/common/utils/pricing.util.js'; import NetworkGate from '$lib/common/ui/NetworkGate.svelte'; - import { detectNetwork } from '$lib/common/services/network.service.js'; + import { isLocalNetwork } from '$lib/common/services/network.service.js'; let { onBack = () => {} } = $props(); const store = createPrintStore(); @@ -47,7 +47,7 @@ async function handleConfirmPayment() { if (printNetGate === 'checking') return; printNetGate = 'checking'; - const net = await detectNetwork(); + const net = await isLocalNetwork(); if (net === 'local') { printNetGate = null; store.submitPrint(); @@ -77,7 +77,7 @@
-

Проверка подключения к принтеру…

+

Проверка подключения…

{:else}