mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-11 03:58:28 +08:00
feat: 添加版本更新检查功能
- 后端新增 /api/admin/system/check-update 接口,从 GitHub Tags 获取最新版本 - 前端新增 UpdateDialog 组件,管理员登录后自动检查更新并弹窗提示 - 同一会话内只检查一次,点击"稍后提醒"后 24 小时内不再提示 - CI 和 deploy.sh 自动生成 _version.py 版本文件
This commit is contained in:
@@ -295,6 +295,15 @@
|
||||
</template>
|
||||
|
||||
<RouterView />
|
||||
|
||||
<!-- 更新提示弹窗 -->
|
||||
<UpdateDialog
|
||||
v-if="updateInfo"
|
||||
v-model="showUpdateDialog"
|
||||
:current-version="updateInfo.current_version"
|
||||
:latest-version="updateInfo.latest_version || ''"
|
||||
:release-url="updateInfo.release_url"
|
||||
/>
|
||||
</AppShell>
|
||||
</template>
|
||||
|
||||
@@ -304,10 +313,12 @@ import { useRoute, useRouter } from 'vue-router'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useDarkMode } from '@/composables/useDarkMode'
|
||||
import { isDemoMode } from '@/config/demo'
|
||||
import { adminApi, type CheckUpdateResponse } from '@/api/admin'
|
||||
import Button from '@/components/ui/button.vue'
|
||||
import AppShell from '@/components/layout/AppShell.vue'
|
||||
import SidebarNav from '@/components/layout/SidebarNav.vue'
|
||||
import HeaderLogo from '@/components/HeaderLogo.vue'
|
||||
import UpdateDialog from '@/components/common/UpdateDialog.vue'
|
||||
import {
|
||||
Home,
|
||||
Users,
|
||||
@@ -345,17 +356,67 @@ const showAuthError = ref(false)
|
||||
const mobileMenuOpen = ref(false)
|
||||
let authCheckInterval: number | null = null
|
||||
|
||||
// 更新检查相关
|
||||
const showUpdateDialog = ref(false)
|
||||
const updateInfo = ref<CheckUpdateResponse | null>(null)
|
||||
|
||||
// 路由变化时自动关闭移动端菜单
|
||||
watch(() => route.path, () => {
|
||||
mobileMenuOpen.value = false
|
||||
})
|
||||
|
||||
// 检查是否应该显示更新提示
|
||||
function shouldShowUpdatePrompt(latestVersion: string): boolean {
|
||||
const ignoreKey = 'aether_update_ignore'
|
||||
const ignoreData = localStorage.getItem(ignoreKey)
|
||||
if (!ignoreData) return true
|
||||
|
||||
try {
|
||||
const { version, until } = JSON.parse(ignoreData)
|
||||
// 如果忽略的是同一版本且未过期,则不显示
|
||||
if (version === latestVersion && Date.now() < until) {
|
||||
return false
|
||||
}
|
||||
} catch {
|
||||
// 解析失败,显示提示
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 检查更新
|
||||
async function checkForUpdate() {
|
||||
// 只有管理员才检查更新
|
||||
if (authStore.user?.role !== 'admin') return
|
||||
|
||||
// 同一会话内只检查一次
|
||||
const sessionKey = 'aether_update_checked'
|
||||
if (sessionStorage.getItem(sessionKey)) return
|
||||
sessionStorage.setItem(sessionKey, '1')
|
||||
|
||||
try {
|
||||
const result = await adminApi.checkUpdate()
|
||||
if (result.has_update && result.latest_version) {
|
||||
if (shouldShowUpdatePrompt(result.latest_version)) {
|
||||
updateInfo.value = result
|
||||
showUpdateDialog.value = true
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// 静默失败,不影响用户体验
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
authCheckInterval = setInterval(() => {
|
||||
if (authStore.user && !authStore.token) {
|
||||
showAuthError.value = true
|
||||
}
|
||||
}, 5000)
|
||||
|
||||
// 延迟检查更新,避免影响页面加载
|
||||
setTimeout(() => {
|
||||
checkForUpdate()
|
||||
}, 2000)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
|
||||
Reference in New Issue
Block a user