From 0fcad02f3b4a43e3be07ef4d327b95e801f7cc26 Mon Sep 17 00:00:00 2001 From: PKC278 <52959804+PKC278@users.noreply.github.com> Date: Sat, 3 Jan 2026 20:15:05 +0800 Subject: [PATCH] =?UTF-8?q?fix(VersionUpdateToast):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E6=A0=B7=E5=BC=8F=20fix(useVersionChecker):?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 13 +++++++++-- src/App.vue | 3 ++- src/components/toast/VersionUpdateToast.vue | 24 ++++++++++++++++++--- src/composables/useVersionChecker.ts | 23 +++++++++++++------- src/styles/main.scss | 6 ++++++ 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/index.html b/index.html index b94410ca..b343341c 100644 --- a/index.html +++ b/index.html @@ -294,7 +294,7 @@ // 3. 重载页面 const url = new URL(window.location.href) url.searchParams.set('_t', Date.now().toString()) - window.location.replace(url.toString()) + window.location.replace(url.pathname + url.search + url.hash) } }; @@ -328,7 +328,16 @@ msg = messages['zh-CN']; } - timeoutEl.innerHTML = msg.text + ' ' + msg.btn + ''; + const textNode = document.createTextNode(msg.text + ' '); + const btnLink = document.createElement('a'); + btnLink.href = 'javascript:void(0)'; + btnLink.id = 'timeout-btn'; + btnLink.onclick = window.clearAndReload; + btnLink.textContent = msg.btn; + + timeoutEl.innerHTML = ''; + timeoutEl.appendChild(textNode); + timeoutEl.appendChild(btnLink); timeoutEl.style.display = 'block'; } }, 15000); // 15秒后显示超时提示 diff --git a/src/App.vue b/src/App.vue index af9b50fa..29da4893 100644 --- a/src/App.vue +++ b/src/App.vue @@ -241,7 +241,8 @@ onMounted(async () => { const url = new URL(window.location.href) if (url.searchParams.has('_t')) { url.searchParams.delete('_t') - window.history.replaceState({}, '', url.toString()) + const newUrl = url.pathname + url.search + url.hash + window.history.replaceState(null, '', newUrl) } // 配置 ApexCharts diff --git a/src/components/toast/VersionUpdateToast.vue b/src/components/toast/VersionUpdateToast.vue index 568bef28..0f5bb784 100644 --- a/src/components/toast/VersionUpdateToast.vue +++ b/src/components/toast/VersionUpdateToast.vue @@ -1,9 +1,10 @@ @@ -11,7 +12,7 @@ // 接收 props interface Props { message: string - refreshText: string + refreshText?: string onRefresh?: () => void } @@ -30,12 +31,12 @@ const handleRefresh = () => { .version-update-toast { display: flex; align-items: center; - justify-content: space-between; gap: 12px; } .message { flex: 1; + white-space: nowrap; } .refresh-button { @@ -48,6 +49,7 @@ const handleRefresh = () => { font-size: 14px; font-weight: 500; white-space: nowrap; + flex-shrink: 0; transition: all 0.2s; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } @@ -60,4 +62,20 @@ const handleRefresh = () => { .refresh-button:active { transform: scale(0.98); } + +.spinner { + width: 16px; + height: 16px; + border: 2px solid rgba(255, 255, 255, 0.3); + border-top-color: #fff; + border-radius: 50%; + animation: spin 0.8s linear infinite; + flex-shrink: 0; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} diff --git a/src/composables/useVersionChecker.ts b/src/composables/useVersionChecker.ts index 80e448d6..6407744b 100644 --- a/src/composables/useVersionChecker.ts +++ b/src/composables/useVersionChecker.ts @@ -19,7 +19,7 @@ const needsUpdate = computed(() => { export const reloadWithTimestamp = (): void => { const url = new URL(window.location.href) url.searchParams.set('_t', Date.now().toString()) - window.location.replace(url.toString()); + window.location.replace(url.pathname + url.search + url.hash) } /** @@ -72,6 +72,7 @@ export function useVersionChecker() { closeButton: false, closeOnClick: false, draggable: false, + toastClassName: 'version-update-toast-container', }) } @@ -104,13 +105,13 @@ export function useVersionChecker() { // 优先尝试通过 Service Worker 检查更新 if ('serviceWorker' in navigator && navigator.serviceWorker.controller) { - console.log('[VersionChecker] Requesting Service Worker update check...') + console.log('[VersionChecker] 正在请求 Service Worker 检查更新...') const registration = await navigator.serviceWorker.getRegistration() // 如果已经有等待中的更新,直接处理 if (registration?.waiting) { - console.log('[VersionChecker] New worker waiting, skipping manual check.') + console.log('[VersionChecker] Service Worker 发现新版本,跳过版本号对比') handleVersionMismatch() return } @@ -119,7 +120,7 @@ export function useVersionChecker() { messageChannel.port1.onmessage = event => { if (event.data && event.data.type === 'SW_NO_UPDATE_DETECTED') { - console.log('[VersionChecker] Service Worker reported no update, checking version manually...') + console.log('[VersionChecker] Service Worker 报告无更新, 进行版本号检查...') handleVersionMismatch() } } @@ -144,19 +145,25 @@ export function useVersionChecker() { navigator.serviceWorker.addEventListener('message', event => { // 1. 发现新版本 -> 弹出通知 if (event.data && event.data.type === 'SW_VERSION_DETECTED') { - console.log('[VersionChecker] Detected new version:', event.data.version) + console.log('[VersionChecker] 发现新版本:', event.data.version) notificationShowTime = Date.now() - toast.info(i18n.global.t('common.newVersionFound'), { + + const component = h(VersionUpdateToast, { + message: i18n.global.t('common.newVersionFound'), + }) + + toast.info(component, { timeout: false, hideProgressBar: true, closeButton: false, + toastClassName: 'version-update-toast-container', }) } // 2. 安装完成 -> 刷新页面 else if (event.data && event.data.type === 'SW_RELOAD_PAGE') { const elapsed = Date.now() - notificationShowTime - const delay = Math.max(0, 1000 - elapsed) - console.log(`[VersionChecker] Update installed, reloading in ${delay}ms...`) + const delay = Math.max(0, 1500 - elapsed) + console.log(`[VersionChecker] 更新已安装, 延迟 ${delay}ms 后刷新...`) setTimeout(() => { reloadWithTimestamp() }, delay) diff --git a/src/styles/main.scss b/src/styles/main.scss index 5f0be75f..c0fac356 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -11,3 +11,9 @@ @import 'vue-toastification/dist/index.css'; @import 'vue3-perfect-scrollbar/style.css'; @import '@vue-js-cron/vuetify/dist/vuetify.css'; + +/* 版本更新通知专用样式 */ +.version-update-toast-container { + min-width: unset !important; + width: fit-content !important; +}