i18n 国际化全量接入 + 修复与 UI 增强

- 引入 i18n 系统,所有用户可见字符串替换为 t() 调用,支持中/EN/日三语
- 插件激活时读取 ai.outputLanguage 配置初始化语言,onDidChangeConfiguration 监听变更自动切换
- ReviewPanel 与 SetupViewProvider 注册 onLanguageChange 回调,语言切换时全量重渲染
- package.json description:"AI 输出语言" -> "插件语言"
- 修复 repairJsonEscapes 无差别解引号导致 JSON 解析失败
- 设置页规则名称空值时输入框红框 + 错误提示
- 规则导入流程添加 withProgress 加载提示
This commit is contained in:
范智鹏
2026-07-26 15:44:26 +08:00
parent d96e4dd866
commit ff32ecf5c2
12 changed files with 220 additions and 140 deletions
+12 -12
View File
@@ -9,6 +9,7 @@ import type {
TranslatedDiagnostic,
AIFinding,
} from './schema';
import { t } from '../i18n/messages';
function buildCustomRulePrompt(rules: CustomRule[]): string {
return rules.map(r =>
@@ -27,22 +28,21 @@ function addLineNumbers(code: string): string {
}
function repairJsonEscapes(str: string): string {
let s = str.replace(/\\"\\n/g, '\\n').replace(/\\"/g, '"');
let inString = false;
let out = '';
for (let i = 0; i < s.length; i++) {
const ch = s[i];
for (let i = 0; i < str.length; i++) {
const ch = str[i];
if (ch === '\\') {
out += ch;
if (i + 1 < s.length) { out += s[++i]; }
if (i + 1 < str.length) { out += str[++i]; }
} else if (ch === '"') {
if (!inString) {
inString = true;
out += ch;
} else {
let j = i + 1;
while (j < s.length && s[j] === ' ') { j++; }
if (j < s.length && ':,\]}'.includes(s[j])) {
while (j < str.length && str[j] === ' ') { j++; }
if (j < str.length && ':,\]}'.includes(str[j])) {
inString = false;
out += ch;
} else {
@@ -109,7 +109,7 @@ export async function runAIReview(
translatedDiagnostics: [],
findings: [],
degraded: true,
error: '未配置 API Key',
error: t('adapter.noApiKey'),
};
}
@@ -125,7 +125,7 @@ export async function runAIReview(
translatedDiagnostics: [],
findings: [],
degraded: true,
error: `创建 Provider 失败: ${err instanceof Error ? err.message : String(err)}`,
error: t('adapter.createProviderFail', { 0: err instanceof Error ? err.message : String(err) }),
};
}
@@ -166,10 +166,10 @@ export async function runAIReview(
ruleId: `custom:${r.ruleId}`,
}));
} catch (e) {
errors.push(`自定义规则响应解析失败: ${e instanceof Error ? e.message : String(e)}`);
errors.push(t('adapter.customRuleParseFail', { 0: e instanceof Error ? e.message : String(e) }));
}
} else {
errors.push(`自定义规则请求失败: ${resultA.reason}`);
errors.push(t('adapter.customRuleRequestFail', { 0: resultA.reason }));
}
let translatedDiagnostics: TranslatedDiagnostic[] = [];
@@ -183,10 +183,10 @@ export async function runAIReview(
translatedDiagnostics = parsed.translatedDiagnostics ?? [];
findings = parsed.findings ?? [];
} catch (e) {
errors.push(`AI 审查响应解析失败: ${e instanceof Error ? e.message : String(e)}`);
errors.push(t('adapter.aiReviewParseFail', { 0: e instanceof Error ? e.message : String(e) }));
}
} else {
errors.push(`AI 审查请求失败: ${resultB.reason}`);
errors.push(t('adapter.aiReviewRequestFail', { 0: resultB.reason }));
}
const degraded = errors.length > 0;