const fs = require('fs'); const path = require('path'); const Database = require('better-sqlite3'); console.log('=== 全面分析所有配置源和数据库中的模板差异 ===\n'); // 1. 收集所有配置文件 const configFiles = [ { name: 'C盘根目录', path: 'C:\\system-templates.json' }, { name: '项目打包配置', path: 'packaging/resources/common/config/system-templates.json' }, { name: '项目开发配置', path: 'electron/config/system-templates.json' }, { name: '历史配置v2', path: 'electron/config/default-subtitle-templates-v2.json' }, { name: 'TypeScript源文件', path: 'src/config/systemSubtitleTemplates.ts' }, ]; // 2. 查找数据库 const possibleDbPaths = [ path.join(process.env.APPDATA || '', 'aigc-tools-panel', 'database.db'), path.join(process.env.APPDATA || '', 'zhenqianba', 'data.db'), path.join(process.env.LOCALAPPDATA || '', 'aigc-tools-panel', 'database.db'), path.join(process.env.LOCALAPPDATA || '', 'zhenqianba', 'data.db'), path.join(__dirname, '../userData/data.db'), path.join(__dirname, '../data.db'), ]; let dbPath = null; for (const dbp of possibleDbPaths) { if (fs.existsSync(dbp)) { dbPath = dbp; break; } } // 3. 读取所有配置源 const configs = {}; // 读取JSON配置文件 configFiles.forEach(cf => { if (fs.existsSync(cf.path)) { try { if (cf.path.endsWith('.ts')) { // TypeScript文件需要特殊处理 const content = fs.readFileSync(cf.path, 'utf-8'); const match = content.match(/export const SYSTEM_TEMPLATES = (\[[\s\S]*?\]);/); if (match) { // 简单提取,实际应该用AST解析 configs[cf.name] = { type: 'ts', path: cf.path, content }; } } else { const data = JSON.parse(fs.readFileSync(cf.path, 'utf-8')); configs[cf.name] = { type: 'json', path: cf.path, data }; } } catch (e) { console.log(`⚠️ 读取 ${cf.name} 失败: ${e.message}`); } } else { console.log(`⚠️ ${cf.name} 不存在: ${cf.path}`); } }); // 读取数据库 if (dbPath) { try { const db = new Database(dbPath, { readonly: true }); const templates = db.prepare(` SELECT id, name, description, config, is_system, created_at FROM subtitle_templates WHERE is_system = 1 ORDER BY created_at ASC `).all(); configs['数据库'] = { type: 'db', path: dbPath, templates: templates.map(t => ({ ...t, config: JSON.parse(t.config) })) }; db.close(); } catch (e) { console.log(`⚠️ 读取数据库失败: ${e.message}`); } } else { console.log('⚠️ 未找到数据库文件'); } // 4. 分析每个配置源的模板 console.log('\n=== 各配置源的模板标题字幕配置 ===\n'); const analysis = {}; Object.keys(configs).forEach(sourceName => { const config = configs[sourceName]; const templates = []; if (config.type === 'json') { const data = config.data; if (data.subtitleTemplates) { data.subtitleTemplates.forEach(t => { const title = t.config && t.config.titleSubtitleConfig; templates.push({ 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('|') : '', fontNames: title ? title.lines.map(l => l.fontName).join(',') : '', }); }); } } else if (config.type === 'db') { config.templates.forEach(t => { const title = t.config && t.config.titleSubtitleConfig; templates.push({ 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('|') : '', fontNames: title ? title.lines.map(l => l.fontName).join(',') : '', }); }); } analysis[sourceName] = templates; console.log(`【${sourceName}】`); templates.forEach(t => { if (t.hasTitle) { console.log(` 模板 ${t.name}: ${t.maxCharsPerLine}字符/行, ${t.lines}行`); } else { console.log(` 模板 ${t.name}: 无标题配置`); } }); console.log(''); }); // 5. 找出相同配置的模板组 console.log('\n=== 各配置源中相同配置的模板组 ===\n'); Object.keys(analysis).forEach(sourceName => { const templates = analysis[sourceName]; const groups = {}; templates.forEach(t => { if (t.hasTitle) { 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(`【${sourceName}】`); sameGroups.forEach(key => { console.log(` 模板 ${groups[key].join(', ')} 配置相同`); }); console.log(''); } }); // 6. 对比不同配置源 console.log('\n=== 配置源之间的差异 ===\n'); const sources = Object.keys(analysis); if (sources.length > 1) { const baseSource = sources[0]; const baseTemplates = analysis[baseSource]; sources.slice(1).forEach(sourceName => { const compareTemplates = analysis[sourceName]; console.log(`【${baseSource} vs ${sourceName}】`); baseTemplates.forEach(baseT => { const compareT = compareTemplates.find(t => t.id === baseT.id || t.name === baseT.name); if (!compareT) { console.log(` 模板 ${baseT.name}: 在 ${sourceName} 中不存在`); } else if (baseT.hasTitle !== compareT.hasTitle) { console.log(` 模板 ${baseT.name}: 标题配置存在性不同 (${baseSource}: ${baseT.hasTitle}, ${sourceName}: ${compareT.hasTitle})`); } else if (baseT.hasTitle && compareT.hasTitle) { const baseKey = `${baseT.maxCharsPerLine}-${baseT.lines}-${baseT.linesText}`; const compareKey = `${compareT.maxCharsPerLine}-${compareT.lines}-${compareT.linesText}`; if (baseKey !== compareKey) { console.log(` 模板 ${baseT.name}: 配置不同`); console.log(` ${baseSource}: ${baseT.maxCharsPerLine}字符/行, ${baseT.lines}行`); console.log(` ${sourceName}: ${compareT.maxCharsPerLine}字符/行, ${compareT.lines}行`); } } }); console.log(''); }); } // 7. 总结 console.log('\n=== 总结 ===\n'); console.log('检查的配置源:'); Object.keys(configs).forEach(name => { console.log(` - ${name}: ${configs[name].type === 'db' ? '数据库' : '文件'}`); }); console.log('\n建议:'); console.log('1. 检查哪个配置源是"正确的"(应该包含8个不同的模板)'); console.log('2. 将正确的配置同步到所有配置源'); console.log('3. 确保数据库中的配置与配置文件一致');