const fs = require('fs'); const path = require('path'); console.log('=== 8个模板配置差异全面分析报告 ===\n'); // 读取所有配置源 const sources = { 'C盘根目录': 'C:\\system-templates.json', '项目打包配置': 'packaging/resources/common/config/system-templates.json', '项目开发配置': 'electron/config/system-templates.json', '历史配置v2': 'electron/config/default-subtitle-templates-v2.json', 'TypeScript源': 'src/config/systemSubtitleTemplates.ts', }; const configs = {}; // 读取JSON文件 Object.keys(sources).forEach(name => { const filePath = sources[name]; if (fs.existsSync(filePath)) { try { if (filePath.endsWith('.ts')) { // TypeScript文件,提取配置 const content = fs.readFileSync(filePath, 'utf-8'); // 简单提取,实际应该用AST const templates = []; const regex = /"id": "template_system_(\d+)",[\s\S]*?"name": "(\d+)",[\s\S]*?titleSubtitleConfig: \{[\s\S]*?maxCharsPerLine: (\d+),[\s\S]*?lines: \[([\s\S]*?)\],/g; let match; while ((match = regex.exec(content)) !== null) { const id = match[1]; const name = match[2]; const maxChars = parseInt(match[3]); const linesContent = match[4]; const lines = []; const lineRegex = /text: "([^"]+)"/g; let lineMatch; while ((lineMatch = lineRegex.exec(linesContent)) !== null) { lines.push(lineMatch[1]); } templates.push({ id: `template_system_${id}`, name, maxCharsPerLine: maxChars, lines: lines.length, linesText: lines.join('|') }); } configs[name] = templates; } else { const data = JSON.parse(fs.readFileSync(filePath, 'utf-8')); const templates = (data.subtitleTemplates || []).map(t => { const title = t.config && t.config.titleSubtitleConfig; return { id: t.id, name: t.name, hasTitle: !!title, maxCharsPerLine: title ? title.maxCharsPerLine : null, lines: title ? title.lines.length : 0, linesText: title ? title.lines.map(l => l.text).join('|') : '', }; }); configs[name] = templates; } } catch (e) { console.log(`⚠️ 读取 ${name} 失败: ${e.message}`); } } }); // 分析每个配置源 console.log('【1】各配置源的模板标题字幕配置详情\n'); Object.keys(configs).forEach(sourceName => { const templates = configs[sourceName]; console.log(`\n${sourceName}:`); templates.forEach(t => { if (t.hasTitle !== false && t.maxCharsPerLine) { console.log(` 模板 ${t.name}: ${t.maxCharsPerLine}字符/行, ${t.lines}行`); } else { console.log(` 模板 ${t.name}: 无标题配置`); } }); }); // 找出相同配置的模板组 console.log('\n\n【2】各配置源中相同配置的模板组\n'); Object.keys(configs).forEach(sourceName => { const templates = configs[sourceName]; const groups = {}; templates.forEach(t => { if (t.maxCharsPerLine !== null && t.maxCharsPerLine !== undefined) { const key = `${t.maxCharsPerLine}-${t.lines}-${t.linesText}`; if (!groups[key]) groups[key] = []; groups[key].push(t.name); } }); const sameGroups = Object.keys(groups).filter(k => groups[k].length > 1); if (sameGroups.length > 0) { console.log(`\n${sourceName}:`); sameGroups.forEach(key => { console.log(` ❌ 模板 ${groups[key].join(', ')} 配置相同 (${key.split('-')[0]}字符/行, ${key.split('-')[1]}行)`); }); } else { console.log(`\n${sourceName}:`); console.log(` ✅ 所有模板配置都不同`); } }); // 对比不同配置源 console.log('\n\n【3】配置源之间的差异对比\n'); const sourceNames = Object.keys(configs); if (sourceNames.length > 1) { const baseSource = sourceNames[0]; const baseTemplates = configs[baseSource]; sourceNames.slice(1).forEach(sourceName => { const compareTemplates = configs[sourceName]; console.log(`\n${baseSource} vs ${sourceName}:`); let hasDiff = false; baseTemplates.forEach(baseT => { const compareT = compareTemplates.find(t => t.id === baseT.id || t.name === baseT.name); if (!compareT) { console.log(` ⚠️ 模板 ${baseT.name}: 在 ${sourceName} 中不存在`); hasDiff = true; } else { const baseKey = baseT.maxCharsPerLine !== null ? `${baseT.maxCharsPerLine}-${baseT.lines}-${baseT.linesText}` : 'no-title'; const compareKey = compareT.maxCharsPerLine !== null ? `${compareT.maxCharsPerLine}-${compareT.lines}-${compareT.linesText}` : 'no-title'; if (baseKey !== compareKey) { console.log(` ❌ 模板 ${baseT.name}: 配置不同`); if (baseT.maxCharsPerLine) { console.log(` ${baseSource}: ${baseT.maxCharsPerLine}字符/行, ${baseT.lines}行`); } else { console.log(` ${baseSource}: 无标题配置`); } if (compareT.maxCharsPerLine) { console.log(` ${sourceName}: ${compareT.maxCharsPerLine}字符/行, ${compareT.lines}行`); } else { console.log(` ${sourceName}: 无标题配置`); } hasDiff = true; } } }); if (!hasDiff) { console.log(` ✅ 配置相同`); } }); } // 总结 console.log('\n\n【4】总结\n'); console.log('检查的配置源:'); sourceNames.forEach(name => { const templates = configs[name]; const hasTitleCount = templates.filter(t => t.maxCharsPerLine !== null).length; console.log(` - ${name}: ${templates.length}个模板, ${hasTitleCount}个有标题配置`); }); console.log('\n发现的问题:'); console.log('1. ❌ 所有有标题配置的源中,模板都分为两组:'); console.log(' - 模板 11, 33, 55, 77 配置相同(8字符/行,2行)'); console.log(' - 模板 22, 44, 66, 88 配置相同(15字符/行,1行)'); console.log('2. ❌ 项目打包配置和项目开发配置中缺少 titleSubtitleConfig'); console.log('3. ⚠️ 需要确认:这8个模板原本是否应该有不同的配置?'); console.log('\n建议:'); console.log('1. 如果8个模板应该不同,需要为每个模板创建不同的标题字幕配置'); console.log('2. 将完整的配置同步到所有配置源(项目打包配置、项目开发配置)'); console.log('3. 确保数据库初始化时使用正确的配置');