Files
renjianbo f2e65a8fbb feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00

89 lines
2.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Service Worker — 今天吃啥 PWA
* 策略:静态资源 Cache First,数据 Network First,图片 Cache First
*/
const CACHE_STATIC = 'weinan-dishes-v1';
const CACHE_IMAGES = 'weinan-images-v1';
const STATIC_FILES = [
'/',
'/index.html',
'/style.css',
'/app.js',
'/dishes.json',
'/manifest.json',
];
// Install: 预缓存核心静态资源
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_STATIC).then((cache) => {
return cache.addAll(STATIC_FILES);
})
);
self.skipWaiting();
});
// Activate: 清理旧缓存
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((keys) => {
return Promise.all(
keys.filter((k) => k !== CACHE_STATIC && k !== CACHE_IMAGES)
.map((k) => caches.delete(k))
);
})
);
self.clients.claim();
});
// Fetch: 按资源类型分策略
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
// 图片: Cache First
if (url.pathname.match(/\.(jpg|png|svg|webp|ico)$/i)) {
event.respondWith(
caches.match(event.request).then((cached) => {
const fetchPromise = fetch(event.request).then((response) => {
if (response.ok) {
const clone = response.clone();
caches.open(CACHE_IMAGES).then((cache) => cache.put(event.request, clone));
}
return response;
});
return cached || fetchPromise;
})
);
return;
}
// dishes.json: Network First(保证数据新鲜)
if (url.pathname.endsWith('dishes.json')) {
event.respondWith(
fetch(event.request)
.then((response) => {
const clone = response.clone();
caches.open(CACHE_STATIC).then((cache) => cache.put(event.request, clone));
return response;
})
.catch(() => caches.match(event.request))
);
return;
}
// HTML/CSS/JS: Cache First(App Shell)
event.respondWith(
caches.match(event.request).then((cached) => {
const fetchPromise = fetch(event.request).then((response) => {
if (response.ok) {
const clone = response.clone();
caches.open(CACHE_STATIC).then((cache) => cache.put(event.request, clone));
}
return response;
});
return cached || fetchPromise;
})
);
});