feat: add recipe translation tool with AI translation and settings management
- Add Word document parsing and translation export - Add database configuration management - Add AI/LLM translation configuration - Add translation vocabulary management - Add export settings (colors, page orientation, headers) - Separate database and AI configurations - Add debounced search to prevent database overload
This commit is contained in:
+173
@@ -0,0 +1,173 @@
|
||||
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 AppConfig {
|
||||
db: DBConfig;
|
||||
ai: AIConfig;
|
||||
}
|
||||
|
||||
// 配置文件路径(单一文件)
|
||||
const configPath = path.join(process.cwd(), "config.json");
|
||||
|
||||
/**
|
||||
* 读取完整配置
|
||||
*/
|
||||
function readConfigFile(): Partial<AppConfig> {
|
||||
try {
|
||||
if (fs.existsSync(configPath)) {
|
||||
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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
return { host, port, user, password, database };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取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;
|
||||
}
|
||||
|
||||
return { apiKey, baseUrl, model };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整配置(兼容旧接口)
|
||||
*/
|
||||
export function getConfig(): AppConfig {
|
||||
return {
|
||||
db: getDBConfig(),
|
||||
ai: getAIConfig(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据库配置
|
||||
*/
|
||||
export function saveDBConfig(config: Partial<DBConfig>): DBConfig {
|
||||
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" },
|
||||
db: newConfig,
|
||||
};
|
||||
writeConfigFile(updatedConfig);
|
||||
|
||||
return newConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存AI翻译配置
|
||||
*/
|
||||
export function saveAIConfig(config: Partial<AIConfig>): AIConfig {
|
||||
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" },
|
||||
ai: newConfig,
|
||||
};
|
||||
writeConfigFile(updatedConfig);
|
||||
|
||||
return newConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存完整配置(兼容旧接口)
|
||||
*/
|
||||
export function saveConfig(config: Partial<AppConfig>): AppConfig {
|
||||
const current = getConfig();
|
||||
const fileConfig = readConfigFile();
|
||||
|
||||
return {
|
||||
db: config.db ? saveDBConfig(config.db) : current.db,
|
||||
ai: config.ai ? saveAIConfig(config.ai) : current.ai,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user