diff --git a/public/offline.html b/public/offline.html new file mode 100644 index 00000000..126ceaa4 --- /dev/null +++ b/public/offline.html @@ -0,0 +1,307 @@ + + + + + + + MoviePilot - 离线模式 + + + + +
+ +
📡
+

网络连接已断开

+

+ + MoviePilot 需要网络连接才能正常工作。请检查您的网络连接后重试。 +

+ + + +
+

🔍 可能的解决方案

+ +
+ +
+

📱 关于MoviePilot

+

MoviePilot是一个智能媒体管理平台,需要稳定的网络连接来获取最新的电影、剧集信息以及执行各种管理操作。

+

感谢您的耐心等待,网络恢复后您将能够:

+ +
+
+ + + + + diff --git a/src/App.vue b/src/App.vue index 4ff8097f..74747774 100644 --- a/src/App.vue +++ b/src/App.vue @@ -174,7 +174,7 @@ onMounted(async () => { ) // 加载背景图片 - await loadBackgroundImages() + loadBackgroundImages() // 移除加载动画 ensureRenderComplete(() => { diff --git a/src/service-worker.ts b/src/service-worker.ts index 3c5652c8..6257bf62 100644 --- a/src/service-worker.ts +++ b/src/service-worker.ts @@ -1,4 +1,4 @@ -import { createHandlerBoundToURL, cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching' +import { cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching' import { NavigationRoute, registerRoute } from 'workbox-routing' declare let self: ServiceWorkerGlobalScope @@ -8,8 +8,43 @@ cleanupOutdatedCaches() // self.__WB_MANIFEST is default injection point precacheAndRoute(self.__WB_MANIFEST) -// to allow work offline -registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html'), { denylist: [/^(\/[\w-]+)*\/api/] })) +// 预缓存离线页面 +const OFFLINE_PAGE = '/offline.html' +const CACHE_NAME = 'mp-offline-cache-v1' + +// 安装时缓存离线页面 +self.addEventListener('install', event => { + event.waitUntil( + (async () => { + const cache = await caches.open(CACHE_NAME) + await cache.add(OFFLINE_PAGE) + })(), + ) +}) + +// 处理导航请求的离线回退 +const navigationHandler = async (params: any) => { + try { + // 尝试从网络获取页面 + const response = await fetch(params.request) + return response + } catch (error) { + // 如果网络失败,返回离线页面 + const cache = await caches.open(CACHE_NAME) + const offlineResponse = await cache.match(OFFLINE_PAGE) + return offlineResponse || new Response('离线页面不可用', { status: 503 }) + } +} + +// 注册导航路由,排除API请求 +registerRoute( + new NavigationRoute(navigationHandler, { + denylist: [/^(\/[\w-]+)*\/api/, /\/offline\.html$/], + }), +) + +// 注意:静态资源和API的缓存策略已在vite.config.ts中的workbox配置中定义 +// 这里只处理离线页面的特殊逻辑 // 通知选项 const options = { diff --git a/vite.config.ts b/vite.config.ts index 070c8868..343ff33d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -53,6 +53,13 @@ export default defineConfig({ filename: 'service-worker.ts', workbox: { globPatterns: ['**/*.{js,css,html,ico,png,svg,jpg,jpeg,webp,woff,woff2,ttf,otf,eot}'], + // 确保offline.html被预缓存 + additionalManifestEntries: [ + { + url: '/offline.html', + revision: null, + }, + ], runtimeCaching: [ { urlPattern: /\.(?:js|css|html)$/, @@ -115,8 +122,8 @@ export default defineConfig({ }, }, ], - navigateFallback: '/index.html', - navigateFallbackDenylist: [/.*\/api\/v\d+\/system\/logging.*/], + navigateFallback: null, + navigateFallbackDenylist: [/.*\/api\/v\d+\/system\/logging.*/, /\/offline\.html$/], skipWaiting: true, clientsClaim: true, },