diff --git a/src/components/SettingsModal.vue b/src/components/SettingsModal.vue index 9dc7978..462190e 100644 --- a/src/components/SettingsModal.vue +++ b/src/components/SettingsModal.vue @@ -159,6 +159,13 @@ > {{ option.label }} + + + {{ getLatencyText(option.value) }} + = { cfapi: 'https://cf.api.searchgal.homes', api: 'https://api.searchgal.homes', + gzapi: 'https://gz.api.searchgal.homes', usapi: 'https://us.api.searchgal.homes', jpapi: 'https://jp.api.searchgal.homes', deapi: 'https://de.api.searchgal.homes', @@ -583,6 +592,9 @@ function getOptionFromUrl(url: string): string { if (url === apiUrls.api) { return 'api' } + if (url === apiUrls.gzapi) { + return 'gzapi' + } if (url === apiUrls.usapi) { return 'usapi' } @@ -595,6 +607,77 @@ function getOptionFromUrl(url: string): string { return 'custom' } +// API 延迟测量 +const apiLatencies = ref>({}) + +// 测量单个 API 延迟(使用 no-cors 模式绕过 CORS 限制) +async function measureApiLatency(apiKey: string): Promise { + const url = apiUrls[apiKey] + if (!url) { return } + + apiLatencies.value[apiKey] = null // 测量中 + + try { + const controller = new AbortController() + const timeoutId = setTimeout(() => controller.abort(), 10000) // 10秒超时 + + const start = Date.now() + // no-cors 模式:无法读取响应内容,但可以测量网络延迟 + await fetch(url, { + method: 'GET', + mode: 'no-cors', + cache: 'no-store', + signal: controller.signal, + }) + const end = Date.now() + + clearTimeout(timeoutId) + + // 请求完成即视为成功(no-cors 模式无法读取状态码) + apiLatencies.value[apiKey] = Math.round(end - start) + } catch { + apiLatencies.value[apiKey] = 'error' + } +} + +// 测量所有 API 延迟 +function measureAllApiLatencies() { + const keys = Object.keys(apiUrls) + keys.forEach((key) => { + void measureApiLatency(key) + }) +} + +// 获取延迟显示文本 +function getLatencyText(apiKey: string): string { + const latency = apiLatencies.value[apiKey] + if (latency === undefined || latency === null) { + return '...' + } + if (latency === 'error') { + return '超时' + } + return `${latency}ms` +} + +// 获取延迟颜色类 +function getLatencyClass(apiKey: string): string { + const latency = apiLatencies.value[apiKey] + if (latency === undefined || latency === null) { + return 'text-gray-400 dark:text-slate-500' + } + if (latency === 'error') { + return 'text-red-500 dark:text-red-400' + } + if (latency < 100) { + return 'text-green-500 dark:text-green-400' + } + if (latency < 300) { + return 'text-yellow-500 dark:text-yellow-400' + } + return 'text-orange-500 dark:text-orange-400' +} + // 获取 API URL function getApiUrl(option: string): string { return apiUrls[option] || '' @@ -661,12 +744,14 @@ watch(() => props.isOpen, (isOpen) => { localVndbApiBaseUrl.value = settingsStore.settings.vndbApiBaseUrl localVndbImageProxyUrl.value = settingsStore.settings.vndbImageProxyUrl localAiTranslateApiUrl.value = settingsStore.settings.aiTranslateApiUrl + // 异步测量 API 延迟(不阻塞面板打开) + setTimeout(measureAllApiLatencies, 100) localAiTranslateApiKey.value = settingsStore.settings.aiTranslateApiKey localAiTranslateModel.value = settingsStore.settings.aiTranslateModel localBackgroundImageApiUrl.value = settingsStore.settings.backgroundImageApiUrl localVideoParseApiUrl.value = settingsStore.settings.videoParseApiUrl } -}) +}, { immediate: true }) function close() { playTap()