You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
9.7 KiB

// 数据库服务
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();