diff --git a/frontend/.yarn/install-state.gz b/frontend/.yarn/install-state.gz deleted file mode 100644 index 2f3047b..0000000 Binary files a/frontend/.yarn/install-state.gz and /dev/null differ diff --git a/frontend/package.json b/frontend/package.json index 1476357..03550ed 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "frontend", "private": true, - "version": "1.0.1", + "version": "1.0.2", "main": "dist-electron/main.js", "scripts": { "dev": "concurrently \"vite\" \"yarn watch:main\" \"yarn electron-dev\"", diff --git a/frontend/src/components/initialization/AutoMode.vue b/frontend/src/components/initialization/AutoMode.vue index a7ffb90..0f61829 100644 --- a/frontend/src/components/initialization/AutoMode.vue +++ b/frontend/src/components/initialization/AutoMode.vue @@ -15,8 +15,20 @@
- 重新配置环境 - 强行进入应用 + + 重新配置环境 + + + 强行进入应用 +
@@ -41,9 +53,11 @@ import { ref, onMounted } from 'vue' import { getConfig } from '@/utils/config' import { getMirrorUrl } from '@/config/mirrors' +import { mirrorManager } from '@/utils/mirrorManager' import router from '@/router' import { useUpdateChecker } from '@/composables/useUpdateChecker' import { connectAfterBackendStart } from '@/composables/useWebSocket' +import { message } from 'ant-design-vue' @@ -69,6 +83,11 @@ const aborted = ref(false) // 状态:控制弹窗显隐 const forceEnterVisible = ref(false) +// 镜像源重试相关状态 +const currentMirrorIndex = ref(0) +const availableMirrors = ref([]) +const maxRetries = ref(3) + // 点击“强行进入应用”按钮,显示弹窗 function handleForceEnter() { forceEnterVisible.value = true @@ -104,12 +123,17 @@ async function startAutoProcess() { progressText.value = '发现更新,正在更新代码...' progress.value = 40 - // 使用配置中保存的Git镜像源 - const gitMirrorUrl = getGitMirrorUrl(config.selectedGitMirror) - const result = await window.electronAPI.updateBackend(gitMirrorUrl) + // 尝试更新代码,支持镜像源重试 + const updateSuccess = await tryUpdateBackendWithRetry(config) if (aborted.value) return - if (!result.success) { - throw new Error(`代码更新失败: ${result.error}`) + if (!updateSuccess) { + // 所有镜像源都失败了,显示重新配置按钮 + progressText.value = '代码更新失败,所有镜像源均无法访问' + progressStatus.value = 'exception' + setTimeout(() => { + progressText.value = '请点击下方按钮重新配置环境' + }, 2000) + return } } @@ -117,23 +141,17 @@ async function startAutoProcess() { progressText.value = '检查并安装依赖包...' progress.value = 60 - // 先尝试使用初始化时的镜像源 - let pipMirror = config.selectedPipMirror || 'tsinghua' - let pipResult = await window.electronAPI.installDependencies(pipMirror) + // 尝试安装依赖,支持镜像源重试 + const dependenciesSuccess = await tryInstallDependenciesWithRetry(config) if (aborted.value) return - // 如果初始化时的镜像源不通,让用户重新选择 - if (!pipResult.success) { - console.warn(`使用镜像源 ${pipMirror} 安装依赖失败,需要重新选择镜像源`) - - // 切换到手动模式让用户重新选择镜像源 - progressText.value = '依赖安装失败,需要重新配置镜像源' + if (!dependenciesSuccess) { + // 所有PIP镜像源都失败了,显示重新配置按钮 + progressText.value = '依赖安装失败,所有PIP镜像源均无法访问' progressStatus.value = 'exception' - setTimeout(() => { progressText.value = '请点击下方按钮重新配置环境' }, 2000) - return } @@ -184,6 +202,108 @@ function getGitMirrorUrl(mirrorKey: string): string { return getMirrorUrl('git', mirrorKey) } +// 尝试更新后端代码,支持镜像源重试 +async function tryUpdateBackendWithRetry(config: any): Promise { + // 获取所有Git镜像源 + const allGitMirrors = mirrorManager.getMirrors('git') + + // 加载用户的自定义镜像源 + const customMirrors = config.customGitMirrors || [] + const combinedMirrors = [...allGitMirrors, ...customMirrors] + + // 优先使用用户选择的镜像源 + const selectedMirror = combinedMirrors.find(m => m.key === config.selectedGitMirror) + let mirrorsToTry = selectedMirror ? [selectedMirror] : [] + + // 添加其他镜像源作为备选 + const otherMirrors = combinedMirrors.filter(m => m.key !== config.selectedGitMirror) + mirrorsToTry = [...mirrorsToTry, ...otherMirrors] + + console.log('准备尝试的Git镜像源:', mirrorsToTry.map(m => m.name)) + + for (let i = 0; i < mirrorsToTry.length; i++) { + if (aborted.value) return false + + const mirror = mirrorsToTry[i] + progressText.value = `正在使用 ${mirror.name} 更新代码... (${i + 1}/${mirrorsToTry.length})` + + try { + console.log(`尝试使用镜像源: ${mirror.name} (${mirror.url})`) + const result = await window.electronAPI.updateBackend(mirror.url) + + if (result.success) { + console.log(`使用镜像源 ${mirror.name} 更新成功`) + message.success(`使用 ${mirror.name} 更新代码成功`) + return true + } else { + console.warn(`镜像源 ${mirror.name} 更新失败:`, result.error) + if (i < mirrorsToTry.length - 1) { + progressText.value = `${mirror.name} 失败,尝试下一个镜像源...` + await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒 + } + } + } catch (error) { + console.error(`镜像源 ${mirror.name} 更新异常:`, error) + if (i < mirrorsToTry.length - 1) { + progressText.value = `${mirror.name} 异常,尝试下一个镜像源...` + await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒 + } + } + } + + console.error('所有Git镜像源都无法更新代码') + return false +} + +// 尝试安装依赖,支持镜像源重试 +async function tryInstallDependenciesWithRetry(config: any): Promise { + // 获取所有PIP镜像源 + const allPipMirrors = mirrorManager.getMirrors('pip') + + // 优先使用用户选择的镜像源 + const selectedMirror = allPipMirrors.find(m => m.key === config.selectedPipMirror) + let mirrorsToTry = selectedMirror ? [selectedMirror] : [] + + // 添加其他镜像源作为备选 + const otherMirrors = allPipMirrors.filter(m => m.key !== config.selectedPipMirror) + mirrorsToTry = [...mirrorsToTry, ...otherMirrors] + + console.log('准备尝试的PIP镜像源:', mirrorsToTry.map(m => m.name)) + + for (let i = 0; i < mirrorsToTry.length; i++) { + if (aborted.value) return false + + const mirror = mirrorsToTry[i] + progressText.value = `正在使用 ${mirror.name} 安装依赖... (${i + 1}/${mirrorsToTry.length})` + + try { + console.log(`尝试使用PIP镜像源: ${mirror.name} (${mirror.url})`) + const result = await window.electronAPI.installDependencies(mirror.key) + + if (result.success) { + console.log(`使用PIP镜像源 ${mirror.name} 安装成功`) + message.success(`使用 ${mirror.name} 安装依赖成功`) + return true + } else { + console.warn(`PIP镜像源 ${mirror.name} 安装失败:`, result.error) + if (i < mirrorsToTry.length - 1) { + progressText.value = `${mirror.name} 失败,尝试下一个镜像源...` + await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒 + } + } + } catch (error) { + console.error(`PIP镜像源 ${mirror.name} 安装异常:`, error) + if (i < mirrorsToTry.length - 1) { + progressText.value = `${mirror.name} 异常,尝试下一个镜像源...` + await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒 + } + } + } + + console.error('所有PIP镜像源都无法安装依赖') + return false +} + // 启动后端服务 async function startBackendService() { const result = await window.electronAPI.startBackend() diff --git a/frontend/src/components/initialization/BackendStep.vue b/frontend/src/components/initialization/BackendStep.vue index f14f910..16562a1 100644 --- a/frontend/src/components/initialization/BackendStep.vue +++ b/frontend/src/components/initialization/BackendStep.vue @@ -67,6 +67,67 @@ + +
+
+

自定义镜像源

+ 手动添加 +
+
+ + + + 添加 + + +
+ + +
+
+
+
+

{{ mirror.name }}

+ 自定义 +
+
+
+ 未测试 + 测试中... + 超时 + {{ mirror.speed }}ms +
+ + 删除 + +
+
+
{{ mirror.description }}
+
+
+
+
{{ testingGitSpeed ? '测速中...' : '重新测速' }} @@ -105,12 +166,26 @@ const sortedMirrorMirrors = computed(() => sortMirrorsBySpeedAndRecommendation(m const selectedGitMirror = ref('ghproxy_edgeone') const testingGitSpeed = ref(false) +// 自定义镜像源相关 +const customMirrorUrl = ref('') +const customMirrors = ref([]) +const addingCustomMirror = ref(false) + // 加载配置中的镜像源选择 async function loadMirrorConfig() { try { const config = await getConfig() - selectedGitMirror.value = config.selectedGitMirror + selectedGitMirror.value = config.selectedGitMirror || 'ghproxy_edgeone' + + // 加载自定义镜像源 + if (config.customGitMirrors && Array.isArray(config.customGitMirrors)) { + customMirrors.value = config.customGitMirrors + // 将自定义镜像源添加到gitMirrors中 + gitMirrors.value = [...GIT_MIRRORS, ...customMirrors.value] + } + console.log('Git镜像源配置已加载:', selectedGitMirror.value) + console.log('自定义镜像源已加载:', customMirrors.value.length, '个') } catch (error) { console.warn('加载Git镜像源配置失败:', error) } @@ -119,8 +194,12 @@ async function loadMirrorConfig() { // 保存镜像源选择 async function saveMirrorConfig() { try { - await saveConfig({ selectedGitMirror: selectedGitMirror.value }) + await saveConfig({ + selectedGitMirror: selectedGitMirror.value, + customGitMirrors: customMirrors.value + }) console.log('Git镜像源配置已保存:', selectedGitMirror.value) + console.log('自定义镜像源已保存:', customMirrors.value.length, '个') } catch (error) { console.warn('保存Git镜像源配置失败:', error) } @@ -176,6 +255,135 @@ function getSpeedClass(speed: number | null) { return 'speed-slow' } +// 处理自定义镜像源URL +function processCustomMirrorUrl(input: string): string { + const trimmedInput = input.trim() + + // 如果已经是完整的Git地址且以.git结尾,直接返回 + if (trimmedInput.includes('github.com/AUTO-MAS-Project/AUTO-MAS') && trimmedInput.endsWith('.git')) { + return trimmedInput + } + + // 如果是完整的Git地址但没有.git结尾,添加.git + if (trimmedInput.includes('github.com/AUTO-MAS-Project/AUTO-MAS')) { + return trimmedInput.endsWith('.git') ? trimmedInput : trimmedInput + '.git' + } + + // 如果只是域名,拼接完整地址 + let domain = trimmedInput + + // 移除协议前缀 + domain = domain.replace(/^https?:\/\//, '') + + // 移除尾部斜杠 + domain = domain.replace(/\/$/, '') + + // 拼接完整地址 + return `https://${domain}/https://github.com/AUTO-MAS-Project/AUTO-MAS.git` +} + +// 添加自定义镜像源 +async function addCustomMirror() { + if (!customMirrorUrl.value.trim()) { + return + } + + addingCustomMirror.value = true + + try { + const processedUrl = processCustomMirrorUrl(customMirrorUrl.value) + + // 检查是否已存在 + const existingMirror = [...gitMirrors.value, ...customMirrors.value].find( + m => m.url === processedUrl + ) + + if (existingMirror) { + console.warn('镜像源已存在:', processedUrl) + customMirrorUrl.value = '' + return + } + + // 生成镜像源配置 + const customKey = `custom_${Date.now()}` + const customName = extractDomainName(customMirrorUrl.value) + + const newMirror: MirrorConfig = { + key: customKey, + name: `${customName} (自定义)`, + url: processedUrl, + speed: null, + type: 'mirror', + chinaConnectivity: 'good', + description: `用户自定义的镜像源: ${customName}` + } + + // 添加到自定义镜像源列表 + customMirrors.value.push(newMirror) + + // 更新完整的镜像源列表 + gitMirrors.value = [...GIT_MIRRORS, ...customMirrors.value] + + // 自动选择新添加的镜像源 + selectedGitMirror.value = customKey + + // 保存配置 + await saveMirrorConfig() + + // 清空输入框 + customMirrorUrl.value = '' + + console.log('自定义镜像源添加成功:', newMirror) + + } catch (error) { + console.error('添加自定义镜像源失败:', error) + } finally { + addingCustomMirror.value = false + } +} + +// 提取域名作为显示名称 +function extractDomainName(url: string): string { + try { + // 移除协议前缀 + let domain = url.replace(/^https?:\/\//, '') + + // 如果包含路径,只取域名部分 + domain = domain.split('/')[0] + + // 移除端口号 + domain = domain.split(':')[0] + + return domain || '自定义镜像' + } catch { + return '自定义镜像' + } +} + +// 删除自定义镜像源 +async function removeCustomMirror(key: string) { + try { + // 从自定义镜像源列表中移除 + customMirrors.value = customMirrors.value.filter(m => m.key !== key) + + // 更新完整的镜像源列表 + gitMirrors.value = [...GIT_MIRRORS, ...customMirrors.value] + + // 如果当前选中的是被删除的镜像源,切换到默认镜像源 + if (selectedGitMirror.value === key) { + selectedGitMirror.value = 'ghproxy_edgeone' + } + + // 保存配置 + await saveMirrorConfig() + + console.log('自定义镜像源删除成功:', key) + + } catch (error) { + console.error('删除自定义镜像源失败:', error) + } +} + defineExpose({ selectedGitMirror, testGitMirrorSpeed, @@ -334,4 +542,34 @@ onMounted(async () => { font-size: 12px; color: var(--ant-color-text-tertiary); } + +.custom-mirror-input { + margin-bottom: 16px; +} + +.custom-mirror-help { + margin-top: 8px; +} + +.custom-mirror-help code { + background: var(--ant-color-fill-alter); + padding: 2px 4px; + border-radius: 3px; + font-family: 'Courier New', monospace; + font-size: 12px; +} + +.mirror-card.custom-mirror { + border-color: var(--ant-color-primary-border); +} + +.mirror-card.custom-mirror:hover { + border-color: var(--ant-color-primary); +} + +.mirror-actions { + display: flex; + align-items: center; + gap: 8px; +} \ No newline at end of file diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 78adbce..a7bd096 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -12,6 +12,9 @@ import 'dayjs/locale/zh-cn' // 导入日志系统 import { logger } from '@/utils/logger' +// 导入镜像管理器 +import { mirrorManager } from '@/utils/mirrorManager' + // 配置dayjs中文本地化 dayjs.locale('zh-cn') @@ -24,6 +27,13 @@ OpenAPI.BASE = API_ENDPOINTS.local logger.info('前端应用开始初始化') logger.info(`API基础URL: ${OpenAPI.BASE}`) +// 初始化镜像管理器(异步) +mirrorManager.initialize().then(() => { + logger.info('镜像管理器初始化完成') +}).catch((error) => { + logger.error('镜像管理器初始化失败:', error) +}) + // 创建应用实例 const app = createApp(App) diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index a316355..16badf9 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -94,6 +94,12 @@ const routes: RouteRecordRaw[] = [ component: () => import('../views/Logs.vue'), meta: { title: '日志查看' }, }, + { + path: '/mirror-test', + name: 'MirrorTest', + component: () => import('../views/MirrorTest.vue'), + meta: { title: '镜像配置测试' }, + }, ] const router = createRouter({ diff --git a/frontend/src/utils/cloudConfigManager.ts b/frontend/src/utils/cloudConfigManager.ts new file mode 100644 index 0000000..27684c0 --- /dev/null +++ b/frontend/src/utils/cloudConfigManager.ts @@ -0,0 +1,187 @@ +/** + * 云端配置管理器 + * 负责从云端拉取最新的镜像站配置,如果失败则使用本地兜底配置 + */ + +import type { MirrorCategory, MirrorConfig } from '@/config/mirrors' + +export interface CloudMirrorConfig { + version: string + lastUpdated: string + mirrors: MirrorCategory + apiEndpoints: Record + downloadLinks: Record +} + +export class CloudConfigManager { + private static instance: CloudConfigManager + private cloudConfigUrl = 'https://download.auto-mas.top/d/AUTO_MAS/Server/mirrors.json' + private fallbackConfig: CloudMirrorConfig | null = null + private currentConfig: CloudMirrorConfig | null = null + private fetchTimeout = 3000 // 3秒超时 + + private constructor() {} + + static getInstance(): CloudConfigManager { + if (!CloudConfigManager.instance) { + CloudConfigManager.instance = new CloudConfigManager() + } + return CloudConfigManager.instance + } + + /** + * 设置兜底配置(本地配置) + */ + setFallbackConfig(config: CloudMirrorConfig): void { + this.fallbackConfig = config + } + + /** + * 从云端拉取最新配置 + */ + async fetchCloudConfig(): Promise { + try { + console.log('正在从云端拉取镜像站配置...') + + const controller = new AbortController() + const timeoutId = setTimeout(() => controller.abort(), this.fetchTimeout) + + const response = await fetch(this.cloudConfigUrl, { + method: 'GET', + headers: { + 'Accept': 'application/json', + 'Cache-Control': 'no-cache' + }, + signal: controller.signal + }) + + clearTimeout(timeoutId) + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`) + } + + const config: CloudMirrorConfig = await response.json() + + // 验证配置格式 + if (!this.validateConfig(config)) { + throw new Error('云端配置格式不正确') + } + + this.currentConfig = config + console.log('云端配置拉取成功:', config.version) + return config + + } catch (error) { + console.warn('云端配置拉取失败:', error) + return null + } + } + + /** + * 验证配置格式是否正确 + */ + private validateConfig(config: any): config is CloudMirrorConfig { + if (!config || typeof config !== 'object') { + return false + } + + // 检查必需字段 + if (!config.version || !config.mirrors || !config.apiEndpoints || !config.downloadLinks) { + return false + } + + // 检查mirrors结构 + if (typeof config.mirrors !== 'object') { + return false + } + + // 检查每个镜像类型的配置 + for (const [type, mirrors] of Object.entries(config.mirrors)) { + if (!Array.isArray(mirrors)) { + return false + } + + // 检查每个镜像配置 + for (const mirror of mirrors as any[]) { + if (!mirror.key || !mirror.name || !mirror.url || !mirror.type) { + return false + } + } + } + + return true + } + + /** + * 获取当前有效配置(优先云端,兜底本地) + */ + getCurrentConfig(): CloudMirrorConfig | null { + return this.currentConfig || this.fallbackConfig + } + + /** + * 初始化配置(启动时调用) + */ + async initializeConfig(fallbackConfig: CloudMirrorConfig): Promise { + this.setFallbackConfig(fallbackConfig) + + // 尝试拉取云端配置 + const cloudConfig = await this.fetchCloudConfig() + + if (cloudConfig) { + console.log('使用云端配置') + return cloudConfig + } else { + console.log('使用本地兜底配置') + return fallbackConfig + } + } + + /** + * 手动刷新配置 + */ + async refreshConfig(): Promise<{ success: boolean; config?: CloudMirrorConfig; error?: string }> { + try { + const cloudConfig = await this.fetchCloudConfig() + + if (cloudConfig) { + return { success: true, config: cloudConfig } + } else { + return { + success: false, + error: '无法获取云端配置,继续使用当前配置', + config: this.getCurrentConfig() || undefined + } + } + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : '未知错误', + config: this.getCurrentConfig() || undefined + } + } + } + + /** + * 获取配置状态信息 + */ + getConfigStatus(): { + isUsingCloudConfig: boolean + version?: string + lastUpdated?: string + source: 'cloud' | 'fallback' + } { + const config = this.getCurrentConfig() + + return { + isUsingCloudConfig: this.currentConfig !== null, + version: config?.version, + lastUpdated: config?.lastUpdated, + source: this.currentConfig ? 'cloud' : 'fallback' + } + } +} + +// 导出单例实例 +export const cloudConfigManager = CloudConfigManager.getInstance() \ No newline at end of file diff --git a/frontend/src/utils/mirrorManager.ts b/frontend/src/utils/mirrorManager.ts index 1b06003..fe8bf80 100644 --- a/frontend/src/utils/mirrorManager.ts +++ b/frontend/src/utils/mirrorManager.ts @@ -14,6 +14,7 @@ import { sortMirrorsBySpeed, getFastestMirror, } from '@/config/mirrors' +import { cloudConfigManager, type CloudMirrorConfig } from './cloudConfigManager' /** * 镜像源管理器类 @@ -23,6 +24,7 @@ export class MirrorManager { private mirrorConfigs: MirrorCategory = { ...ALL_MIRRORS } private apiEndpoints = { ...API_ENDPOINTS } private downloadLinks = { ...DOWNLOAD_LINKS } + private isInitialized = false private constructor() {} @@ -36,6 +38,73 @@ export class MirrorManager { return MirrorManager.instance } + /** + * 初始化镜像管理器(从云端拉取配置) + */ + async initialize(): Promise { + if (this.isInitialized) { + return + } + + try { + // 准备兜底配置 + const fallbackConfig: CloudMirrorConfig = { + version: '1.0.0-local', + lastUpdated: new Date().toISOString(), + mirrors: { ...ALL_MIRRORS }, + apiEndpoints: { ...API_ENDPOINTS }, + downloadLinks: { ...DOWNLOAD_LINKS } + } + + // 从云端初始化配置 + const config = await cloudConfigManager.initializeConfig(fallbackConfig) + + // 更新本地配置 + this.mirrorConfigs = config.mirrors + this.apiEndpoints = config.apiEndpoints + this.downloadLinks = config.downloadLinks + + this.isInitialized = true + console.log('镜像管理器初始化完成') + } catch (error) { + console.error('镜像管理器初始化失败:', error) + // 使用默认配置 + this.isInitialized = true + } + } + + /** + * 手动刷新云端配置 + */ + async refreshCloudConfig(): Promise<{ success: boolean; error?: string }> { + try { + const result = await cloudConfigManager.refreshConfig() + + if (result.success && result.config) { + // 更新本地配置 + this.mirrorConfigs = result.config.mirrors + this.apiEndpoints = result.config.apiEndpoints + this.downloadLinks = result.config.downloadLinks + + return { success: true } + } else { + return { success: false, error: result.error } + } + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : '刷新配置失败' + } + } + } + + /** + * 获取配置状态 + */ + getConfigStatus() { + return cloudConfigManager.getConfigStatus() + } + /** * 获取指定类型的镜像源列表 */ diff --git a/frontend/src/views/Initialization.vue b/frontend/src/views/Initialization.vue index d3da8ca..025c2b7 100644 --- a/frontend/src/views/Initialization.vue +++ b/frontend/src/views/Initialization.vue @@ -34,6 +34,7 @@ import AdminCheck from '@/components/initialization/AdminCheck.vue' import AutoMode from '@/components/initialization/AutoMode.vue' import ManualMode from '@/components/initialization/ManualMode.vue' import type { DownloadProgress } from '@/types/initialization' +import { mirrorManager } from '@/utils/mirrorManager' const router = useRouter() @@ -48,6 +49,12 @@ const backendExists = ref(false) const dependenciesInstalled = ref(false) const serviceStarted = ref(false) +// 镜像配置状态 +const mirrorConfigStatus = ref({ + source: 'fallback' as 'cloud' | 'fallback', + version: '' +}) + // 组件引用 const manualModeRef = ref() @@ -230,6 +237,14 @@ function handleProgressUpdate(progress: DownloadProgress) { onMounted(async () => { console.log('初始化页面 onMounted 开始') + // 更新镜像配置状态 + const status = mirrorManager.getConfigStatus() + mirrorConfigStatus.value = { + source: status.source, + version: status.version || '' + } + console.log('镜像配置状态:', mirrorConfigStatus.value) + // 测试配置系统 try { console.log('测试配置系统...') diff --git a/frontend/src/views/MirrorTest.vue b/frontend/src/views/MirrorTest.vue new file mode 100644 index 0000000..66e954e --- /dev/null +++ b/frontend/src/views/MirrorTest.vue @@ -0,0 +1,256 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/views/Settings.vue b/frontend/src/views/Settings.vue index 987d8a1..5bea5e2 100644 --- a/frontend/src/views/Settings.vue +++ b/frontend/src/views/Settings.vue @@ -16,6 +16,7 @@ import type { SelectValue } from 'ant-design-vue/es/select' import type { SettingsData } from '../types/settings' import { Service, type VersionOut } from '@/api' import UpdateModal from '@/components/UpdateModal.vue' +import { mirrorManager } from '@/utils/mirrorManager' const updateData = ref>({}) @@ -32,6 +33,15 @@ const activeKey = ref('basic') const backendUpdateInfo = ref(null) +// 镜像配置相关状态 +const mirrorConfigStatus = ref({ + isUsingCloudConfig: false, + version: '', + lastUpdated: '', + source: 'fallback' as 'cloud' | 'fallback' +}) +const refreshingConfig = ref(false) + const settings = reactive({ UI: { IfShowTray: false, @@ -257,6 +267,34 @@ const checkUpdate = async () => { } } +// 镜像配置相关方法 +const updateMirrorConfigStatus = () => { + const status = mirrorManager.getConfigStatus() + mirrorConfigStatus.value = status +} + +const refreshMirrorConfig = async () => { + refreshingConfig.value = true + try { + const result = await mirrorManager.refreshCloudConfig() + if (result.success) { + message.success('镜像配置刷新成功') + updateMirrorConfigStatus() + } else { + message.warning(result.error || '刷新失败,继续使用当前配置') + } + } catch (error) { + console.error('刷新镜像配置失败:', error) + message.error('刷新镜像配置失败') + } finally { + refreshingConfig.value = false + } +} + +const goToMirrorTest = () => { + router.push('/mirror-test') +} + // 确认回调 const onUpdateConfirmed = () => { updateVisible.value = false @@ -265,6 +303,7 @@ const onUpdateConfirmed = () => { onMounted(() => { loadSettings() getBackendVersion() + updateMirrorConfigStatus() }) @@ -1186,6 +1225,97 @@ onMounted(() => {
+ + +
+
+
+

镜像站配置

+

+ 管理下载站和加速站配置,支持从云端自动更新最新的镜像站列表 +

+
+ + + +
+
+ 配置状态 +
+ + + + {{ mirrorConfigStatus.source === 'cloud' ? '云端配置' : '本地兜底配置' }} + + + + {{ mirrorConfigStatus.version }} + + + {{ new Date(mirrorConfigStatus.lastUpdated).toLocaleString() }} + + +
+
+
+ + + +
+
+ 配置管理 +
+ + + 刷新云端配置 + + + 更新状态 + + + 测试页面 + + +
+
+
+ + + +
+
+ 说明 +
+ + + +
+
+
+
+
+
+