80 lines
2.5 KiB
TypeScript
80 lines
2.5 KiB
TypeScript
import OpenAI from "openai";
|
|
import {getConfig} from "@/lib/config";
|
|
|
|
function parseTranslation(content: string): string | null {
|
|
// 第一步:清理内容,移除 Markdown 代码块、换行、多余空格
|
|
const cleanContent = content
|
|
.replace(/```json|```/g, '') // 移除 ```json 和 ```
|
|
.replace(/\n/g, ' ') // 把换行换成空格
|
|
.trim();
|
|
|
|
// 精准匹配 english 字段(支持任何格式、带空格)
|
|
const regex = /"english"\s*:\s*["']([^"']+)["']/i;
|
|
const match = cleanContent.match(regex);
|
|
|
|
if (match && match[1]) {
|
|
return match[1].trim();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// 翻译单个词组(带重试)
|
|
export async function translateWithAI(word: string): Promise<string | null> {
|
|
// 获取配置
|
|
const aiConfig = getConfig().ai
|
|
|
|
if (!aiConfig.apiKey) {
|
|
throw new Error("AI API Key 未配置");
|
|
}
|
|
|
|
const client = new OpenAI({
|
|
apiKey: aiConfig.apiKey,
|
|
baseURL: aiConfig.baseUrl,
|
|
});
|
|
|
|
const prompt = `你是一个专业的中文到英文翻译助手。
|
|
任务:将给定的中文词组翻译成英文。
|
|
严格要求:
|
|
1. 必须严格返回 JSON 格式:{"word":"中文原文","english":"英文翻译"}
|
|
2. 不要返回任何其他内容,不要解释
|
|
3. 只返回这一行 JSON,不要加引号,不要加代码块
|
|
中文词组:${word}`;
|
|
|
|
try {
|
|
const completion = await client.chat.completions.create({
|
|
model: aiConfig.model,
|
|
messages: [
|
|
{
|
|
role: "system",
|
|
content: "你是一个严格遵循指令的翻译助手。必须只返回一行纯 JSON,不要加任何其他文字、符号、代码块。",
|
|
},
|
|
{role: "user", content: prompt},
|
|
]
|
|
});
|
|
const content = completion.choices[0]?.message?.content || "";
|
|
return parseTranslation(content);
|
|
} catch (error) {
|
|
console.error("翻译出错:", error);
|
|
}
|
|
return null;
|
|
}
|
|
// 批量翻译词组
|
|
export async function batchTranslateWithAI(
|
|
words: string[]
|
|
): Promise<Map<string, string>> {
|
|
const results = new Map<string, string>();
|
|
|
|
for (const word of words) {
|
|
try {
|
|
const translation = await translateWithAI(word);
|
|
if (translation) {
|
|
results.set(word, translation);
|
|
}
|
|
} catch (error) {
|
|
console.error(`Failed to translate "${word}":`, error);
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|