import fs from "fs"; import path from "path"; export interface DBConfig { host: string; port: number; user: string; password: string; database: string; } export interface AIConfig { apiKey: string; baseUrl: string; model: string; } export interface ExportConfig { // 未翻译文本的颜色 (hex) untranslatedColor: string; // 第二页是否显示表头 secondPageHeader: boolean; // 页面方向: portrait | landscape orientation: "portrait" | "landscape"; } export interface AppConfig { db: DBConfig; ai: AIConfig; export: ExportConfig; } // 配置文件路径(单一文件) const configPath = path.join(process.cwd(), "config.json"); /** * 检查配置文件是否存在 */ function configFileExists(): boolean { return fs.existsSync(configPath); } /** * 读取完整配置(仅从 config.json) */ function readConfigFile(): Partial { try { if (configFileExists()) { const content = fs.readFileSync(configPath, "utf-8"); return JSON.parse(content); } } catch (e) { console.error("Config read error:", e); } return {}; } /** * 写入完整配置 */ function writeConfigFile(config: AppConfig): void { fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8"); } /** * 初始化配置(仅在 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 { // 如果配置文件不存在,从环境变量初始化 if (!configFileExists()) { return initConfigFromEnv().db; } 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) */ export function getAIConfig(): AIConfig { // 如果配置文件不存在,从环境变量初始化 if (!configFileExists()) { return initConfigFromEnv().ai; } 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) */ export function getExportConfig(): ExportConfig { // 如果配置文件不存在,从环境变量初始化 if (!configFileExists()) { return initConfigFromEnv().export; } const fileConfig = readConfigFile(); const defaultConfig: ExportConfig = { untranslatedColor: "CC0000", secondPageHeader: false, orientation: "landscape", }; if (fileConfig.export) { return { untranslatedColor: fileConfig.export.untranslatedColor || defaultConfig.untranslatedColor, secondPageHeader: fileConfig.export.secondPageHeader ?? defaultConfig.secondPageHeader, orientation: fileConfig.export.orientation || defaultConfig.orientation, }; } return defaultConfig; } /** * 获取完整配置 */ export function getConfig(): AppConfig { // 如果配置文件不存在,从环境变量初始化 if (!configFileExists()) { return initConfigFromEnv(); } return { db: getDBConfig(), ai: getAIConfig(), export: getExportConfig(), }; } /** * 保存数据库配置 */ export function saveDBConfig(config: Partial): DBConfig { // 确保配置文件存在 if (!configFileExists()) { initConfigFromEnv(); } const current = getDBConfig(); const newConfig: DBConfig = { host: config.host ?? current.host, port: config.port ?? current.port, user: config.user ?? current.user, password: config.password ?? current.password, database: config.database ?? current.database, }; // 读取现有配置,更新 db 部分 const fileConfig = readConfigFile(); const updatedConfig: AppConfig = { ai: fileConfig.ai ?? { apiKey: "", baseUrl: "https://api.openai.com/v1", model: "gpt-3.5-turbo" }, export: fileConfig.export ?? { untranslatedColor: "CC0000", secondPageHeader: false, orientation: "landscape" }, db: newConfig, }; writeConfigFile(updatedConfig); return newConfig; } /** * 保存AI翻译配置 */ export function saveAIConfig(config: Partial): AIConfig { // 确保配置文件存在 if (!configFileExists()) { initConfigFromEnv(); } const current = getAIConfig(); const newConfig: AIConfig = { apiKey: config.apiKey ?? current.apiKey, baseUrl: config.baseUrl ?? current.baseUrl, model: config.model ?? current.model, }; // 读取现有配置,更新 ai 部分 const fileConfig = readConfigFile(); const updatedConfig: AppConfig = { db: fileConfig.db ?? { host: "127.0.0.1", port: 3306, user: "root", password: "", database: "recipe_tools" }, export: fileConfig.export ?? { untranslatedColor: "CC0000", secondPageHeader: false, orientation: "landscape" }, ai: newConfig, }; writeConfigFile(updatedConfig); return newConfig; } /** * 保存导出配置 */ export function saveExportConfig(config: Partial): ExportConfig { // 确保配置文件存在 if (!configFileExists()) { initConfigFromEnv(); } const current = getExportConfig(); const newConfig: ExportConfig = { untranslatedColor: config.untranslatedColor ?? current.untranslatedColor, secondPageHeader: config.secondPageHeader ?? current.secondPageHeader, orientation: config.orientation ?? current.orientation, }; // 读取现有配置,更新 export 部分 const fileConfig = readConfigFile(); const updatedConfig: AppConfig = { db: fileConfig.db ?? { host: "127.0.0.1", port: 3306, user: "root", password: "", database: "recipe_tools" }, ai: fileConfig.ai ?? { apiKey: "", baseUrl: "https://api.openai.com/v1", model: "gpt-3.5-turbo" }, export: newConfig, }; writeConfigFile(updatedConfig); return newConfig; } /** * 保存完整配置 */ export function saveConfig(config: Partial): AppConfig { // 确保配置文件存在 if (!configFileExists()) { initConfigFromEnv(); } const current = getConfig(); const fileConfig = readConfigFile(); return { db: config.db ? saveDBConfig(config.db) : current.db, ai: config.ai ? saveAIConfig(config.ai) : current.ai, export: config.export ? saveExportConfig(config.export) : current.export, }; }