diff --git a/internal/server/router/dto/update.go b/internal/server/router/dto/update.go index 3df3b41..39ab91c 100644 --- a/internal/server/router/dto/update.go +++ b/internal/server/router/dto/update.go @@ -39,7 +39,8 @@ type VersionInfo struct { GitCommit string `json:"git_commit,omitempty"` BuildTime string `json:"build_time,omitempty"` GoVersion string `json:"go_version,omitempty"` - Platform string `json:"platform,omitempty"` + OS string `json:"os,omitempty"` + Arch string `json:"arch,omitempty"` } // StatusResponse 服务器状态响应 diff --git a/internal/server/router/handler/update.go b/internal/server/router/handler/update.go index 8191dbb..def6fc9 100644 --- a/internal/server/router/handler/update.go +++ b/internal/server/router/handler/update.go @@ -127,6 +127,7 @@ func getVersionInfo() dto.VersionInfo { GitCommit: info.GitCommit, BuildTime: info.BuildTime, GoVersion: info.GoVersion, - Platform: info.OS + "/" + info.Arch, + OS: info.OS, + Arch: info.Arch, } } diff --git a/web/src/App.vue b/web/src/App.vue index 132c9bc..bffa69f 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -6,10 +6,10 @@ import { type GlobalThemeOverrides } from 'naive-ui' import { - HomeOutline, ExtensionPuzzleOutline, SettingsOutline, - PersonCircleOutline, LogOutOutline, LogoGithub + HomeOutline, DesktopOutline, SettingsOutline, + PersonCircleOutline, LogOutOutline, LogoGithub, ServerOutline, CheckmarkCircleOutline, ArrowUpCircleOutline } from '@vicons/ionicons5' -import { getServerStatus, getVersionInfo, removeToken, getToken } from './api' +import { getServerStatus, getVersionInfo, checkServerUpdate, removeToken, getToken, type UpdateInfo } from './api' const router = useRouter() const route = useRoute() @@ -17,20 +17,20 @@ const serverInfo = ref({ bind_addr: '', bind_port: 0 }) const clientCount = ref(0) const version = ref('') const showUserMenu = ref(false) +const updateInfo = ref(null) const isLoginPage = computed(() => route.path === '/login') const navItems = [ { key: 'home', label: '首页', icon: HomeOutline, path: '/' }, - { key: 'plugins', label: '插件', icon: ExtensionPuzzleOutline, path: '/plugins' }, + { key: 'clients', label: '客户端', icon: DesktopOutline, path: '/clients' }, { key: 'settings', label: '设置', icon: SettingsOutline, path: '/settings' } ] const activeNav = computed(() => { const path = route.path if (path === '/' || path === '/home') return 'home' - if (path.startsWith('/client')) return 'home' - if (path === '/plugins') return 'plugins' + if (path === '/clients' || path.startsWith('/client/')) return 'clients' if (path === '/settings') return 'settings' return 'home' }) @@ -56,16 +56,28 @@ const fetchVersion = async () => { } } +const checkUpdate = async () => { + if (isLoginPage.value || !getToken()) return + try { + const { data } = await checkServerUpdate() + updateInfo.value = data + } catch (e) { + console.error('Failed to check update', e) + } +} + watch(() => route.path, (newPath, oldPath) => { if (oldPath === '/login' && newPath !== '/login') { fetchServerStatus() fetchVersion() + checkUpdate() } }) onMounted(() => { fetchServerStatus() fetchVersion() + checkUpdate() }) const logout = () => { @@ -139,7 +151,20 @@ const themeOverrides: GlobalThemeOverrides = {