From 847352a788e8517db238d58a994b40aeb749db49 Mon Sep 17 00:00:00 2001 From: u2nyakim Date: Fri, 29 Aug 2025 13:45:50 +0800 Subject: [PATCH] =?UTF-8?q?up.=20=E6=96=B0=E5=A2=9E=20workbox-webpack-plug?= =?UTF-8?q?in=20=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- z_ele/package.json | 7 +-- z_ele/public/service-worker.js | 63 ++++++++++++++++++++++ z_ele/src/main.ts | 2 + z_ele/src/plugins/notification/index.ts | 11 ++++ z_ele/src/plugins/service-worker/events.ts | 4 ++ z_ele/src/plugins/service-worker/index.ts | 13 +++++ z_ele/vite.config.ts | 15 ++++-- 7 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 z_ele/public/service-worker.js create mode 100644 z_ele/src/plugins/notification/index.ts create mode 100644 z_ele/src/plugins/service-worker/events.ts create mode 100644 z_ele/src/plugins/service-worker/index.ts diff --git a/z_ele/package.json b/z_ele/package.json index b91847b..6aa3fa2 100644 --- a/z_ele/package.json +++ b/z_ele/package.json @@ -38,14 +38,15 @@ "nprogress": "0.2.0", "pinia": "3.0.2", "sortablejs": "1.15.6", - "tinymce": "5.10.9", + "tinymce": "^8.0.2", "vue": "3.5.15", "vue-echarts": "7.0.3", - "vue-i18n": "11.1.5", + "vue-i18n": "^11.1.11", "vue-router": "4.5.1", "vuedraggable": "4.1.0", + "workbox-webpack-plugin": "^7.3.0", "xgplayer": "3.0.22", - "xgplayer-hls": "3.0.22", + "xgplayer-hls": "^2.5.2", "xgplayer-music": "3.0.22" }, "devDependencies": { diff --git a/z_ele/public/service-worker.js b/z_ele/public/service-worker.js new file mode 100644 index 0000000..ccf897a --- /dev/null +++ b/z_ele/public/service-worker.js @@ -0,0 +1,63 @@ +// 存储所有客户端ID(用于定向通知) +let controlledClients = []; +// 监听安装事件 +self.addEventListener('install', e => e.waitUntil(self.skipWaiting())); + +// 监听激活事件 +self.addEventListener('activate', e => + e.waitUntil(clients.claim().then(() => self.clients.matchAll()) + .then(clients => { + // 获取所有受控客户端ID + controlledClients = clients.map(c => c.id); + }) + ) +); + +// 监听客户端连接变化(窗口打开/关闭) +self.addEventListener('message', event => { + if (event.data.type === 'REGISTER_CLIENT') { + if (!controlledClients.includes(event.data.clientId)) { + controlledClients.push(event.data.clientId); + } + } +}); + +// 核心:处理锁屏/解锁广播 +self.addEventListener('message', event => { + const { action, senderId } = event.data; + + if (action === 'LOCK' || action === 'UNLOCK') { + // 向所有其他客户端广播 + self.clients.matchAll().then(clients => { + clients.forEach(client => { + // 排除发送者 + if (client.id !== senderId) { + client.postMessage({ + action: `${action}_REQUESTED`, + timestamp: Date.now() + }); + } + }); + }); + } +}); + +self.addEventListener('push', event => { + const title = '新消息'; + const options = { + body: event.data.text(), + // icon: '/images/icon.png', + // badge: '/images/badge.png' + }; + + event.waitUntil( + self.registration.showNotification(title, options) + ); +}); + +self.addEventListener('notificationclick', event => { + event.notification.close(); + event.waitUntil( + clients.openWindow('https://example.com/notifications') + ); +}); diff --git a/z_ele/src/main.ts b/z_ele/src/main.ts index 4a2c642..645efd0 100644 --- a/z_ele/src/main.ts +++ b/z_ele/src/main.ts @@ -8,6 +8,8 @@ import i18n from './i18n'; import installer from './as-needed'; import { iconsInstaller } from '@/components/IconSelect/util'; import { WsConfig, WsPlugin } from '@/plugins/websocket'; +import "@/plugins/notification" +import "@/plugins/service-worker" import 'element-plus/theme-chalk/display.css'; import 'ele-admin-plus/es/style/nprogress.scss'; import './styles/themes/rounded.scss'; diff --git a/z_ele/src/plugins/notification/index.ts b/z_ele/src/plugins/notification/index.ts new file mode 100644 index 0000000..2739be7 --- /dev/null +++ b/z_ele/src/plugins/notification/index.ts @@ -0,0 +1,11 @@ +/* + * 请求通知权限 + */ +Notification && Notification.requestPermission().then(permission => { + if (permission === 'granted') { + console.debug("[.permission] 通知权限已授予"); + }else{ + console.error("[.permission] 通知权限未授权"); + } +}); + diff --git a/z_ele/src/plugins/service-worker/events.ts b/z_ele/src/plugins/service-worker/events.ts new file mode 100644 index 0000000..a84a360 --- /dev/null +++ b/z_ele/src/plugins/service-worker/events.ts @@ -0,0 +1,4 @@ + +export function lock(){ + +} diff --git a/z_ele/src/plugins/service-worker/index.ts b/z_ele/src/plugins/service-worker/index.ts new file mode 100644 index 0000000..4f761db --- /dev/null +++ b/z_ele/src/plugins/service-worker/index.ts @@ -0,0 +1,13 @@ +function serviceWorkerRegister() { + if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/service-worker.js').then(registration => { + console.log('Service Worker 注册成功:', registration); + }).catch(error => { + console.error('Service Worker 注册失败:', error); + }); + }); + } +} + +serviceWorkerRegister(); diff --git a/z_ele/vite.config.ts b/z_ele/vite.config.ts index dbce5e3..a0508ea 100644 --- a/z_ele/vite.config.ts +++ b/z_ele/vite.config.ts @@ -5,14 +5,23 @@ import Compression from 'vite-plugin-compression'; import Components from 'unplugin-vue-components/vite'; import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'; import { EleAdminResolver } from 'ele-admin-plus/es/utils/resolvers'; - +import GenSW from 'workbox-webpack-plugin'; export default defineConfig(({ command }) => { const isBuild = command === 'build'; const alias = { '@/': resolve('src') + '/', 'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js' }; - const plugins = [vue()]; + const plugins = [ + vue(), + new GenSW.GenerateSW({ + // 配置选项 + swDest: 'service-worker.js', // Service Worker 的输出文件路径 + clientsClaim: true, + skipWaiting: true, + exclude: [/\.map$/, /asset-manifest\.json$/], // 可选:排除某些文件 + }) + ]; if (isBuild) { // 组件按需引入 plugins.push( @@ -46,7 +55,7 @@ export default defineConfig(({ command }) => { resolve: { alias }, plugins, server: { - allowedHosts: ['a.tcp.run'] + allowedHosts: ['a.tcp.run'] }, css: { preprocessorOptions: {