From eba70631deeecd42a49ece8d038c2b0eaea869dd Mon Sep 17 00:00:00 2001 From: Baobhan Sith <80159437+Heavrnl@users.noreply.github.com> Date: Sat, 3 May 2025 11:31:48 +0800 Subject: [PATCH] update --- packages/frontend/package.json | 2 +- packages/frontend/src/locales/en-US.json | 11 +++- packages/frontend/src/locales/zh-CN.json | 11 +++- packages/frontend/src/views/SettingsView.vue | 60 +++++++++++++++++++- 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/packages/frontend/package.json b/packages/frontend/package.json index fbdccf5..2119bcc 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -1,6 +1,6 @@ { "name": "@nexus-terminal/frontend", - "version": "0.2.2", + "version": "0.2.4", "private": true, "type": "module", "scripts": { diff --git a/packages/frontend/src/locales/en-US.json b/packages/frontend/src/locales/en-US.json index 6da41c4..8ad4ec8 100644 --- a/packages/frontend/src/locales/en-US.json +++ b/packages/frontend/src/locales/en-US.json @@ -689,7 +689,16 @@ } }, "about": { - "version": "Version" + "version": "Version", + "checkingUpdate": "Checking for update...", + "latestVersion": "Up to date", + "updateAvailable": "Update available: {version}!", + "error": { + "checkFailed": "Failed to check for updates", + "checkFailedShort": "Check failed", + "noReleases": "No releases found", + "rateLimit": "GitHub API rate limit exceeded, please try again later" + } } }, "notificationController": { diff --git a/packages/frontend/src/locales/zh-CN.json b/packages/frontend/src/locales/zh-CN.json index 2994c7e..1b595be 100644 --- a/packages/frontend/src/locales/zh-CN.json +++ b/packages/frontend/src/locales/zh-CN.json @@ -690,7 +690,16 @@ }, "about": { - "version": "版本" + "version": "版本", + "checkingUpdate": "正在检查更新...", + "latestVersion": "已是最新版本", + "updateAvailable": "发现新版本 {version}!", + "error": { + "checkFailed": "检查更新失败", + "checkFailedShort": "检查失败", + "noReleases": "未找到发布版本", + "rateLimit": "GitHub API 速率限制,请稍后再试" + } } }, "notificationController": { diff --git a/packages/frontend/src/views/SettingsView.vue b/packages/frontend/src/views/SettingsView.vue index dd21c11..1dc63c8 100644 --- a/packages/frontend/src/views/SettingsView.vue +++ b/packages/frontend/src/views/SettingsView.vue @@ -303,6 +303,23 @@
{{ $t('settings.about.version') }}: {{ appVersion }} + + + {{ $t('settings.about.checkingUpdate') }} + + + {{ $t('settings.about.error.checkFailedShort') }} + + + {{ $t('settings.about.latestVersion') }} + + + + {{ $t('settings.about.updateAvailable', { version: latestVersion }) }} + | @@ -563,6 +580,7 @@ interface UpdateCaptchaSettingsDto { recaptchaSecretKey?: string; } import { ref, onMounted, computed, reactive, watch } from 'vue'; +import axios from 'axios'; // 导入 axios 用于 API 请求 import pkg from '../../package.json'; // 导入 package.json import { useAuthStore } from '../stores/auth.store'; import { useSettingsStore } from '../stores/settings.store'; @@ -580,8 +598,17 @@ const settingsStore = useSettingsStore(); const appearanceStore = useAppearanceStore(); // 实例化外观 store const { t } = useI18n(); const appVersion = ref(pkg.version); // 获取版本号 - - // --- Reactive state from store --- + +// --- Version Check State --- +const latestVersion = ref(null); +const isCheckingVersion = ref(false); +const versionCheckError = ref(null); +const isUpdateAvailable = computed(() => { + // 简单的字符串比较,假设 tag 格式为 vX.Y.Z + return latestVersion.value && latestVersion.value !== `v${appVersion.value}`; +}); + +// --- Reactive state from store --- // 使用 storeToRefs 获取响应式 getter,包括 language const { settings, @@ -1175,11 +1202,40 @@ const handleUpdateCaptchaSettings = async () => { }; +// --- Version Check Function --- +const checkLatestVersion = async () => { + isCheckingVersion.value = true; + versionCheckError.value = null; + latestVersion.value = null; + try { + // 使用 GitHub API 获取最新的 release 信息 + // 移除 headers 以避免 CORS 问题 + const response = await axios.get('https://api.github.com/repos/Heavrnl/nexus-terminal/releases/latest'); + if (response.data && response.data.tag_name) { + latestVersion.value = response.data.tag_name; + } else { + throw new Error('Invalid API response format'); + } + } catch (error: any) { + console.error('检查最新版本失败:', error); + if (axios.isAxiosError(error) && error.response?.status === 404) { + versionCheckError.value = t('settings.about.error.noReleases'); // 没有找到发布版本 + } else if (axios.isAxiosError(error) && error.response?.status === 403) { + versionCheckError.value = t('settings.about.error.rateLimit'); // API 速率限制 + } else { + versionCheckError.value = t('settings.about.error.checkFailed'); // 通用检查失败 + } + } finally { + isCheckingVersion.value = false; + } +}; + // --- Lifecycle Hooks --- onMounted(async () => { await checkTwoFactorStatus(); // Check 2FA status await fetchIpBlacklist(); // Fetch current blacklist entries await settingsStore.loadCaptchaSettings(); // <-- Load CAPTCHA settings + await checkLatestVersion(); // <-- Check for latest version on mount // Removed fetchPasskeys call: await authStore.fetchPasskeys(); // Initial settings (including language, whitelist, blacklist config) are loaded in main.ts via settingsStore.loadInitialSettings() });