From 79172275f7bd61de09501def8ab1691c22b2050e Mon Sep 17 00:00:00 2001 From: overtrue Date: Wed, 9 Jul 2025 10:28:20 +0800 Subject: [PATCH] fix: server config --- pages/auth/login.vue | 30 ++++++++++-- pages/settings.vue | 32 ++++++------ plugins/01.config.ts | 67 ++++++++++++++----------- utils/config.ts | 114 +++++++++++++++++++++++++++++++++++++------ 4 files changed, 180 insertions(+), 63 deletions(-) diff --git a/pages/auth/login.vue b/pages/auth/login.vue index bf81db0..a4d6a5e 100644 --- a/pages/auth/login.vue +++ b/pages/auth/login.vue @@ -39,12 +39,29 @@ const expandedNames = ref([]) const configAlert = ref('') // 检查是否需要默认展开服务器配置 -onMounted(() => { +onMounted(async () => { + // 使用 configManager 加载配置(按优先级:config.json > localStorage > 默认值) + const config = await configManager.loadConfig() + if (config) { + const serverConfigData = configManager.extractServerConfig(config) + if (serverConfigData) { + // 更新 serverConfig + serverConfig.value = serverConfigData + + // 更新 serverUrl + serverUrl.value = `${serverConfigData.protocol}://${serverConfigData.host}:${serverConfigData.port}` + } + } + + // 如果没有有效配置,设置默认 serverUrl + if (!serverUrl.value) { + serverUrl.value = `${serverConfig.value.protocol}://${serverConfig.value.host}:${serverConfig.value.port}` + } + if (route.query.showConfig === '1') { expandedNames.value = ['server-config'] configAlert.value = t('No valid server configuration detected, please check server configuration') } - serverUrl.value = `${serverConfig.value.protocol}://${serverConfig.value.host}:${serverConfig.value.port}` }) const handleLogin = async () => { @@ -58,15 +75,18 @@ const handleLogin = async () => { const credentials = method.value === 'accessKeyAndSecretKey' ? accessKeyAndSecretKey.value : sts.value try { - // 保存配置到 localStorage - configManager.saveConfig({ + // 使用 configManager 保存配置(如果有 public/config.json 则不保存) + const saved = await configManager.saveConfig({ protocol: serverConfig.value.protocol, host: serverConfig.value.host, port: serverConfig.value.port, region: serverConfig.value.region }) - message.success(t('Server configuration saved')) + if (saved) { + message.success(t('Server configuration saved')) + } + await auth.login(credentials) message.success(t('Login Success')) window.location.href = '/' diff --git a/pages/settings.vue b/pages/settings.vue index 1a9830a..30abcea 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -15,36 +15,36 @@ const serverConfig = ref({ }) // 加载当前配置 -const loadCurrentConfig = () => { - const currentConfig = configManager.loadConfig() +const loadCurrentConfig = async () => { + const currentConfig = await configManager.loadConfig() if (currentConfig) { - // 从 baseURL 解析配置 - const url = new URL(currentConfig.api.baseURL) - serverConfig.value = { - protocol: url.protocol.replace(':', ''), - host: url.hostname, - port: url.port || (url.protocol === 'https:' ? '443' : '80'), - region: currentConfig.s3.region + const serverConfigData = configManager.extractServerConfig(currentConfig) + if (serverConfigData) { + serverConfig.value = serverConfigData } } } // 保存配置 -const saveConfig = () => { - configManager.saveConfig(serverConfig.value) - message.success(t('Server configuration saved')) +const saveConfig = async () => { + const saved = await configManager.saveConfig(serverConfig.value) + if (saved) { + message.success(t('Server configuration saved')) + } else { + message.info(t('Using public configuration, cannot save to localStorage')) + } } // 清除配置 -const clearConfig = () => { +const clearConfig = async () => { configManager.clearConfig() message.success('Configuration cleared') - loadCurrentConfig() + await loadCurrentConfig() } // 页面加载时读取当前配置 -onMounted(() => { - loadCurrentConfig() +onMounted(async () => { + await loadCurrentConfig() }) diff --git a/plugins/01.config.ts b/plugins/01.config.ts index 170e2ba..e00db9a 100644 --- a/plugins/01.config.ts +++ b/plugins/01.config.ts @@ -5,39 +5,50 @@ export default defineNuxtPlugin({ async setup(nuxtApp) { let finalConfig: any - // 优先级:localStorage > public/config.json > runtimeConfig try { - // 1. 首先尝试从 localStorage 读取配置 - const localStorageConfig = configManager.loadConfig() - if (localStorageConfig) { - finalConfig = { ...useRuntimeConfig().public, ...localStorageConfig } - console.log('Configuration loaded from localStorage') - } - - // 2. 如果 localStorage 没有配置,尝试从 public/config.json 加载 - if (!finalConfig) { - const response = await fetch('/config.json') - const remoteConfig = await response.json() - - // 获取license - // 判断是否是开发环境 - if (process.env.NODE_ENV !== 'development') { - const licenseResponse = await fetch('/license') - const licenseConfig = await licenseResponse.json() - remoteConfig.license = licenseConfig - } - - // 合并 public/runtimeConfig 与 remote 配置,remote 的优先 - finalConfig = { ...useRuntimeConfig().public, ...remoteConfig } - console.log('Configuration loaded from config.json') - } - - // 3. 如果都没有,使用 runtimeConfig - if (!finalConfig) { + // 使用 configManager 加载配置(内部优先级:config.json > localStorage > runtimeconfig) + const userConfig = await configManager.loadConfig() + if (userConfig) { + finalConfig = { ...useRuntimeConfig().public, ...userConfig } + console.log('Configuration loaded from configManager') + } else { + // 如果 configManager 没有配置,使用 runtimeConfig finalConfig = useRuntimeConfig().public console.log('Configuration loaded from runtimeConfig') } + // 如果有 public/config.json,尝试获取额外的信息(如 license) + if (await configManager.hasPublicConfig()) { + try { + const response = await fetch('/config.json') + const publicConfig = await response.json() + + // 保留 license 和其他额外信息 + if (publicConfig.license) { + finalConfig.license = publicConfig.license + } + if (publicConfig.release) { + finalConfig.release = publicConfig.release + } + if (publicConfig.doc) { + finalConfig.doc = publicConfig.doc + } + + // 获取 license 信息(如果不是开发环境) + if (process.env.NODE_ENV !== 'development') { + try { + const licenseResponse = await fetch('/license') + const licenseConfig = await licenseResponse.json() + finalConfig.license = licenseConfig + } catch (licenseError) { + console.warn('Failed to load license info:', licenseError) + } + } + } catch (error) { + console.warn('Failed to load additional config info:', error) + } + } + } catch (error) { console.error('Failed to load configuration:', error) diff --git a/utils/config.ts b/utils/config.ts index 8f956dc..9c44b16 100644 --- a/utils/config.ts +++ b/utils/config.ts @@ -18,25 +18,26 @@ export interface RustFSConfig { const CONFIG_KEY = 'rustfs-config' export const configManager = { - // 保存配置到 localStorage - saveConfig(serverConfig: ServerConfig): void { + // 从 public/config.json 读取配置 + async loadPublicConfig(): Promise { if (process.client) { - const config: RustFSConfig = { - api: { - baseURL: `${serverConfig.protocol}://${serverConfig.host}:${serverConfig.port}/rustfs/admin/v3` - }, - s3: { - endpoint: `${serverConfig.protocol}://${serverConfig.host}:${serverConfig.port}`, - region: serverConfig.region + try { + const response = await fetch('/config.json') + if (response.ok) { + const publicConfig = await response.json() + if (publicConfig.api?.baseURL) { + return publicConfig + } } + } catch (error) { + console.log('public/config.json not found') } - - localStorage.setItem(CONFIG_KEY, JSON.stringify(config)) } + return null }, // 从 localStorage 读取配置 - loadConfig(): RustFSConfig | null { + loadStorageConfig(): RustFSConfig | null { if (process.client) { try { const configStr = localStorage.getItem(CONFIG_KEY) @@ -50,6 +51,91 @@ export const configManager = { return null }, + // 从 nuxt runtimeconfig 读取配置 + loadRuntimeConfig(): RustFSConfig | null { + try { + const runtimeConfig = useRuntimeConfig() + if (runtimeConfig.public?.api?.baseURL) { + return { + api: { + baseURL: runtimeConfig.public.api.baseURL + }, + s3: { + endpoint: runtimeConfig.public.s3?.endpoint || runtimeConfig.public.api.baseURL, + region: runtimeConfig.public.s3?.region || 'us-east-1' + } + } + } + } catch (error) { + console.warn('Failed to load runtime config:', error) + } + return null + }, + + // 按优先级加载配置:config.json > localStorage > runtimeconfig + async loadConfig(): Promise { + // 首先尝试从 config.json 加载 + const publicConfig = await this.loadPublicConfig() + if (publicConfig) { + return publicConfig + } + + // 如果没有 config.json,尝试从 localStorage 加载 + const storageConfig = this.loadStorageConfig() + if (storageConfig) { + return storageConfig + } + + // 如果都没有,使用 runtimeconfig 作为默认值 + return this.loadRuntimeConfig() + }, + + // 从 RustFSConfig 提取 ServerConfig + extractServerConfig(config: RustFSConfig): ServerConfig | null { + try { + const urlObj = new URL(config.api.baseURL) + return { + protocol: urlObj.protocol.replace(':', ''), + host: urlObj.hostname, + port: urlObj.port || (urlObj.protocol === 'https:' ? '443' : '80'), + region: config.s3.region + } + } catch (error) { + console.warn('Failed to extract server config:', error) + return null + } + }, + + // 检查是否有 public/config.json + async hasPublicConfig(): Promise { + const config = await this.loadPublicConfig() + return !!config + }, + + // 保存配置到 localStorage(只有当没有 public/config.json 时) + async saveConfig(serverConfig: ServerConfig): Promise { + if (process.client) { + // 如果有 public/config.json,就不保存到 localStorage + if (await this.hasPublicConfig()) { + return false + } + + const config: RustFSConfig = { + api: { + baseURL: `${serverConfig.protocol}://${serverConfig.host}:${serverConfig.port}/rustfs/admin/v3` + }, + s3: { + endpoint: `${serverConfig.protocol}://${serverConfig.host}:${serverConfig.port}`, + region: serverConfig.region + } + } + + localStorage.setItem(CONFIG_KEY, JSON.stringify(config)) + return true + } + return false + }, + // 清除配置 clearConfig(): void { if (process.client) { @@ -58,8 +144,8 @@ export const configManager = { }, // 检查是否有有效配置 - hasValidConfig(): boolean { - const config = this.loadConfig() + async hasValidConfig(): Promise { + const config = await this.loadConfig() return !!(config?.api?.baseURL) } }