const mysql = require('mysql2/promise'); const fs = require('fs'); const path = require('path'); require('dotenv').config(); class DatabaseSetup { constructor() { this.config = { host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT), user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, multipleStatements: true }; } async checkConnection() { console.log('🔍 检查数据库连接...'); console.log(`📍 服务器: ${this.config.host}:${this.config.port}`); console.log(`👤 用户: ${this.config.user}`); console.log(`🗄️ 数据库: ${this.config.database}`); try { const connection = await mysql.createConnection(this.config); console.log('✅ 数据库连接成功!'); // 获取数据库版本信息 const [version] = await connection.execute('SELECT VERSION() as version'); console.log(`📋 MySQL版本: ${version[0].version}`); await connection.end(); return true; } catch (error) { console.error('❌ 数据库连接失败:', error.message); if (error.code === 'ER_ACCESS_DENIED_ERROR') { console.log('\n💡 可能的解决方案:'); console.log('1. 检查用户名和密码是否正确'); console.log('2. 确认用户有访问该数据库的权限'); console.log('3. 检查IP白名单是否包含当前服务器IP'); console.log(` 当前尝试连接的IP需要添加到腾讯云数据库白名单中`); } else if (error.code === 'ENOTFOUND') { console.log('\n💡 域名解析失败,请检查:'); console.log('1. 数据库服务器地址是否正确'); console.log('2. 网络连接是否正常'); } return false; } } async executeSQL(sqlFile) { console.log(`\n📄 执行SQL文件: ${sqlFile}`); try { const sqlPath = path.join(__dirname, sqlFile); const sql = fs.readFileSync(sqlPath, 'utf8'); const connection = await mysql.createConnection(this.config); // 分割SQL语句并逐个执行 const statements = sql.split(';').filter(stmt => stmt.trim().length > 0); let successCount = 0; for (const statement of statements) { const trimmedStmt = statement.trim(); if (trimmedStmt) { try { await connection.execute(trimmedStmt); successCount++; } catch (error) { if (!error.message.includes('already exists')) { console.warn(`⚠️ 执行语句时警告: ${error.message}`); } } } } console.log(`✅ 成功执行 ${successCount} 条SQL语句`); await connection.end(); return true; } catch (error) { console.error(`❌ 执行SQL文件失败: ${error.message}`); return false; } } async checkTables() { console.log('\n📋 检查数据库表结构...'); try { const connection = await mysql.createConnection(this.config); // 获取所有表 const [tables] = await connection.execute( 'SELECT TABLE_NAME, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = ?', [this.config.database] ); console.log(`📊 数据库 ${this.config.database} 中共有 ${tables.length} 张表:`); tables.forEach((table, index) => { console.log(` ${index + 1}. ${table.TABLE_NAME} - ${table.TABLE_COMMENT || '无注释'}`); }); // 检查重要表是否存在 const requiredTables = ['users', 'cattle', 'loan_applications', 'insurance_applications', 'contracts', 'products', 'orders']; const existingTables = tables.map(t => t.TABLE_NAME); const missingTables = requiredTables.filter(table => !existingTables.includes(table)); if (missingTables.length === 0) { console.log('✅ 所有核心表已创建'); } else { console.log(`⚠️ 缺少核心表: ${missingTables.join(', ')}`); } await connection.end(); return { tables: existingTables, missing: missingTables }; } catch (error) { console.error('❌ 检查表结构失败:', error.message); return null; } } async getMyIPAddress() { try { const https = require('https'); return new Promise((resolve, reject) => { https.get('https://api.ipify.org', (resp) => { let data = ''; resp.on('data', (chunk) => { data += chunk; }); resp.on('end', () => { resolve(data); }); }).on('error', (err) => { reject(err); }); }); } catch (error) { return '无法获取'; } } async setup() { console.log('🚀 开始数据库初始化流程...\n'); // 获取当前IP地址 const myIP = await this.getMyIPAddress(); console.log(`🌐 当前公网IP地址: ${myIP}`); console.log('📝 请确保此IP已添加到腾讯云数据库白名单中\n'); // 检查连接 const connected = await this.checkConnection(); if (!connected) { console.log('\n❌ 数据库连接失败,请先解决连接问题'); return false; } // 执行基础表创建 console.log('\n🔨 创建基础表结构...'); const basicResult = await this.executeSQL('init_tables.sql'); if (!basicResult) { console.log('❌ 基础表创建失败'); return false; } // 执行扩展表创建 console.log('\n🔧 创建扩展表结构...'); const extendedResult = await this.executeSQL('init_tables_extended.sql'); if (!extendedResult) { console.log('❌ 扩展表创建失败'); return false; } // 验证表结构 await this.checkTables(); console.log('\n🎉 数据库初始化完成!'); return true; } } // 如果直接运行此脚本 if (require.main === module) { const setup = new DatabaseSetup(); setup.setup().then((success) => { if (success) { console.log('\n✅ 数据库设置成功完成'); process.exit(0); } else { console.log('\n❌ 数据库设置失败'); process.exit(1); } }).catch((error) => { console.error('💥 发生错误:', error); process.exit(1); }); } module.exports = DatabaseSetup;