// 数据库服务 const mysql = require('mysql2/promise'); const config = require('../config/config'); class DatabaseService { constructor() { this.connection = null; } // 连接数据库 async connect() { try { this.connection = await mysql.createConnection({ host: config.db.host, port: config.db.port, user: config.db.user, password: config.db.password, database: config.db.database }); console.log('数据库连接成功'); return this.connection; } catch (error) { console.error('数据库连接失败:', error.message); throw error; } } // 断开数据库连接 async disconnect() { if (this.connection) { await this.connection.end(); console.log('数据库连接已断开'); } } // 查询需要同步的数据 async getAllSyncData() { try { // 根据配置决定是查询所有数据还是仅未同步数据 let usersQuery = `SELECT ${config.tables.users.fields.id}, ${config.tables.users.fields.userId}, ${config.tables.users.fields.phoneNumber}, ${config.tables.users.fields.type}, ${config.tables.users.fields.authorizedRegion}, ${config.tables.users.fields.nickName}, jiandaoyun_record_id FROM ${config.tables.users.name}`; // 如果是增量同步,查询未同步的数据以及有收藏产品的用户 if (config.sync.incremental) { usersQuery += ` WHERE ${config.sync.statusField} = ${config.sync.unsyncedValue} OR EXISTS (SELECT 1 FROM ${config.tables.favorites.name} WHERE ${config.tables.favorites.fields.userPhone} = ${config.tables.users.fields.phoneNumber})`; console.log('启用增量同步模式,查询未同步数据及有收藏产品的用户'); } else { console.log('启用全量同步模式,查询所有数据'); } // 添加DISTINCT确保只返回唯一的用户数据 usersQuery = usersQuery.replace('SELECT', 'SELECT DISTINCT'); console.log('执行用户查询:', usersQuery); const [users] = await this.connection.execute(usersQuery); console.log(`查询结果: 共找到 ${users.length} 条需要同步的用户数据`); const syncData = []; // 为每个用户查询关联数据 for (const user of users) { const userId = user[config.tables.users.fields.userId]; const phoneNumber = user[config.tables.users.fields.phoneNumber]; const jiandaoyunRecordId = user.jiandaoyun_record_id; // 查询负责人信息(usermanagements表) const [userManagements] = await this.connection.execute( `SELECT ${config.tables.userManagements.fields.userName} FROM ${config.tables.userManagements.name} WHERE ${config.tables.userManagements.fields.userId} = ?`, [userId] ); // 查询用户收藏的产品(favorites表) const [favorites] = await this.connection.execute( `SELECT ${config.tables.favorites.fields.productId} FROM ${config.tables.favorites.name} WHERE ${config.tables.favorites.fields.userPhone} = ?`, [phoneNumber] ); // 查询产品详情(products表) let products = []; if (favorites.length > 0) { const productIds = favorites.map(fav => fav[config.tables.favorites.fields.productId]); // 构建动态占位符字符串,用于处理IN查询的数组参数 const placeholders = productIds.map(() => '?').join(','); const [productsResult] = await this.connection.execute( `SELECT ${config.tables.products.fields.productName}, ${config.tables.products.fields.specification}, ${config.tables.products.fields.quantity}, ${config.tables.products.fields.grossWeight}, ${config.tables.products.fields.yolk} FROM ${config.tables.products.name} WHERE ${config.tables.products.fields.productId} IN (${placeholders})`, productIds ); products = productsResult; // 如果用户有收藏商品,无论当前同步状态如何,都将其重置为未同步状态 // 这样可以确保有新收藏商品的用户数据会被重新同步到简道云 await this.connection.execute( `UPDATE ${config.tables.users.name} SET ${config.sync.statusField} = ? WHERE ${config.tables.users.fields.userId} = ?`, [config.sync.unsyncedValue, userId] ); console.log(`用户 ${userId} 有收藏商品,同步状态已重置为未同步`); } syncData.push({ user, userManagement: userManagements[0] || {}, products, userId: userId // 保存用户ID,用于同步后更新状态 }); } return syncData; } catch (error) { console.error('查询数据失败:', error.message); throw error; } } // 获取一条测试数据用于API测试 async getTestData() { try { // 获取一条用户数据 const [users] = await this.connection.execute( `SELECT ${config.tables.users.fields.id}, ${config.tables.users.fields.userId}, ${config.tables.users.fields.company}, ${config.tables.users.fields.name}, ${config.tables.users.fields.phoneNumber}, ${config.tables.users.fields.type}, ${config.tables.users.fields.city} FROM ${config.tables.users.name} LIMIT 1` ); if (users.length === 0) { console.error('没有找到用户数据'); return null; } const user = users[0]; const userId = user[config.tables.users.fields.id]; // 获取该用户的购物车数据 const [cartItems] = await this.connection.execute( `SELECT ${config.tables.cartItems.fields.productName}, ${config.tables.cartItems.fields.specification}, ${config.tables.cartItems.fields.quantity}, ${config.tables.cartItems.fields.yolk} FROM ${config.tables.cartItems.name} WHERE ${config.tables.cartItems.fields.userId} = ?`, [userId] ); // 获取该用户的产品数据 const [products] = await this.connection.execute( `SELECT ${config.tables.products.fields.productName}, ${config.tables.products.fields.specification}, ${config.tables.products.fields.quantity}, ${config.tables.products.fields.yolk} FROM ${config.tables.products.name} WHERE ${config.tables.products.fields.sellerId} = ?`, [userId] ); return { user, cartItems, products }; } catch (error) { console.error('获取测试数据失败:', error.message); throw error; } } // 更新数据同步状态 async updateSyncStatus(userId, synced) { try { const statusValue = synced ? config.sync.syncedValue : config.sync.unsyncedValue; const now = new Date(); await this.connection.execute( `UPDATE ${config.tables.users.name} SET ${config.sync.statusField} = ?, ${config.sync.timeField} = ? WHERE ${config.tables.users.fields.userId} = ?`, [statusValue, now, userId] ); console.log(`用户 ${userId} 的同步状态已更新为: ${synced ? '已同步' : '未同步'}`); } catch (error) { console.error(`更新用户 ${userId} 同步状态失败:`, error.message); throw error; } } // 测试数据库连接和表结构 async testDatabaseConnection() { try { // 测试连接 await this.connect(); // 查询表结构 const tables = [config.tables.users.name, config.tables.cartItems.name, config.tables.products.name]; for (const table of tables) { console.log(`\n--- 表 ${table} 结构 ---`); const [columns] = await this.connection.execute(`DESCRIBE ${table}`); columns.forEach(column => { console.log(`${column.Field}: ${column.Type} ${column.Null === 'YES' ? '(允许为空)' : '(不允许为空)'} ${column.Key === 'PRI' ? '(主键)' : ''}`); }); } // 查询示例数据 console.log(`\n--- 示例数据 ---`); const [usersSample] = await this.connection.execute(`SELECT * FROM ${config.tables.users.name} LIMIT 1`); if (usersSample.length > 0) { console.log('用户表示例数据:', usersSample[0]); const userId = usersSample[0][config.tables.users.fields.id]; const [cartItemsSample] = await this.connection.execute( `SELECT * FROM ${config.tables.cartItems.name} WHERE ${config.tables.cartItems.fields.userId} = ? LIMIT 1`, [userId] ); if (cartItemsSample.length > 0) { console.log('购物车表示例数据:', cartItemsSample[0]); } const [productsSample] = await this.connection.execute( `SELECT * FROM ${config.tables.products.name} WHERE ${config.tables.products.fields.sellerId} = ? LIMIT 1`, [userId] ); if (productsSample.length > 0) { console.log('产品表示例数据:', productsSample[0]); } } await this.disconnect(); return true; } catch (error) { console.error('数据库测试失败:', error.message); if (this.connection) { await this.disconnect(); } return false; } } } module.exports = new DatabaseService();