This commit is contained in:
Baobhan Sith
2025-05-03 11:31:48 +08:00
parent f7aec93f29
commit eba70631de
4 changed files with 79 additions and 5 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@nexus-terminal/frontend",
"version": "0.2.2",
"version": "0.2.4",
"private": true,
"type": "module",
"scripts": {
+10 -1
View File
@@ -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": {
+10 -1
View File
@@ -690,7 +690,16 @@
},
"about": {
"version": "版本"
"version": "版本",
"checkingUpdate": "正在检查更新...",
"latestVersion": "已是最新版本",
"updateAvailable": "发现新版本 {version}",
"error": {
"checkFailed": "检查更新失败",
"checkFailedShort": "检查失败",
"noReleases": "未找到发布版本",
"rateLimit": "GitHub API 速率限制,请稍后再试"
}
}
},
"notificationController": {
+57 -1
View File
@@ -303,6 +303,23 @@
<div class="p-6 space-y-4"> <!-- Reduced space-y for tighter layout -->
<div class="flex items-center space-x-4 text-sm text-text-secondary"> <!-- Flex container for info items -->
<span class="font-medium">{{ $t('settings.about.version') }}: {{ appVersion }}</span>
<!-- Version Check Status -->
<span v-if="isCheckingVersion" class="inline-block text-xs ml-2 px-2 py-0.5 rounded-full bg-blue-500 text-white italic">
{{ $t('settings.about.checkingUpdate') }}
</span>
<span v-else-if="versionCheckError" class="inline-block text-xs ml-2 px-2 py-0.5 rounded-full bg-error text-white" :title="versionCheckError">
{{ $t('settings.about.error.checkFailedShort') }}
</span>
<span v-else-if="!isUpdateAvailable && latestVersion" class="inline-block text-xs ml-2 px-2 py-0.5 rounded-full bg-success text-white">
{{ $t('settings.about.latestVersion') }}
</span>
<a v-else-if="isUpdateAvailable && latestVersion"
:href="`https://github.com/Heavrnl/nexus-terminal/releases/tag/${latestVersion}`"
target="_blank" rel="noopener noreferrer"
class="inline-flex items-center text-xs ml-2 px-2 py-0.5 rounded-full bg-warning text-white hover:bg-warning/80">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-1 h-3 w-3"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" x2="12" y1="3" y2="15"/></svg>
{{ $t('settings.about.updateAvailable', { version: latestVersion }) }}
</a>
<span class="opacity-50">|</span>
<a href="https://github.com/Heavrnl/nexus-terminal" target="_blank" rel="noopener noreferrer" class="text-primary hover:underline inline-flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="mr-1" viewBox="0 0 16 16"> <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/> </svg>
@@ -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';
@@ -581,7 +599,16 @@ const appearanceStore = useAppearanceStore(); // 实例化外观 store
const { t } = useI18n();
const appVersion = ref(pkg.version); // 获取版本号
// --- Reactive state from store ---
// --- Version Check State ---
const latestVersion = ref<string | null>(null);
const isCheckingVersion = ref(false);
const versionCheckError = ref<string | null>(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()
});