Skip to content

Commit

Permalink
chore: 路由切换时检测前端版本更新(原为定时器检测)
Browse files Browse the repository at this point in the history
  • Loading branch information
Charles7c committed Aug 4, 2024
1 parent ff405d1 commit 5fdfada
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 69 deletions.
68 changes: 0 additions & 68 deletions src/layout/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>
60 changes: 59 additions & 1 deletion src/router/permission.ts
Original file line number Diff line number Diff line change
@@ -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']

Expand Down Expand Up @@ -59,4 +111,10 @@ router.beforeEach(async (to, from, next) => {
next('/login')
}
}

// 生产环境开启检测版本更新
const isProd = import.meta.env.PROD
if (isProd) {
await compareTag()
}
})

0 comments on commit 5fdfada

Please sign in to comment.