const CACHE_NAME = 'din-v1'; const STATIC_ASSETS = [ '/', '/index.html', '/style.css', '/app.js', '/manifest.json', '/icon-72.png', '/icon-96.png', '/icon-128.png', '/icon-144.png', '/icon-192.png', '/icon-512.png' ]; // 安装时缓存静态资源 self.addEventListener('install', (e) => { e.waitUntil( caches.open(CACHE_NAME).then((cache) => { return cache.addAll(STATIC_ASSETS); }) ); self.skipWaiting(); }); // 激活时清理旧缓存 self.addEventListener('activate', (e) => { e.waitUntil( caches.keys().then((cacheNames) => { return Promise.all( cacheNames .filter((name) => name !== CACHE_NAME) .map((name) => caches.delete(name)) ); }) ); self.clients.claim(); }); // 拦截请求 self.addEventListener('fetch', (e) => { const { request } = e; const url = new URL(request.url); // API 请求:网络优先,失败时返回缓存 if (url.pathname.startsWith('/api/')) { e.respondWith( fetch(request) .then((response) => { // 缓存成功的 GET 请求 if (request.method === 'GET') { const clone = response.clone(); caches.open(CACHE_NAME).then((cache) => { cache.put(request, clone); }); } return response; }) .catch(() => { return caches.match(request).then((cached) => { if (cached) return cached; // 返回离线数据 if (url.pathname === '/api/stats') { return new Response( JSON.stringify({ today: 0, week: 0, month: 0, total: 0 }), { headers: { 'Content-Type': 'application/json' } } ); } if (url.pathname === '/api/din') { return new Response(JSON.stringify([]), { headers: { 'Content-Type': 'application/json' } }); } return new Response('Offline', { status: 503 }); }); }) ); return; } // 静态资源:缓存优先 e.respondWith( caches.match(request).then((cached) => { return cached || fetch(request); }) ); }); // 后台同步(用于离线时记录的数据) self.addEventListener('sync', (e) => { if (e.tag === 'sync-din') { e.waitUntil(syncPendingDins()); } }); async function syncPendingDins() { // 从 IndexedDB 获取待同步的记录并发送 // 这里简化处理,实际项目可以用 idb 库 console.log('Syncing pending dins...'); }