const { getDb } = require('../db/init'); const db = getDb('onion'); const CATEGORY_KEY = 'basic_info_role'; const FATHER_SYNONYMS = ['父', '爸', '父 亲', '孩子爸', '爸专', '爸备']; const GRANDPA_SYNONYMS = ['姥爷', '外爷']; const GRANDMA_SYNONYMS = ['姥姥', '姥姥/外婆']; const GRANDSON_SYNONYMS = []; function updateStats(dbConn) { const totalUsers = dbConn.prepare('SELECT COUNT(*) AS n FROM users').get().n || 1; const tags = dbConn.prepare('SELECT id FROM tags').all(); const stmt = dbConn.prepare(` UPDATE tags SET coverage = (SELECT COUNT(DISTINCT user_id) FROM user_tags WHERE tag_id = tags.id), coverage_rate = ROUND((SELECT COUNT(DISTINCT user_id) FROM user_tags WHERE tag_id = tags.id) * 100.0 / ?, 2) WHERE id = ? `); for (const tag of tags) stmt.run(totalUsers, tag.id); } function main() { try { const category = db.prepare('SELECT id FROM tag_categories WHERE key = ?').get(CATEGORY_KEY); if (!category) throw new Error(`找不到分类: ${CATEGORY_KEY}`); const catId = category.id; const getTag = db.prepare('SELECT id, name FROM tags WHERE category_id = ? AND name = ?'); const renameTag = db.prepare('UPDATE tags SET name = ? WHERE id = ?'); const mergeRel = db.prepare(` INSERT OR IGNORE INTO user_tags (user_id, tag_id) SELECT user_id, ? FROM user_tags WHERE tag_id = ? `); const deleteRel = db.prepare('DELETE FROM user_tags WHERE tag_id = ?'); const deleteTag = db.prepare('DELETE FROM tags WHERE id = ?'); const tx = db.transaction(() => { // 1) 保证标准名存在:爸爸、外婆 let dad = getTag.get(catId, '爸爸'); const father = getTag.get(catId, '父亲'); if (!dad && father) { renameTag.run('爸爸', father.id); dad = { id: father.id, name: '爸爸' }; console.log('✅ 重命名: 父亲 -> 爸爸'); } let grandma = getTag.get(catId, '外婆'); const extGrandma = getTag.get(catId, '姥姥/外婆'); if (!grandma && extGrandma) { renameTag.run('外婆', extGrandma.id); grandma = { id: extGrandma.id, name: '外婆' }; console.log('✅ 重命名: 姥姥/外婆 -> 外婆'); } // 2) 合并爸爸系 dad = getTag.get(catId, '爸爸'); if (dad) { for (const synonym of FATHER_SYNONYMS) { const tag = getTag.get(catId, synonym); if (!tag || tag.id === dad.id) continue; mergeRel.run(dad.id, tag.id); deleteRel.run(tag.id); deleteTag.run(tag.id); console.log(`✅ 合并: ${synonym} -> 爸爸`); } } // 3) 合并祖辈 const grandpa = getTag.get(catId, '爷爷'); if (grandpa) { for (const synonym of GRANDPA_SYNONYMS) { const tag = getTag.get(catId, synonym); if (!tag || tag.id === grandpa.id) continue; mergeRel.run(grandpa.id, tag.id); deleteRel.run(tag.id); deleteTag.run(tag.id); console.log(`✅ 合并: ${synonym} -> 爷爷`); } } const grandma2 = getTag.get(catId, '奶奶'); if (grandma2) { const tag = getTag.get(catId, '婆婆'); if (tag && tag.id !== grandma2.id) { mergeRel.run(grandma2.id, tag.id); deleteRel.run(tag.id); deleteTag.run(tag.id); console.log('✅ 合并: 婆婆 -> 奶奶'); } } grandma = getTag.get(catId, '外婆'); if (grandma) { for (const synonym of GRANDMA_SYNONYMS) { const tag = getTag.get(catId, synonym); if (!tag || tag.id === grandma.id) continue; mergeRel.run(grandma.id, tag.id); deleteRel.run(tag.id); deleteTag.run(tag.id); console.log(`✅ 合并: ${synonym} -> 外婆`); } } // 4) 外公系 const grandpa2 = getTag.get(catId, '外公'); if (grandpa2) { const tag = getTag.get(catId, '姥爷'); if (tag && tag.id !== grandpa2.id) { mergeRel.run(grandpa2.id, tag.id); deleteRel.run(tag.id); deleteTag.run(tag.id); console.log('✅ 合并: 姥爷 -> 外公'); } } }); tx(); updateStats(db); const stats = db.prepare(` SELECT (SELECT COUNT(*) FROM tags t JOIN tag_categories c ON c.id=t.category_id WHERE c.key = ?) AS tag_count, (SELECT COUNT(*) FROM user_tags) AS rel_count `).get(CATEGORY_KEY); console.log('\n✨ 标准名修复完成'); console.log(` • 家庭角色标签剩余: ${stats.tag_count}`); console.log(` • 用户-标签关系总数: ${stats.rel_count}`); db.close(); } catch (error) { console.error('❌ 标准名修复失败:', error); try { db.close(); } catch (_) {} process.exit(1); } } main();