/* 将现有的 copy-audit.xlsx 转换为 i18next 格式的翻译文件 */ const fs = require('fs'); const path = require('path'); const XLSX = require('xlsx'); const WORKDIR = process.cwd(); function generateI18nKey(item) { // 生成 i18next 格式的键名 const route = item.route === "shared" ? "common" : item.route.replace(/[^a-zA-Z0-9]/g, "_"); const component = item.componentOrFn.replace(/[^a-zA-Z0-9]/g, "_"); const kind = item.kind; const locator = item.keyOrLocator.replace(/[^a-zA-Z0-9]/g, "_"); return `${route}.${component}.${kind}.${locator}`.toLowerCase(); } function main() { // 读取现有的 Excel 文件 const excelFile = path.join(WORKDIR, 'docs', 'copy-audit.xlsx'); if (!fs.existsSync(excelFile)) { console.error('❌ 找不到 copy-audit.xlsx 文件,请先运行 extract-copy 脚本'); process.exit(1); } const workbook = XLSX.readFile(excelFile); const sheetName = workbook.SheetNames[0]; const worksheet = workbook.Sheets[sheetName]; const data = XLSX.utils.sheet_to_json(worksheet); console.log(`📊 读取到 ${data.length} 条记录`); // 生成 i18next 格式的翻译文件 const translation = {}; const i18nKeys = []; data.forEach((item, index) => { if (item.text && item.text.trim()) { const key = generateI18nKey(item); translation[key] = item.text; i18nKeys.push({ key, value: item.text, route: item.route, file: item.file, line: item.line, kind: item.kind }); } }); // 确保目录存在 const localesDir = path.join(WORKDIR, 'public', 'locales', 'en'); if (!fs.existsSync(localesDir)) { fs.mkdirSync(localesDir, { recursive: true }); } // 写入翻译文件 const translationFile = path.join(localesDir, 'translation.json'); fs.writeFileSync(translationFile, JSON.stringify(translation, null, 2)); // 生成详细的 i18n 扫描报告 const report = { totalItems: data.length, uniqueTexts: new Set(data.map(item => item.text)).size, translationKeys: Object.keys(translation).length, byRoute: data.reduce((acc, item) => { acc[item.route] = (acc[item.route] || 0) + 1; return acc; }, {}), byKind: data.reduce((acc, item) => { acc[item.kind] = (acc[item.kind] || 0) + 1; return acc; }, {}), sampleKeys: Object.keys(translation).slice(0, 10) }; // 生成 Excel 格式的 i18n 报告 const i18nWorkbook = XLSX.utils.book_new(); const i18nSheet = XLSX.utils.json_to_sheet(i18nKeys); XLSX.utils.book_append_sheet(i18nWorkbook, i18nSheet, 'i18n-keys'); const i18nReportFile = path.join(WORKDIR, 'docs', 'i18n-scan-report.xlsx'); XLSX.writeFile(i18nWorkbook, i18nReportFile); // 生成 JSON 报告 const reportFile = path.join(WORKDIR, 'docs', 'i18n-scan-report.json'); fs.writeFileSync(reportFile, JSON.stringify(report, null, 2)); console.log('✅ i18next 扫描转换完成!'); console.log(`📊 总扫描条目: ${data.length}`); console.log(`🔑 生成翻译键: ${Object.keys(translation).length}`); console.log(`📁 翻译文件: ${translationFile}`); console.log(`📋 i18n Excel 报告: ${i18nReportFile}`); console.log(`📄 JSON 报告: ${reportFile}`); console.log('\n📝 示例翻译键:'); report.sampleKeys.forEach(key => { console.log(` ${key}: "${translation[key]}"`); }); } main();