const { Sequelize } = require('sequelize'); const fs = require('fs'); const path = require('path'); // 读取环境变量 const envPath = path.join(__dirname, '.env'); if (fs.existsSync(envPath)) { const envContent = fs.readFileSync(envPath, 'utf8'); const envVars = envContent.split('\n').filter(line => line.trim() && !line.startsWith('#')); envVars.forEach(line => { const [key, value] = line.split('=').map(part => part.trim()); process.env[key] = value; }); } // 数据库连接配置 const sequelize = new Sequelize( process.env.DB_NAME || 'wechat_app', process.env.DB_USER || 'root', process.env.DB_PASSWORD || '', { host: process.env.DB_HOST || 'localhost', port: process.env.DB_PORT || 3306, dialect: 'mysql', logging: false, timezone: '+08:00' // 设置时区为UTC+8 } ); /** * 检查并修复所有用户的关联记录 * 这个函数会扫描所有用户,并为每个用户创建缺失的关联记录 */ async function checkAndFixAllUserAssociations() { try { console.log('========================================'); console.log('检查并修复所有用户的关联记录'); console.log('========================================'); // 连接数据库 await sequelize.authenticate(); console.log('✅ 数据库连接成功'); // 获取所有用户 const users = await sequelize.query( 'SELECT userId, nickName, phoneNumber FROM users', { type: sequelize.QueryTypes.SELECT } ); console.log(`📊 共找到 ${users.length} 个用户记录`); let totalContactsCreated = 0; let totalManagementsCreated = 0; let fullyFixedUsers = 0; let partiallyFixedUsers = 0; let alreadyFixedUsers = 0; // 为每个用户检查并创建关联记录 for (let i = 0; i < users.length; i++) { const user = users[i]; console.log(`\n🔄 处理用户 ${i + 1}/${users.length}: ${user.userId}`); let contactsCreated = 0; let managementsCreated = 0; // 检查并创建联系人记录 try { const existingContact = await sequelize.query( 'SELECT * FROM contacts WHERE userId = ?', { replacements: [user.userId], type: sequelize.QueryTypes.SELECT } ); if (existingContact.length === 0) { await sequelize.query( 'INSERT INTO contacts (userId, nickName, phoneNumber) VALUES (?, ?, ?)', { replacements: [user.userId, user.nickName || '默认联系人', user.phoneNumber || ''] } ); console.log('✅ 创建了联系人记录'); contactsCreated++; } else { console.log('✅ 联系人记录已存在'); } } catch (error) { console.error('❌ 创建联系人记录失败:', error.message); } // 检查并创建用户管理记录 try { const existingManagement = await sequelize.query( 'SELECT * FROM usermanagements WHERE userId = ?', { replacements: [user.userId], type: sequelize.QueryTypes.SELECT } ); if (existingManagement.length === 0) { await sequelize.query( 'INSERT INTO usermanagements (userId) VALUES (?)', { replacements: [user.userId] } ); console.log('✅ 创建了用户管理记录'); managementsCreated++; } else { console.log('✅ 用户管理记录已存在'); } } catch (error) { console.error('❌ 创建用户管理记录失败:', error.message); } // 更新统计信息 totalContactsCreated += contactsCreated; totalManagementsCreated += managementsCreated; if (contactsCreated === 0 && managementsCreated === 0) { alreadyFixedUsers++; } else if (contactsCreated > 0 || managementsCreated > 0) { if (contactsCreated > 0 && managementsCreated > 0) { fullyFixedUsers++; } else { partiallyFixedUsers++; } } } console.log('\n========================================'); console.log('修复完成!'); console.log(`📊 总计: ${users.length} 个用户`); console.log(`✅ 已经完整的用户: ${alreadyFixedUsers} 个`); console.log(`🔧 完全修复的用户: ${fullyFixedUsers} 个`); console.log(`⚠️ 部分修复的用户: ${partiallyFixedUsers} 个`); console.log(`📈 共创建了 ${totalContactsCreated} 条联系人记录`); console.log(`📈 共创建了 ${totalManagementsCreated} 条用户管理记录`); console.log('========================================'); } catch (error) { console.error('❌ 修复过程中发生错误:', error.message); console.error('错误详情:', error); } finally { // 关闭数据库连接 await sequelize.close(); } } /** * 监控新用户并自动创建关联记录 * 这个函数会定期检查新用户,并为其创建关联记录 */ async function monitorAndAutoFixNewUsers(intervalMinutes = 10) { console.log(`\n🔄 启动新用户监控,每 ${intervalMinutes} 分钟检查一次`); // 保存上次检查的最大用户ID let lastCheckedUserId = ''; async function checkNewUsers() { try { // 连接数据库 await sequelize.authenticate(); // 获取最新的用户ID const latestUser = await sequelize.query( 'SELECT userId FROM users ORDER BY userId DESC LIMIT 1', { type: sequelize.QueryTypes.SELECT } ); if (latestUser.length > 0 && latestUser[0].userId !== lastCheckedUserId) { console.log(`\n🕵️‍♂️ 检测到可能的新用户活动,运行完整检查`); // 重新运行修复函数检查所有用户 await checkAndFixAllUserAssociations(); // 更新最后检查的用户ID lastCheckedUserId = latestUser[0].userId; } } catch (error) { console.error('❌ 监控过程中发生错误:', error.message); } finally { // 关闭数据库连接 await sequelize.close(); } } // 立即运行一次 await checkNewUsers(); // 设置定期检查(在实际部署时启用) // setInterval(checkNewUsers, intervalMinutes * 60 * 1000); } /** * 创建一个服务器文件补丁,确保新用户在授权时自动创建关联记录 */ function createServerPatch() { console.log('\n========================================'); console.log('创建服务器代码补丁'); console.log('========================================'); const patchContent = `/** * 用户关联记录创建工具函数 * 用于在用户授权成功后自动创建contacts和usermanagements表关联记录 */ async function createUserAssociations(user) { try { // 确保用户对象有效 if (!user || !user.userId) { console.error('创建用户关联记录失败: 用户对象或userId无效'); return false; } console.log('为用户创建关联记录:', user.userId); // 1. 创建或更新联系人记录 const [contactResult] = await sequelize.query( 'INSERT INTO contacts (userId, nickName, phoneNumber) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE nickName = ?, phoneNumber = ?', { replacements: [user.userId, user.nickName || '默认联系人', user.phoneNumber || '', user.nickName || '默认联系人', user.phoneNumber || ''] } ); // 2. 创建或更新用户管理记录 const [managementResult] = await sequelize.query( 'INSERT INTO usermanagements (userId) VALUES (?) ON DUPLICATE KEY UPDATE userId = ?', { replacements: [user.userId, user.userId] } ); console.log('用户关联记录创建成功:', user.userId); return true; } catch (error) { console.error('创建用户关联记录失败:', error.message); return false; } } // 在server-mysql.js文件中的用户授权相关代码后添加: // 示例:在用户创建或更新成功后调用 // const user = { userId: '...', nickName: '...', phoneNumber: '...' }; // await createUserAssociations(user);`; const patchFilePath = path.join(__dirname, 'user-association-patch.js'); fs.writeFileSync(patchFilePath, patchContent); console.log('✅ 服务器补丁已创建:', patchFilePath); console.log('请将此补丁中的createUserAssociations函数添加到server-mysql.js文件中,'); console.log('并在用户授权成功后调用该函数,以确保自动创建关联记录。'); console.log('========================================'); } /** * 主函数 */ async function main() { try { // 1. 先检查并修复所有现有用户 await checkAndFixAllUserAssociations(); // 2. 创建服务器补丁,解决根本问题 createServerPatch(); // 3. 提供使用说明 console.log('\n========================================'); console.log('使用说明:'); console.log('========================================'); console.log('1. 手动修复现有用户:'); console.log(' 已完成,所有用户的关联记录已检查并修复'); console.log('\n2. 长期解决方案:'); console.log(' a. 请将user-association-patch.js中的createUserAssociations函数添加到server-mysql.js文件'); console.log(' b. 在用户授权成功后调用该函数'); console.log(' c. 重启服务器以应用更改'); console.log('\n3. 可选: 定期检查(适用于临时解决方案):'); console.log(' 运行: node user-association-auto-fix.js monitor'); console.log(' 这将每10分钟检查一次新用户并自动修复关联记录'); console.log('========================================'); } catch (error) { console.error('❌ 执行过程中发生错误:', error); } } // 根据命令行参数决定执行模式 const args = process.argv.slice(2); const mode = args[0] || 'fix'; if (mode === 'monitor') { // 监控模式 monitorAndAutoFixNewUsers(); } else { // 默认修复模式 main(); }