/** * NAC知识引擎 - 多语言AI翻译服务 * * 支持七种语言:zh(中文)、en(英文)、ar(阿拉伯文)、ja(日文)、ko(韩文)、fr(法文)、ru(俄文) * * 使用OpenAI兼容接口(无Manus依赖,中国大陆可正常访问) * 通过环境变量配置: * NAC_AI_API_URL - AI接口地址(如 https://api.openai.com 或国内兼容端点) * NAC_AI_API_KEY - AI接口密钥 * NAC_AI_MODEL - 模型名称(默认 gpt-3.5-turbo) * * 阿拉伯语(ar)特殊处理: * - 文本方向:RTL(从右到左) * - 字符集:Unicode阿拉伯字符块(U+0600-U+06FF) * - 前端需设置 dir="rtl" 属性 */ export const SUPPORTED_LANGUAGES = ["zh", "en", "ar", "ja", "ko", "fr", "ru"] as const; export type SupportedLanguage = typeof SUPPORTED_LANGUAGES[number]; export const LANGUAGE_NAMES: Record = { zh: "中文(简体)", en: "English", ar: "العربية", ja: "日本語", ko: "한국어", fr: "Français", ru: "Русский", }; /** * RTL语言列表(从右到左书写) * 前端渲染时需要为这些语言设置 dir="rtl" */ export const RTL_LANGUAGES: SupportedLanguage[] = ["ar"]; /** * 判断语言是否为RTL */ export function isRTL(lang: SupportedLanguage): boolean { return RTL_LANGUAGES.includes(lang); } /** * 多语言内容结构 */ export interface MultiLangContent { zh?: string; en?: string; ar?: string; ja?: string; ko?: string; fr?: string; ru?: string; } // ─── AI翻译接口(OpenAI兼容,无Manus依赖)──────────────────────── /** * 检查AI翻译服务是否已配置 */ export function isAiTranslationConfigured(): boolean { return !!(process.env.NAC_AI_API_URL && process.env.NAC_AI_API_KEY); } /** * 调用AI接口进行翻译(OpenAI兼容格式) */ async function callAiTranslation( systemPrompt: string, userPrompt: string ): Promise { const apiUrl = process.env.NAC_AI_API_URL; const apiKey = process.env.NAC_AI_API_KEY; const model = process.env.NAC_AI_MODEL || "gpt-3.5-turbo"; if (!apiUrl || !apiKey) { throw new Error( "[AI翻译] 未配置AI接口。请在 .env 文件中设置 NAC_AI_API_URL 和 NAC_AI_API_KEY。\n" + "支持任何OpenAI兼容接口(如 OpenAI、Azure OpenAI、国内大模型等)。" ); } const endpoint = `${apiUrl.replace(/\/$/, "")}/v1/chat/completions`; const response = await fetch(endpoint, { method: "POST", headers: { "content-type": "application/json", authorization: `Bearer ${apiKey}`, }, body: JSON.stringify({ model, messages: [ { role: "system", content: systemPrompt }, { role: "user", content: userPrompt }, ], max_tokens: 2048, temperature: 0.3, // 低温度保证翻译一致性 }), }); if (!response.ok) { const errorText = await response.text(); throw new Error(`AI接口调用失败: ${response.status} ${response.statusText} – ${errorText}`); } const result = await response.json() as { choices: Array<{ message: { content: string } }>; }; const content = result.choices?.[0]?.message?.content; return (typeof content === "string" ? content : "").trim(); } /** * 使用AI翻译单个文本到指定语言 * * 阿拉伯语特殊说明: * - 翻译结果为标准现代阿拉伯语(MSA) * - 返回的文本为Unicode阿拉伯字符,前端需设置 dir="rtl" * - 专有名词(NAC、RWA等)保持英文不翻译 */ export async function translateText( sourceText: string, sourceLang: SupportedLanguage, targetLang: SupportedLanguage, context?: string ): Promise { if (sourceLang === targetLang) return sourceText; if (!sourceText.trim()) return sourceText; const contextHint = context ? `\n\n背景信息(仅供参考,不要翻译):${context}` : ""; // 阿拉伯语特殊提示 const arabicHint = targetLang === "ar" ? "\n特别说明:翻译成标准现代阿拉伯语(MSA),使用Unicode阿拉伯字符,文本方向为从右到左(RTL)。" : ""; const systemPrompt = `你是NAC(NewAssetChain)公链的专业法律合规翻译专家。 NAC是一条专注于RWA(真实世界资产)的原生公链,使用Charter智能合约语言、NVM虚拟机、CBPP共识协议。 你的任务是将合规规则文本从${LANGUAGE_NAMES[sourceLang]}翻译成${LANGUAGE_NAMES[targetLang]}。 要求: 1. 保持法律术语的准确性和专业性 2. 保留专有名词(如:NAC、RWA、Charter、NVM、CBPP、CSNP、CNNL、ACC-20、GNACS、XTZH)不翻译 3. 保留机构名称(如:SEC、SFC、MAS、ESMA、DFSA、DLD)不翻译 4. 只返回翻译结果,不要添加任何解释或注释${arabicHint}`; const userPrompt = `请将以下文本翻译成${LANGUAGE_NAMES[targetLang]}:\n\n${sourceText}${contextHint}`; try { const translated = await callAiTranslation(systemPrompt, userPrompt); return translated || sourceText; } catch (error) { console.error(`[Translation] 翻译到 ${targetLang} 失败:`, (error as Error).message); return sourceText; // 降级返回原文 } } /** * 为合规规则生成完整的七语言翻译 * @param ruleName 规则名称(源语言) * @param description 规则描述(源语言) * @param sourceLang 源语言 * @param existingTranslations 已有的翻译(跳过已有的) */ export async function generateRuleTranslations( ruleName: string, description: string, sourceLang: SupportedLanguage = "zh", existingTranslations?: { ruleNameI18n?: MultiLangContent; descriptionI18n?: MultiLangContent } ): Promise<{ ruleNameI18n: MultiLangContent; descriptionI18n: MultiLangContent }> { const ruleNameI18n: MultiLangContent = { ...(existingTranslations?.ruleNameI18n || {}) }; const descriptionI18n: MultiLangContent = { ...(existingTranslations?.descriptionI18n || {}) }; // 设置源语言内容 ruleNameI18n[sourceLang] = ruleName; descriptionI18n[sourceLang] = description; // 并行翻译所有缺失的语言 const targetLangs = SUPPORTED_LANGUAGES.filter( (lang) => lang !== sourceLang && !ruleNameI18n[lang] ); await Promise.all( targetLangs.map(async (targetLang) => { const [translatedName, translatedDesc] = await Promise.all([ translateText(ruleName, sourceLang, targetLang, `这是一条${description.slice(0, 50)}...的合规规则`), translateText(description, sourceLang, targetLang), ]); ruleNameI18n[targetLang] = translatedName; descriptionI18n[targetLang] = translatedDesc; }) ); return { ruleNameI18n, descriptionI18n }; } /** * 批量迁移现有规则,为其生成多语言翻译 */ export async function migrateRuleToMultiLang(rule: { ruleName: string; description: string; ruleNameI18n?: MultiLangContent; descriptionI18n?: MultiLangContent; }): Promise<{ ruleNameI18n: MultiLangContent; descriptionI18n: MultiLangContent }> { const sourceLang: SupportedLanguage = "zh"; return generateRuleTranslations( rule.ruleName, rule.description, sourceLang, { ruleNameI18n: rule.ruleNameI18n, descriptionI18n: rule.descriptionI18n } ); } /** * 阿拉伯语RTL测试用例 * 用于验证阿拉伯语翻译质量和RTL布局 */ export const ARABIC_RTL_TEST_CASES = [ { id: "ar-rtl-001", sourceLang: "zh" as SupportedLanguage, targetLang: "ar" as SupportedLanguage, sourceText: "不动产登记证要求", expectedContains: ["عقار", "تسجيل", "شهادة"], // 应包含房产/登记/证书相关词汇 isRTL: true, description: "房产登记证要求(阿拉伯语RTL测试)", }, { id: "ar-rtl-002", sourceLang: "en" as SupportedLanguage, targetLang: "ar" as SupportedLanguage, sourceText: "RWA asset compliance verification", expectedContains: ["امتثال", "أصول", "التحقق"], // 应包含合规/资产/验证相关词汇 isRTL: true, description: "RWA资产合规验证(阿拉伯语RTL测试)", }, { id: "ar-rtl-003", sourceLang: "zh" as SupportedLanguage, targetLang: "ar" as SupportedLanguage, sourceText: "NAC公链智能合约审批流程", expectedContains: ["NAC", "عقد", "موافقة"], // NAC不翻译,包含合约/审批相关词汇 isRTL: true, description: "NAC专有名词保留测试(阿拉伯语RTL)", }, ]; /** * 执行阿拉伯语RTL专项测试 * 返回测试结果报告 */ export async function runArabicRTLTests(): Promise<{ passed: number; failed: number; results: Array<{ id: string; description: string; passed: boolean; translated: string; isRTL: boolean; issues: string[]; }>; }> { if (!isAiTranslationConfigured()) { return { passed: 0, failed: ARABIC_RTL_TEST_CASES.length, results: ARABIC_RTL_TEST_CASES.map(tc => ({ id: tc.id, description: tc.description, passed: false, translated: "", isRTL: true, issues: ["AI翻译服务未配置,请设置 NAC_AI_API_URL 和 NAC_AI_API_KEY"], })), }; } const results = await Promise.all( ARABIC_RTL_TEST_CASES.map(async (tc) => { const issues: string[] = []; let translated = ""; try { translated = await translateText(tc.sourceText, tc.sourceLang, tc.targetLang); // 检查是否包含阿拉伯字符(Unicode范围 U+0600-U+06FF) const hasArabicChars = /[\u0600-\u06FF]/.test(translated); if (!hasArabicChars) { issues.push("翻译结果不包含阿拉伯字符"); } // 检查专有名词是否保留(NAC不应被翻译) if (tc.sourceText.includes("NAC") && !translated.includes("NAC")) { issues.push("专有名词NAC被错误翻译,应保留英文"); } // 检查是否为空 if (!translated.trim()) { issues.push("翻译结果为空"); } } catch (error) { issues.push(`翻译失败: ${(error as Error).message}`); } return { id: tc.id, description: tc.description, passed: issues.length === 0, translated, isRTL: tc.isRTL, issues, }; }) ); const passed = results.filter(r => r.passed).length; const failed = results.filter(r => !r.passed).length; return { passed, failed, results }; }