修复AI翻译功能

This commit is contained in:
2026-04-13 21:40:27 +08:00
parent c269a57588
commit 8e245076fe
2 changed files with 52 additions and 122 deletions
+25 -85
View File
@@ -1,60 +1,27 @@
import OpenAI from "openai"; import OpenAI from "openai";
import {getConfig} from "@/lib/config";
// AI 翻译配置
interface AIConfig {
apiKey: string;
baseUrl?: string;
model?: string;
}
// 默认配置(从环境变量)
function getDefaultConfig(): AIConfig {
return {
apiKey: process.env.AI_API_KEY || "",
baseUrl: process.env.AI_BASE_URL || undefined,
model: process.env.AI_MODEL || "gpt-3.5-turbo",
};
}
// 模块级配置存储
let savedConfig: AIConfig | null = null;
// 设置保存的配置
export function setAIConfig(config: AIConfig) {
savedConfig = config;
}
// 获取配置(优先使用保存的配置)
export function getAIConfig(): AIConfig {
return savedConfig || getDefaultConfig();
}
// 解析翻译结果
function parseTranslation(content: string): string | null { function parseTranslation(content: string): string | null {
const patterns = [ // 第一步:清理内容,移除 Markdown 代码块、换行、多余空格
/english\s*:\s*['"]([^'"]+)['"]/i, const cleanContent = content
/english\s*[:\s]+([^,'"\n]+)/i, .replace(/```json|```/g, '') // 移除 ```json 和 ```
/['"]([^'"]+)['"]\s*[,}].*english/i, .replace(/\n/g, ' ') // 把换行换成空格
/^([^,]+)\s*,\s*english\s*:\s*['"]([^'"]+)['"]/i, .trim();
];
for (const pattern of patterns) { // 精准匹配 english 字段(支持任何格式、带空格)
const match = content.match(pattern); const regex = /"english"\s*:\s*["']([^"']+)["']/i;
if (match) { const match = cleanContent.match(regex);
return match[1]?.trim() || null;
}
}
if (match && match[1]) {
return match[1].trim();
}
return null; return null;
} }
// 翻译单个词组(带重试) // 翻译单个词组(带重试)
export async function translateWithAI( export async function translateWithAI(word: string): Promise<string | null> {
word: string, // 获取配置
config?: AIConfig, const aiConfig = getConfig().ai
maxRetries: number = 3
): Promise<string | null> {
const aiConfig = config || getAIConfig();
if (!aiConfig.apiKey) { if (!aiConfig.apiKey) {
throw new Error("AI API Key 未配置"); throw new Error("AI API Key 未配置");
@@ -66,67 +33,40 @@ export async function translateWithAI(
}); });
const prompt = `你是一个专业的中文到英文翻译助手。 const prompt = `你是一个专业的中文到英文翻译助手。
任务:将给定的中文词组翻译成英文。 任务:将给定的中文词组翻译成英文。
严格要求: 严格要求:
1. 必须严格返回 JSON 格式:{"word":"中文原文","english":"英文翻译"} 1. 必须严格返回 JSON 格式:{"word":"中文原文","english":"英文翻译"}
2. 不要返回任何其他内容,不要解释 2. 不要返回任何其他内容,不要解释
3. 只返回这一行 JSON 3. 只返回这一行 JSON,不要加引号,不要加代码块
4. 翻译要简洁、准确 中文词组:${word}`;
中文词组:${word}
请立即返回 JSON 结果:`;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try { try {
const completion = await client.chat.completions.create({ const completion = await client.chat.completions.create({
model: aiConfig.model || "gpt-3.5-turbo", model: aiConfig.model,
messages: [ messages: [
{ {
role: "system", role: "system",
content: "你是一个严格遵循指令的翻译助手。必须只返回要求的 JSON 格式,不要返回任何其他内容。", content: "你是一个严格遵循指令的翻译助手。必须只返回一行纯 JSON,不要任何其他文字、符号、代码块。",
}, },
{ role: "user", content: prompt }, {role: "user", content: prompt},
], ]
temperature: 0,
max_tokens: 50,
}); });
const content = completion.choices[0]?.message?.content || ""; const content = completion.choices[0]?.message?.content || "";
const translation = parseTranslation(content); return parseTranslation(content);
if (translation && translation.length > 0) {
return translation;
}
// Fallback: 提取英文单词
const fallbackMatch = content.match(/[a-zA-Z][a-zA-Z\s-]*/);
if (fallbackMatch) {
const fallback = fallbackMatch[0].trim();
if (fallback.length > 1) {
return fallback;
}
}
} catch (error) { } catch (error) {
console.error(`Attempt ${attempt + 1} error:`, error); console.error("翻译出错:", error);
} }
}
return null; return null;
} }
// 批量翻译词组 // 批量翻译词组
export async function batchTranslateWithAI( export async function batchTranslateWithAI(
words: string[], words: string[]
config?: AIConfig
): Promise<Map<string, string>> { ): Promise<Map<string, string>> {
const results = new Map<string, string>(); const results = new Map<string, string>();
for (const word of words) { for (const word of words) {
try { try {
const translation = await translateWithAI(word, config); const translation = await translateWithAI(word);
if (translation) { if (translation) {
results.set(word, translation); results.set(word, translation);
} }
-10
View File
@@ -14,16 +14,6 @@ const pool = mysql.createPool({
connectionLimit: 10, connectionLimit: 10,
queueLimit: 0, queueLimit: 0,
}); });
console.log({
host: dataBaseConfig.host || "127.0.0.1",
port: dataBaseConfig.port || 3306,
user: dataBaseConfig.user || "root",
password: dataBaseConfig.password || "123456",
database: dataBaseConfig.database || "recipe_tools",
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
})
export default pool; export default pool;
/** /**