From 250abaa45378fc2709fc307b31ccc1b4a1160981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AF=92=E5=AF=92?= <2596194220@qq.com> Date: Mon, 13 Apr 2026 00:59:30 +0800 Subject: [PATCH] fix: only use env vars for initial config.json creation - Environment variables are only read when config.json doesn't exist - After first run, all config operations only read/write config.json - This prevents env vars from overriding user-saved settings --- config.json | 19 ------ lib/config.ts | 165 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 116 insertions(+), 68 deletions(-) delete mode 100644 config.json diff --git a/config.json b/config.json deleted file mode 100644 index da545d4..0000000 --- a/config.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "db": { - "host": "127.0.0.1", - "port": 3306, - "user": "root", - "password": "", - "database": "recipe_tools" - }, - "ai": { - "apiKey": "6a81b361620a44fd86aa3c8fcd833800.PjPyiU8kSzCTviYa", - "baseUrl": "https://open.bigmodel.cn/api/paas/v4/", - "model": "GLM-4.7-Flash" - }, - "export": { - "untranslatedColor": "CC0000", - "secondPageHeader": false, - "orientation": "landscape" - } -} \ No newline at end of file diff --git a/lib/config.ts b/lib/config.ts index c51c0cf..6c6f948 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -34,11 +34,18 @@ export interface AppConfig { const configPath = path.join(process.cwd(), "config.json"); /** - * 读取完整配置 + * 检查配置文件是否存在 + */ +function configFileExists(): boolean { + return fs.existsSync(configPath); +} + +/** + * 读取完整配置(仅从 config.json) */ function readConfigFile(): Partial { try { - if (fs.existsSync(configPath)) { + if (configFileExists()) { const content = fs.readFileSync(configPath, "utf-8"); return JSON.parse(content); } @@ -56,73 +63,108 @@ function writeConfigFile(config: AppConfig): void { } /** - * 获取数据库配置 - * 优先级:环境变量 > config.json + * 初始化配置(仅在 config.json 不存在时调用) + * 从环境变量读取初始值写入 config.json + */ +function initConfigFromEnv(): AppConfig { + const initialConfig: AppConfig = { + db: { + host: process.env.DB_HOST || "127.0.0.1", + port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306, + user: process.env.DB_USER || "root", + password: process.env.DB_PASSWORD || "", + database: process.env.DB_NAME || "recipe_tools", + }, + ai: { + apiKey: process.env.AI_API_KEY || "", + baseUrl: process.env.AI_BASE_URL || "https://api.openai.com/v1", + model: process.env.AI_MODEL || "gpt-3.5-turbo", + }, + export: { + untranslatedColor: process.env.EXPORT_UNTRANSLATED_COLOR || "CC0000", + secondPageHeader: process.env.EXPORT_SECOND_PAGE_HEADER === "true", + orientation: (process.env.EXPORT_ORIENTATION as "portrait" | "landscape") || "landscape", + }, + }; + + writeConfigFile(initialConfig); + return initialConfig; +} + +/** + * 获取数据库配置(仅从 config.json) */ export function getDBConfig(): DBConfig { - let host = "127.0.0.1"; - let port = 3306; - let user = "root"; - let password = ""; - let database = "recipe_tools"; - - // 环境变量优先级最高 - if (process.env.DB_HOST) host = process.env.DB_HOST; - if (process.env.DB_PORT) port = parseInt(process.env.DB_PORT); - if (process.env.DB_USER) user = process.env.DB_USER; - if (process.env.DB_PASSWORD) password = process.env.DB_PASSWORD; - if (process.env.DB_NAME) database = process.env.DB_NAME; - - // config.json 次之(仅当环境变量未设置时) - const fileConfig = readConfigFile(); - if (fileConfig.db) { - if (fileConfig.db.host && !process.env.DB_HOST) host = fileConfig.db.host; - if (fileConfig.db.port && !process.env.DB_PORT) port = fileConfig.db.port; - if (fileConfig.db.user && !process.env.DB_USER) user = fileConfig.db.user; - if (fileConfig.db.password && !process.env.DB_PASSWORD) password = fileConfig.db.password; - if (fileConfig.db.database && !process.env.DB_NAME) database = fileConfig.db.database; + // 如果配置文件不存在,从环境变量初始化 + if (!configFileExists()) { + return initConfigFromEnv().db; } - return { host, port, user, password, database }; + const fileConfig = readConfigFile(); + const defaultConfig: DBConfig = { + host: "127.0.0.1", + port: 3306, + user: "root", + password: "", + database: "recipe_tools", + }; + + if (fileConfig.db) { + return { + host: fileConfig.db.host || defaultConfig.host, + port: fileConfig.db.port || defaultConfig.port, + user: fileConfig.db.user || defaultConfig.user, + password: fileConfig.db.password ?? defaultConfig.password, + database: fileConfig.db.database || defaultConfig.database, + }; + } + + return defaultConfig; } /** - * 获取AI翻译配置 - * 优先级:环境变量 > config.json + * 获取AI翻译配置(仅从 config.json) */ export function getAIConfig(): AIConfig { - let apiKey = ""; - let baseUrl = "https://api.openai.com/v1"; - let model = "gpt-3.5-turbo"; - - // 环境变量优先级最高 - if (process.env.AI_API_KEY) apiKey = process.env.AI_API_KEY; - if (process.env.AI_BASE_URL) baseUrl = process.env.AI_BASE_URL; - if (process.env.AI_MODEL) model = process.env.AI_MODEL; - - // config.json 次之(仅当环境变量未设置时) - const fileConfig = readConfigFile(); - if (fileConfig.ai) { - if (fileConfig.ai.apiKey && !process.env.AI_API_KEY) apiKey = fileConfig.ai.apiKey; - if (fileConfig.ai.baseUrl && !process.env.AI_BASE_URL) baseUrl = fileConfig.ai.baseUrl; - if (fileConfig.ai.model && !process.env.AI_MODEL) model = fileConfig.ai.model; + // 如果配置文件不存在,从环境变量初始化 + if (!configFileExists()) { + return initConfigFromEnv().ai; } - return { apiKey, baseUrl, model }; + const fileConfig = readConfigFile(); + const defaultConfig: AIConfig = { + apiKey: "", + baseUrl: "https://api.openai.com/v1", + model: "gpt-3.5-turbo", + }; + + if (fileConfig.ai) { + return { + apiKey: fileConfig.ai.apiKey ?? defaultConfig.apiKey, + baseUrl: fileConfig.ai.baseUrl || defaultConfig.baseUrl, + model: fileConfig.ai.model || defaultConfig.model, + }; + } + + return defaultConfig; } /** - * 获取导出配置 - * 优先级:config.json(没有环境变量) + * 获取导出配置(仅从 config.json) */ export function getExportConfig(): ExportConfig { + // 如果配置文件不存在,从环境变量初始化 + if (!configFileExists()) { + return initConfigFromEnv().export; + } + + const fileConfig = readConfigFile(); const defaultConfig: ExportConfig = { untranslatedColor: "CC0000", secondPageHeader: false, orientation: "landscape", }; - const fileConfig = readConfigFile(); if (fileConfig.export) { return { untranslatedColor: fileConfig.export.untranslatedColor || defaultConfig.untranslatedColor, @@ -135,9 +177,14 @@ export function getExportConfig(): ExportConfig { } /** - * 获取完整配置(兼容旧接口) + * 获取完整配置 */ export function getConfig(): AppConfig { + // 如果配置文件不存在,从环境变量初始化 + if (!configFileExists()) { + return initConfigFromEnv(); + } + return { db: getDBConfig(), ai: getAIConfig(), @@ -149,6 +196,11 @@ export function getConfig(): AppConfig { * 保存数据库配置 */ export function saveDBConfig(config: Partial): DBConfig { + // 确保配置文件存在 + if (!configFileExists()) { + initConfigFromEnv(); + } + const current = getDBConfig(); const newConfig: DBConfig = { @@ -175,6 +227,11 @@ export function saveDBConfig(config: Partial): DBConfig { * 保存AI翻译配置 */ export function saveAIConfig(config: Partial): AIConfig { + // 确保配置文件存在 + if (!configFileExists()) { + initConfigFromEnv(); + } + const current = getAIConfig(); const newConfig: AIConfig = { @@ -199,6 +256,11 @@ export function saveAIConfig(config: Partial): AIConfig { * 保存导出配置 */ export function saveExportConfig(config: Partial): ExportConfig { + // 确保配置文件存在 + if (!configFileExists()) { + initConfigFromEnv(); + } + const current = getExportConfig(); const newConfig: ExportConfig = { @@ -220,9 +282,14 @@ export function saveExportConfig(config: Partial): ExportConfig { } /** - * 保存完整配置(兼容旧接口) + * 保存完整配置 */ export function saveConfig(config: Partial): AppConfig { + // 确保配置文件存在 + if (!configFileExists()) { + initConfigFromEnv(); + } + const current = getConfig(); const fileConfig = readConfigFile();