chore: 路由切换时检测前端版本更新(原为定时器检测)

This commit is contained in:
2024-08-04 23:25:28 +08:00
parent ff405d12ab
commit 5fdfada11d
2 changed files with 59 additions and 69 deletions

View File

@@ -4,80 +4,12 @@
</template>
<script setup lang="ts">
import { Button, Notification, Space } from '@arco-design/web-vue'
import LayoutDefault from './LayoutDefault.vue'
import LayoutMix from './LayoutMix.vue'
import { useAppStore } from '@/stores'
defineOptions({ name: 'Layout' })
const appStore = useAppStore()
let versionTag: string | null = null // 版本标识
let timer: NodeJS.Timeout | undefined // 定时器
// 更新
const onUpdateSystem = (id: string) => {
Notification.remove(id)
window.location.reload()
}
// 关闭更新弹窗
const onCloseUpdateSystem = (id: string) => {
Notification.remove(id)
}
// 提示用户更新弹窗
const handleNotification = () => {
const id = `updateModel`
Notification.info({
id,
title: '新版本更新',
content: '当前系统检测到有新的版本,请及时更新',
duration: 0,
closable: true,
position: 'bottomRight',
footer: () => {
return h(Space, {}, () => [h(Button, { type: 'primary', onClick: () => onUpdateSystem(id) }, '更新'), h(Button, { type: 'secondary', onClick: () => onCloseUpdateSystem(id) }, '关闭')])
}
})
}
/**
* 获取首页的 ETag 或 Last-Modified 值,作为当前版本标识
* @returns {Promise<string|null>} 返回 ETag 或 Last-Modified 值
*/
const getVersionTag = async () => {
const response = await fetch('/', {
cache: 'no-cache'
})
return response.headers.get('etag') || response.headers.get('last-modified')
}
/**
* 比较当前的 ETag 或 Last-Modified 值与最新获取的值
*/
const compareTag = async () => {
const newVersionTag = await getVersionTag()
if (versionTag === null) {
versionTag = newVersionTag
} else if (versionTag !== newVersionTag) {
// 如果 ETag 或 Last-Modified 发生变化,则认为有更新
// 清除定时器
clearInterval(timer)
// 提示用户更新
handleNotification()
}
}
const isProd = import.meta.env.PROD
onMounted(() => {
if (isProd) {
// 每60秒检查一次是否有新的 ETag 或 Last-Modified 值
timer = setInterval(compareTag, 6000)
}
})
onUnmounted(() => {
if (isProd) {
// 清除定时器
clearInterval(timer)
}
})
</script>
<style lang="scss" scoped></style>

View File

@@ -1,9 +1,61 @@
import { Message } from '@arco-design/web-vue'
import { Button, Message, Notification, Space } from '@arco-design/web-vue'
import router from '@/router'
import { useRouteStore, useUserStore } from '@/stores'
import { getToken } from '@/utils/auth'
import { isHttp } from '@/utils/validate'
// 版本更新
let versionTag: string | null = null // 版本标识
// 更新
const onUpdateSystem = (id: string) => {
Notification.remove(id)
window.location.reload()
}
// 关闭更新弹窗
const onCloseUpdateSystem = (id: string) => {
Notification.remove(id)
}
// 提示用户更新弹窗
const handleNotification = () => {
const id = `updateModel`
Notification.info({
id,
title: '新版本更新',
content: '当前系统检测到有新的版本,请及时更新',
duration: 0,
closable: true,
position: 'bottomRight',
footer: () => {
return h(Space, {}, () => [h(Button, { type: 'primary', onClick: () => onUpdateSystem(id) }, '更新'), h(Button, { type: 'secondary', onClick: () => onCloseUpdateSystem(id) }, '关闭')])
}
})
}
/**
* 获取首页的 ETag 或 Last-Modified 值,作为当前版本标识
* @returns {Promise<string|null>} 返回 ETag 或 Last-Modified 值
*/
const getVersionTag = async () => {
const response = await fetch('/', {
cache: 'no-cache'
})
return response.headers.get('etag') || response.headers.get('last-modified')
}
/**
* 比较当前的 ETag 或 Last-Modified 值与最新获取的值
*/
const compareTag = async () => {
const newVersionTag = await getVersionTag()
if (versionTag === null) {
versionTag = newVersionTag
} else if (versionTag !== newVersionTag) {
// 如果 ETag 或 Last-Modified 发生变化,则认为有更新
// 提示用户更新
handleNotification()
}
}
/** 免登录白名单 */
const whiteList = ['/login', '/social/callback', '/pwdExpired']
@@ -59,4 +111,10 @@ router.beforeEach(async (to, from, next) => {
next('/login')
}
}
// 生产环境开启检测版本更新
const isProd = import.meta.env.PROD
if (isProd) {
await compareTag()
}
})