|
|
@@ -0,0 +1,110 @@
|
|
|
+import { ElMessageBox } from 'element-plus'
|
|
|
+import type { Router } from 'vue-router'
|
|
|
+
|
|
|
+type AppVersion = {
|
|
|
+ version?: string
|
|
|
+ buildTime?: string
|
|
|
+}
|
|
|
+
|
|
|
+const CHECK_INTERVAL = 60 * 1000
|
|
|
+const VERSION_FILE = `${import.meta.env.BASE_URL}version.json`
|
|
|
+
|
|
|
+let currentVersion = ''
|
|
|
+let lastCheckAt = 0
|
|
|
+let checking = false
|
|
|
+let updateNotified = false
|
|
|
+let checkTimer: number | undefined
|
|
|
+
|
|
|
+const getVersionUrl = () => {
|
|
|
+ const versionUrl = new URL(VERSION_FILE, window.location.origin)
|
|
|
+ versionUrl.searchParams.set('t', String(Date.now()))
|
|
|
+ return versionUrl.toString()
|
|
|
+}
|
|
|
+
|
|
|
+const fetchAppVersion = async (): Promise<string> => {
|
|
|
+ const response = await fetch(getVersionUrl(), {
|
|
|
+ cache: 'no-store',
|
|
|
+ headers: {
|
|
|
+ 'Cache-Control': 'no-cache'
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ if (!response.ok) return ''
|
|
|
+
|
|
|
+ const data = (await response.json()) as AppVersion
|
|
|
+ return data.version || data.buildTime || ''
|
|
|
+}
|
|
|
+
|
|
|
+const reloadPage = () => {
|
|
|
+ console.log('111', 111)
|
|
|
+ window.location.reload()
|
|
|
+}
|
|
|
+
|
|
|
+const notifyUpdate = () => {
|
|
|
+ if (updateNotified) return
|
|
|
+
|
|
|
+ updateNotified = true
|
|
|
+ ElMessageBox.confirm('系统已发布新版本,点击确定后将刷新页面。', '发现新版本', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '稍后',
|
|
|
+ type: 'warning',
|
|
|
+ closeOnClickModal: false,
|
|
|
+ closeOnPressEscape: false
|
|
|
+ })
|
|
|
+ .then(reloadPage)
|
|
|
+ .catch(() => {
|
|
|
+ updateNotified = false
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const checkAppVersion = async (force = false) => {
|
|
|
+ if (import.meta.env.DEV || checking) return
|
|
|
+
|
|
|
+ const now = Date.now()
|
|
|
+ if (!force && now - lastCheckAt < CHECK_INTERVAL) return
|
|
|
+
|
|
|
+ checking = true
|
|
|
+ lastCheckAt = now
|
|
|
+
|
|
|
+ try {
|
|
|
+ const latestVersion = await fetchAppVersion()
|
|
|
+ if (!latestVersion) return
|
|
|
+
|
|
|
+ if (!currentVersion) {
|
|
|
+ currentVersion = latestVersion
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (latestVersion !== currentVersion) {
|
|
|
+ notifyUpdate()
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.warn('Failed to check app version:', error)
|
|
|
+ } finally {
|
|
|
+ checking = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export const setupAppVersionCheck = (router: Router) => {
|
|
|
+ checkAppVersion(true)
|
|
|
+
|
|
|
+ router.beforeResolve(() => {
|
|
|
+ checkAppVersion()
|
|
|
+ })
|
|
|
+
|
|
|
+ window.addEventListener('focus', () => {
|
|
|
+ checkAppVersion(true)
|
|
|
+ })
|
|
|
+
|
|
|
+ document.addEventListener('visibilitychange', () => {
|
|
|
+ if (document.visibilityState === 'visible') {
|
|
|
+ checkAppVersion(true)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ if (!checkTimer) {
|
|
|
+ checkTimer = window.setInterval(() => {
|
|
|
+ checkAppVersion()
|
|
|
+ }, CHECK_INTERVAL)
|
|
|
+ }
|
|
|
+}
|