From eefa858078c98f46cf6561e1bdb933a15bac5ee6 Mon Sep 17 00:00:00 2001 From: SunWuyuan Date: Sat, 5 Apr 2025 12:19:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 144 ++++++++++++++++++ dev-dist/sw.js | 57 +++---- public/config.json | 27 ---- public/favicon.ico | Bin 15406 -> 368 bytes .../image/apple-touch-icon-180x180.png | Bin public/{ => pwa}/image/favicon.ico | Bin public/{ => pwa}/image/logo.svg | 0 .../{ => pwa}/image/maskable-icon-512x512.png | Bin public/{ => pwa}/image/pwa-192x192.png | Bin public/{ => pwa}/image/pwa-512x512.png | Bin public/{ => pwa}/image/pwa-64x64.png | Bin public/sw-cache-manager.js | 2 +- src/components/CacheManager.vue | 47 +++--- .../cards/RandomPickerSettingsCard.vue | 117 -------------- src/pages/CacheManagement.vue | 50 +++++- src/pages/settings.vue | 12 +- vite.config.mjs | 115 ++++++-------- 17 files changed, 292 insertions(+), 279 deletions(-) delete mode 100644 public/config.json rename public/{ => pwa}/image/apple-touch-icon-180x180.png (100%) rename public/{ => pwa}/image/favicon.ico (100%) rename public/{ => pwa}/image/logo.svg (100%) rename public/{ => pwa}/image/maskable-icon-512x512.png (100%) rename public/{ => pwa}/image/pwa-192x192.png (100%) rename public/{ => pwa}/image/pwa-512x512.png (100%) rename public/{ => pwa}/image/pwa-64x64.png (100%) delete mode 100644 src/components/settings/cards/RandomPickerSettingsCard.vue diff --git a/.gitignore b/.gitignore index 17ab75f..7e66538 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,147 @@ pnpm-debug.log* *.sln *.sw? +# Created by https://www.toptal.com/developers/gitignore/api/node +# Edit at https://www.toptal.com/developers/gitignore?templates=node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +# End of https://www.toptal.com/developers/gitignore/api/node \ No newline at end of file diff --git a/dev-dist/sw.js b/dev-dist/sw.js index 48d0c19..2f5412d 100644 --- a/dev-dist/sw.js +++ b/dev-dist/sw.js @@ -67,9 +67,9 @@ if (!self.define) { }); }; } -define(['./workbox-5ea419d9'], (function (workbox) { 'use strict'; +define(['./workbox-20a2f87f'], (function (workbox) { 'use strict'; - importScripts("sw-cache-manager.js"); + importScripts("/sw-cache-manager.js"); self.skipWaiting(); workbox.clientsClaim(); @@ -82,55 +82,42 @@ define(['./workbox-5ea419d9'], (function (workbox) { 'use strict'; "url": "suppress-warnings.js", "revision": "d41d8cd98f00b204e9800998ecf8427e" }, { - "url": "/", - "revision": "0.0lkakoc2in8" + "url": "index.html", + "revision": "0.vjgf6ab2p68" }], {}); workbox.cleanupOutdatedCaches(); - workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("/"), { + workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { allowlist: [/^\/$/] })); - workbox.registerRoute(/\.(?:js)$/i, new workbox.StaleWhileRevalidate({ - "cacheName": "js-cache", + workbox.registerRoute(({ + url + }) => url.pathname.startsWith("/assets/"), new workbox.CacheFirst({ + "cacheName": "assets-cache", plugins: [new workbox.ExpirationPlugin({ - maxEntries: 100, - maxAgeSeconds: 604800 + maxEntries: 200, + maxAgeSeconds: 5184000 + }), new workbox.CacheableResponsePlugin({ + statuses: [0, 200] })] }), 'GET'); - workbox.registerRoute(/\.(?:css)$/i, new workbox.StaleWhileRevalidate({ - "cacheName": "css-cache", + workbox.registerRoute(({ + url + }) => url.pathname.startsWith("/pwa/"), new workbox.StaleWhileRevalidate({ + "cacheName": "pwa-cache", plugins: [new workbox.ExpirationPlugin({ maxEntries: 50, maxAgeSeconds: 604800 - })] - }), 'GET'); - workbox.registerRoute(/\.(?:html)$/i, new workbox.NetworkFirst({ - "cacheName": "html-cache", - plugins: [new workbox.ExpirationPlugin({ - maxEntries: 20, - maxAgeSeconds: 86400 - })] - }), 'GET'); - workbox.registerRoute(/\.(?:png|jpg|jpeg|svg|gif)$/i, new workbox.StaleWhileRevalidate({ - "cacheName": "images-cache", - plugins: [new workbox.ExpirationPlugin({ - maxEntries: 50, - maxAgeSeconds: 2592000 - })] - }), 'GET'); - workbox.registerRoute(/\/cdn-cgi\/.*/i, new workbox.NetworkFirst({ - "cacheName": "cdn-cgi-cache", - "networkTimeoutSeconds": 10, - plugins: [new workbox.ExpirationPlugin({ - maxEntries: 50, - maxAgeSeconds: 86400 + }), new workbox.CacheableResponsePlugin({ + statuses: [0, 200] })] }), 'GET'); workbox.registerRoute(({ url }) => { - return url.origin !== self.location.origin; + const path = url.pathname; + return !(path.includes("/assets/") || path.includes("/pwa/")); }, new workbox.NetworkFirst({ - "cacheName": "external-resources", + "cacheName": "other-resources", "networkTimeoutSeconds": 10, plugins: [new workbox.ExpirationPlugin({ maxEntries: 100, diff --git a/public/config.json b/public/config.json deleted file mode 100644 index d2b9fe4..0000000 --- a/public/config.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "studentList": [ - "张三", - "李四", - "王五", - "赵六", - "钱七" - ], - "homeworkArrange": [ - [ - "语文", - "数学", - "英语" - ], - [ - "物理", - "化学", - "生物" - ], - [ - "政治", - "历史", - "地理" - ] - ], - "url": "http://localhost:3030" -} \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico index 8fb9f91b3aab4eec0c76ffc5342528033c61e247..e0db2558fb8a73aaa7c48393ec2f2567fcf0ad3f 100644 GIT binary patch literal 368 zcmZQzU<5(~0|p?;!4SpBz#zuJz|a}s=g!L|#RX*YdV0770coHL1_KT@AQ{f|vmHor z7I;J!GcYi}0Aa?h)j`=nGk82*978JRyuGoJ_mF`=>q8MA$6k#HCeBW-aG!=3850h% z#?E=v#LUL-!p_28 z!l!V$;re3Vd!NfTGFr%+74DB!eP3t$ih0RnPoV(ic}p0!KJsJ=FrK%AaqHtw;RS;J zF$`-f9x-Gb3)Xb7p6A6N_DEAaL3Lgc!?Z`5q6xb5>KH4&2PP%|NwV|4m$&y1+rQoM zA_}tno({bg9*kK>oq=Y_-D$Y>@c~Q5k!J1%qWpXfX*OPrw?1kxMs&FA9q_UN88wk> zgIK@F0SSY;9nXA}WK{DHTxw#z$JfEf!S_P8A?U!A?~D`OZ-~xINUHz_7K5j&pUXO@ GgeCw`vVhJ2 literal 15406 zcmeHO3v5%@8NNVarCoU?zSqezmT6npu}xxXJJhY(x=s~hQ>SSYYSncU&|(|9Y?QVX z@}TB1G8mASM;tRKYgJkrAW)&g7${B%c>oE7;)O>NNO_bu4G-IdNB({PbTkJL{ZGDJe2DLL+vq#sL?l$jZPe_*I2y@|4sBRjso zUy`aUlJo$60})6B%aMKN&yMG1Qvjth%4dDy{HM^34) z&_TyGJg3UC{J|n2-wr)LDYwhNWBH4VL-JgYz;erTEKiMF20`|$Cf~GysBU40j@&)u zboK>@(yL25%R|RmS~6@99bG>PviV`j>&k~M@~J%cn{`uCzUOyY^23rlWt6DH=aut3 zlZo^g63xIXwP(4)hgT<|I>hSGqh7YbLP$jL+%p0>vM2Su?wmOV;-uyLFww=KN5Ox{j<% zmi}mZc22bZyxbmI!x+Ch3+qsk+#YbHJ{CdQjDh~;LRJB63Pq&~p

*N){PEn7FA;EAwj=|b_AUGw z{Eb1Zt8`N8chL?vjkw~yAvg~N+W_qV|N7U7a3HGfPY0GBqUxOaLJzPO2|Qz7H&yF{ z!Y@7SbxH$-YlpxgCaImE$Fk6T4dUMU!=a+u##*PZb&m9d@{VbA<&v z;n*Hvm#Nt5zF}Ud{=9#v%+3;8${f~WV?Q`CFATe5JXp$wT(q1TOU7#0jK6PDXZ)(1 zOSF4N3hStRA?+K$*ZctH(lRF!KFSL%W20hM6%Rz+k9We?_C36J>PVG2%Y`27X;nW+ z*x`6oe7S`dXABgw#vFYvuM;-c|L9ua=7z9?9B!cL=Fyiz34xz{6kpCd?PeyG2V7mkg!!m@d$btKgDK_Ib zt|Qt#$Am-fZ&{xA0GOAnn8Ue+QQBY3NiO*vfvd{5lsp3L_K5f@hhj{}^Nk#us4?p+ ztOM)g!1L3Ff(Tk8KQe4khoQS4_&0;4zo|FQr(iM%k4L+U*z zff0J2FQWxM*K?>u4d$6_8R>l`cK8U+!w`A!D@A2^2+L%A~GSv8* z(uV!wgkD)YqY(1-;X}j zv4?n}%=LOp! z;8GgCC~I2q%*#5{$kpuKJ6-ET*}o#)Z>p>vQsxF25{?c6CQ5()gsGtn{Ul`*ykb!bDMnnlGUdfYdn+9lsY%+pJ_Z_xHs+imH? z!L`+luUT1yv*4C1Z&<#Qlui*r2~lxBI`sAm+}oX{s=OcRf9A0%Q^56>8DC==kKtgy z>D-TeE@f3uu4&Y?ZVVlM3wLg~Z>Y}xfNE|1MIAijELQN`Y2<45F5=t5>wtYuk>yuH zXEJj-vN;uZD0|537U$Eq5Oek?f#JlNGq{dN(qiDuxO185eWG@Tuk1zKUsCs)MAVm# zZTvIN+Wl0&MDXYQF#3{qXA$(Ft>uw;>&qkE2f#n|`-?1D`gl8Gqj+=j77qvaV7#CH z-mDV$x0TsBRP5B|jZ%mFQ}FDv4Rn5l$yl(|`Q7Oe;~u+P58Qvv*6uy)7U=EIpPM-5 zPv}(pkwc!Zx3$@4;Y){)0d2tO5v#db4**wJ~;d2`ShTX zw|GaKwMoD4ydIzqSN(;l&j_8}$q^eYga7tU+}ZvgxyO*m1UDkuojePFZ zG`-$PpE1`DpyrLMO}R7wCfu3t6Y|B7d%f_n+{8^32;HSdS9&hVGwt*sUYr-!%%`a~|XP)!GJa zaPfvq9vz7{ms4}`U~qpQ+@r?~G$CeSuOWUWWPj8xrxoKsi%ALkMoN~Re@yeI<`b#& zQakqh?^Bfdlv*~90r${a#kP)=j;z5r;Qua|_8~6ciamnnhpFd84r{fjgNVx%{UgRa z5XnEKlf}cZ&elidYgP}Qi}Z0^o$C^y%G~k#_Qp8=1^BDy6=xQN&GlMeiCUK;x&F$^ zjA44c!M?-)Y1kOO--Oix|DE7=F!d?WE|oc-P;ICUYO&YsIA3qS68`^+SoxzLDfxQ- z)V%&7_{XQaWqV^?8s0=b5Yxwfs(L2+kBDu`F4FIF*gxGfML8AK#-01US-npCiqalZ z?M~DOWA<^ZR|~P;79^A!*A-C1sshAC6<~Z9P|a%vs7IcNOJh792S@Vc$sCItcXG)K z1Fn?E#hswKujQD~WT#qpf3`ix0(EL{#By^?PeQ2& { } }); -console.log('Cache Manager extension loaded'); \ No newline at end of file +console.log('Cache Manager extension loaded'); \ No newline at end of file diff --git a/src/components/CacheManager.vue b/src/components/CacheManager.vue index 2143d78..ef85a8c 100644 --- a/src/components/CacheManager.vue +++ b/src/components/CacheManager.vue @@ -92,22 +92,22 @@ export default { }, async refreshCaches() { if (!this.serviceWorkerActive) return; - + this.loading = true; this.message = ''; this.caches = []; - + try { // 获取所有缓存名称 const cacheNames = await this.sendMessageToSW({ type: 'CACHE_KEYS' }); - + // 获取每个缓存的内容 for (const cacheName of cacheNames.cacheNames) { - const cacheContent = await this.sendMessageToSW({ - type: 'CACHE_CONTENT', - cacheName + const cacheContent = await this.sendMessageToSW({ + type: 'CACHE_CONTENT', + cacheName }); - + this.caches.push({ name: cacheName, urls: cacheContent.urls || [] @@ -122,11 +122,11 @@ export default { async clearCache(cacheName) { this.loading = true; try { - const result = await this.sendMessageToSW({ - type: 'CLEAR_CACHE', - cacheName + const result = await this.sendMessageToSW({ + type: 'CLEAR_CACHE', + cacheName }); - + if (result.success) { this.showMessage(`已清除缓存: ${this.formatCacheName(cacheName)}`, 'success'); await this.refreshCaches(); @@ -142,12 +142,12 @@ export default { async clearUrl(cacheName, url) { this.loading = true; try { - const result = await this.sendMessageToSW({ - type: 'CLEAR_URL', + const result = await this.sendMessageToSW({ + type: 'CLEAR_URL', cacheName, - url + url }); - + if (result.success) { this.showMessage(`已从缓存中删除: ${this.getFileName(url)}`, 'success'); await this.refreshCaches(); @@ -164,11 +164,11 @@ export default { if (!confirm('确定要清除所有缓存吗?这可能会导致应用需要重新下载资源。')) { return; } - + this.loading = true; try { const result = await this.sendMessageToSW({ type: 'CLEAR_ALL_CACHES' }); - + if (result.success) { this.showMessage('已清除所有缓存', 'success'); await this.refreshCaches(); @@ -187,14 +187,14 @@ export default { reject(new Error('Service Worker 未控制页面')); return; } - + const messageChannel = new MessageChannel(); messageChannel.port1.onmessage = (event) => { resolve(event.data); }; - + navigator.serviceWorker.controller.postMessage(message, [messageChannel.port2]); - + // 设置超时 setTimeout(() => { reject(new Error('Service Worker 响应超时')); @@ -218,14 +218,15 @@ export default { const urlObj = new URL(url); const pathParts = urlObj.pathname.split('/'); return pathParts[pathParts.length - 1] || urlObj.hostname; - } catch (e) { + } catch (error) { + console.error('获取文件名失败:', error); return url; } }, showMessage(message, type = 'info') { this.message = message; this.messageType = type; - + // 5秒后自动清除消息 setTimeout(() => { if (this.message === message) { @@ -235,4 +236,4 @@ export default { } } } - \ No newline at end of file + diff --git a/src/components/settings/cards/RandomPickerSettingsCard.vue b/src/components/settings/cards/RandomPickerSettingsCard.vue deleted file mode 100644 index 42a1405..0000000 --- a/src/components/settings/cards/RandomPickerSettingsCard.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - \ No newline at end of file diff --git a/src/pages/CacheManagement.vue b/src/pages/CacheManagement.vue index 132d0af..b8d37e2 100644 --- a/src/pages/CacheManagement.vue +++ b/src/pages/CacheManagement.vue @@ -2,8 +2,51 @@ -

缓存管理

-

在这里您可以查看和管理应用的缓存文件。清除缓存可能会导致应用需要重新下载资源。

+
+ mdi-database-cog-outline +
+

缓存管理

+
管理应用的本地缓存资源
+
+
+ + + + mdi-information-outline + 在这里您可以查看和管理应用的缓存文件。清除缓存可能会导致应用需要重新下载资源,但有助于解决某些显示问题。 + + + + + + + +
+ mdi-information + 什么是缓存? +
+

缓存是浏览器在本地存储的网站资源副本,如图片、脚本和样式表等。这些缓存可以加快页面加载速度,减少数据使用,并在离线时提供基本功能。

+
+
+
+ + + + +
+ mdi-lightbulb-outline + 何时清除缓存? +
+
    +
  • 应用显示过时的内容
  • +
  • 界面出现异常
  • +
  • 应用功能不正常
  • +
+
+
+
+
+ @@ -17,6 +60,9 @@ export default { name: 'CacheManagementPage', components: { CacheManager + }, + metaInfo: { + title: '缓存管理' } } \ No newline at end of file diff --git a/src/pages/settings.vue b/src/pages/settings.vue index 687b6af..6a59c76 100644 --- a/src/pages/settings.vue +++ b/src/pages/settings.vue @@ -134,7 +134,7 @@ - + @@ -156,12 +156,10 @@ - - - + - + @@ -189,7 +187,6 @@ import AboutCard from '@/components/settings/AboutCard.vue'; import '../styles/settings.scss'; import dataProvider from '@/utils/dataProvider'; import SettingsExplorer from '@/components/settings/SettingsExplorer.vue'; -import RandomPickerSettingsCard from '@/components/settings/cards/RandomPickerSettingsCard.vue'; export default { name: 'Settings', @@ -205,8 +202,7 @@ export default { DataProviderSettingsCard, ThemeSettingsCard, EchoChamberCard, - SettingsExplorer, - RandomPickerSettingsCard + SettingsExplorer }, setup() { const { mobile } = useDisplay(); diff --git a/vite.config.mjs b/vite.config.mjs index 2570a60..65b8d53 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -19,86 +19,62 @@ export default defineConfig({ Layouts(), Vue({ template: { transformAssetUrls } - }), + }), VitePWA({ registerType: 'autoUpdate', devOptions: { - navigateFallback: '/', + navigateFallback: 'index.html', enabled: true, suppressWarnings: true, }, - - lang: 'zh-CN', + + lang: 'zh-CN', injectRegister: 'auto', strategies: 'generateSW', + + workbox: { - globPatterns: ['**/*.{js,css,html,png,svg,jpg,jpeg,gif,ico,woff,woff2,ttf,eot}'], - navigateFallback: '/', + globPatterns: ['*'], + navigateFallback: 'index.html', runtimeCaching: [ { - urlPattern: /\.(?:js)$/i, - handler: 'StaleWhileRevalidate', + urlPattern: ({ url }) => url.pathname.startsWith('/assets/'), + handler: 'CacheFirst', options: { - cacheName: 'js-cache', + cacheName: 'assets-cache', expiration: { - maxEntries: 100, - maxAgeSeconds: 60 * 60 * 24 * 7 // 7 天 - } - } - }, - { - urlPattern: /\.(?:css)$/i, - handler: 'StaleWhileRevalidate', - options: { - cacheName: 'css-cache', - expiration: { - maxEntries: 50, - maxAgeSeconds: 60 * 60 * 24 * 7 // 7 天 - } - } - }, - { - urlPattern: /\.(?:html)$/i, - handler: 'NetworkFirst', - options: { - cacheName: 'html-cache', - expiration: { - maxEntries: 20, - maxAgeSeconds: 60 * 60 * 24 // 1 天 - } - } - }, - { - urlPattern: /\.(?:png|jpg|jpeg|svg|gif)$/i, - handler: 'StaleWhileRevalidate', - options: { - cacheName: 'images-cache', - expiration: { - maxEntries: 50, - maxAgeSeconds: 60 * 60 * 24 * 30 // 30 天 - } - } - }, - { - urlPattern: /\/cdn-cgi\/.*/i, - handler: 'NetworkFirst', - options: { - cacheName: 'cdn-cgi-cache', - expiration: { - maxEntries: 50, - maxAgeSeconds: 60 * 60 * 24 // 1 天 + maxEntries: 200, + maxAgeSeconds: 60 * 60 * 24 * 60 // 60 天 }, - networkTimeoutSeconds: 10 + cacheableResponse: { + statuses: [0, 200] + } } }, { - // 匹配除了当前域名以外的所有请求 + urlPattern: ({ url }) => url.pathname.startsWith('/pwa/'), + handler: 'StaleWhileRevalidate', + options: { + cacheName: 'pwa-cache', + expiration: { + maxEntries: 50, + maxAgeSeconds: 60 * 60 * 24 * 7 // 7 天 + }, + cacheableResponse: { + statuses: [0, 200] + } + } + }, + { + // 匹配除了上述规则外的所有请求 urlPattern: ({ url }) => { - return url.origin !== self.location.origin; + const path = url.pathname; + // 排除已经由其他规则处理的路径 + return !(path.includes('/assets/') || path.includes('/pwa/')); }, handler: 'NetworkFirst', options: { - cacheName: 'external-resources', + cacheName: 'other-resources', expiration: { maxEntries: 100, maxAgeSeconds: 60 * 60 * 24 // 1 天 @@ -108,12 +84,13 @@ export default defineConfig({ statuses: [0, 200] } } - } + }, + ], additionalManifestEntries: [], clientsClaim: true, skipWaiting: true, - importScripts: ['sw-cache-manager.js'] + importScripts: ['/sw-cache-manager.js'] }, manifest: { name: 'Classworks作业板', @@ -128,22 +105,22 @@ export default defineConfig({ }, icons: [ { - src: '/image/pwa-64x64.png', + src: '/pwa/image/pwa-64x64.png', sizes: '64x64', type: 'image/png' }, { - src: '/image/pwa-192x192.png', + src: '/pwa/image/pwa-192x192.png', sizes: '192x192', type: 'image/png' }, { - src: '/image/pwa-512x512.png', + src: '/pwa/image/pwa-512x512.png', sizes: '512x512', type: 'image/png' }, { - src: '/image/maskable-icon-512x512.png', + src: '/pwa/image/maskable-icon-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' @@ -154,9 +131,15 @@ export default defineConfig({ name: '随机点名', short_name: '随机点名', url: '/#random-picker', + icons: [ + { + src: '/pwa/image/pwa-64x64.png', + sizes: '64x64', + type: 'image/png' + } + ] }, ], - } }), // https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin#readme