const fs = require('fs'); const path = require('path'); /** * SQL 语法修复脚本:修复自动替换产生的 SQL 语法错误 */ class SQLSyntaxFixer { constructor() { this.filesToFix = [ 'services/matchingService.js', 'routes/matchingAdmin.js', 'routes/transfers.js', 'routes/matching.js' ]; } /** * 修复单个文件中的 SQL 语法错误 * @param {string} filePath - 文件路径 */ async fixFile(filePath) { const fullPath = path.join(process.cwd(), filePath); if (!fs.existsSync(fullPath)) { console.log(`文件不存在: ${filePath}`); return; } console.log(`正在修复文件: ${filePath}`); let content = fs.readFileSync(fullPath, 'utf8'); let originalContent = content; // 1. 修复 WHERE source_type = 'allocation' FROM transfers 的错误顺序 content = content.replace( /WHERE source_type = 'allocation' FROM transfers/g, "FROM transfers WHERE source_type = 'allocation'" ); // 2. 修复多个 WHERE 子句的问题 content = content.replace( /FROM transfers WHERE source_type = 'allocation'([\s\S]*?)WHERE/g, "FROM transfers WHERE source_type = 'allocation'$1AND" ); // 3. 修复 INSERT 语句中的引号问题 content = content.replace( /'allocation'/g, "'allocation'" ); // 4. 修复 JOIN 语句中的表别名问题 content = content.replace( /FROM transfers oa WHERE oa\.source_type = 'allocation'/g, "FROM transfers oa WHERE oa.source_type = 'allocation'" ); // 5. 修复复杂查询中的语法问题 content = this.fixComplexQueries(content, filePath); if (content !== originalContent) { fs.writeFileSync(fullPath, content); console.log(`✓ 已修复: ${filePath}`); } else { console.log(`- 无需修复: ${filePath}`); } } /** * 修复复杂查询 * @param {string} content - 文件内容 * @param {string} filePath - 文件路径 * @returns {string} 修复后的内容 */ fixComplexQueries(content, filePath) { if (filePath.includes('matchingService.js')) { // 修复 matchingService.js 中的特定查询 // 修复获取匹配目标的查询 content = content.replace( /FROM transfers oa\s+WHERE oa\.source_type = 'allocation'\s+JOIN users u ON oa\.from_user_id = u\.id/g, "FROM transfers oa JOIN users u ON oa.from_user_id = u.id WHERE oa.source_type = 'allocation'" ); // 修复获取用户待处理分配的查询 content = content.replace( /SELECT \* FROM transfers WHERE source_type = 'allocation' WHERE matching_order_id = \? ORDER BY cycle_number, created_at/g, "SELECT * FROM transfers WHERE source_type = 'allocation' AND matching_order_id = ? ORDER BY cycle_number, created_at" ); // 修复检查周期完成的查询 content = content.replace( /SELECT COUNT\(\*\) as count FROM transfers WHERE source_type = 'allocation' WHERE matching_order_id = \? AND cycle_number = \? AND status = "pending"/g, "SELECT COUNT(*) as count FROM transfers WHERE source_type = 'allocation' AND matching_order_id = ? AND cycle_number = ? AND status = 'pending'" ); } if (filePath.includes('matchingAdmin.js')) { // 修复 matchingAdmin.js 中的查询 content = content.replace( /FROM transfers oa WHERE oa\.source_type = 'allocation'\s+JOIN/g, "FROM transfers oa JOIN" ); // 在 JOIN 后添加 WHERE 条件 content = content.replace( /(FROM transfers oa JOIN[\s\S]*?)WHERE(?!.*source_type)/g, "$1WHERE oa.source_type = 'allocation' AND" ); } if (filePath.includes('matching.js')) { // 修复 matching.js 中的查询 content = content.replace( /LEFT JOIN transfers oa ON mo\.id = oa\.matching_order_id WHERE oa\.source_type = 'allocation'/g, "LEFT JOIN transfers oa ON mo.id = oa.matching_order_id AND oa.source_type = 'allocation'" ); } return content; } /** * 执行所有文件的修复 */ async fixAllFiles() { console.log('开始修复 SQL 语法错误...'); console.log('=' .repeat(60)); for (const filePath of this.filesToFix) { try { await this.fixFile(filePath); } catch (error) { console.error(`修复文件 ${filePath} 失败:`, error.message); } } console.log('\n' + '=' .repeat(60)); console.log('✓ SQL 语法修复完成!'); } } async function main() { const fixer = new SQLSyntaxFixer(); await fixer.fixAllFiles(); } // 如果直接运行此脚本 if (require.main === module) { main().catch(console.error); } module.exports = SQLSyntaxFixer;