Files
distribution_erp/public/sw.js
T
chpark 89503ebf03
Deploy momo-erp / deploy (push) Successful in 1m56s
fix(push): 일괄 판매기간 적용도 알림 발송 + 알림 아이콘 모모 로고/단색 배지
- bulk-sale-range: 리스트에서 판매기간 일괄 적용 시에도 일반 사용자 푸시.
  1건이면 품목명, 여러 건이면 'N개 품목 판매' 요약. 해제(clear)는 알림 제외.
- 알림 아이콘: 큰 아이콘은 모모 로고(icon-192), 상태바 작은 배지는 흰 M
  단색 투명 PNG(badge-96) — 기존엔 컬러 PNG라 크롬이 지구본 기본 배지로 대체했음.
- sw.js: CACHE v2 로 올려 갱신 강제 + badge-96 precache, push 핸들러가
  payload icon/badge 우선 사용.
2026-05-27 00:43:45 +09:00

56 lines
1.9 KiB
JavaScript

// 모모유통 ERP — Service Worker (PWA install criteria 충족용)
const CACHE = 'momo-erp-v2';
const PRECACHE = ['/', '/manifest.json', '/icon-192.png', '/icon-512.png', '/badge-96.png'];
self.addEventListener('install', (e) => {
e.waitUntil(caches.open(CACHE).then((c) => c.addAll(PRECACHE)).catch(() => {}));
self.skipWaiting();
});
self.addEventListener('activate', (e) => {
e.waitUntil(
caches.keys().then((keys) =>
Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)))
)
);
self.clients.claim();
});
// API 요청은 항상 네트워크 (캐시 안 함). 정적 자원만 캐시.
self.addEventListener('fetch', (e) => {
const url = new URL(e.request.url);
if (url.pathname.startsWith('/api/')) return;
if (e.request.method !== 'GET') return;
e.respondWith(
fetch(e.request).catch(() => caches.match(e.request))
);
});
// ===== 웹 푸시 =====
self.addEventListener('push', (e) => {
let data = {};
try { data = e.data ? e.data.json() : {}; } catch (_) { data = {}; }
const title = data.title || '모모유통';
const options = {
body: data.body || '',
icon: data.icon || '/icon-192.png', // 큰 아이콘 = 모모 로고(초록 M)
badge: data.badge || '/badge-96.png', // 상태바 작은 아이콘 = 흰 M 단색(투명 배경)
tag: data.tag || undefined,
data: { url: data.url || '/m/orders/new' },
};
e.waitUntil(self.registration.showNotification(title, options));
});
self.addEventListener('notificationclick', (e) => {
e.notification.close();
const target = (e.notification.data && e.notification.data.url) || '/m/orders/new';
e.waitUntil(
self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((cs) => {
for (const c of cs) {
if ('focus' in c) { c.navigate(target); return c.focus(); }
}
if (self.clients.openWindow) return self.clients.openWindow(target);
})
);
});