/** * 搜索请求日志中间件 * @description 记录所有搜索相关的请求和响应 */ const { FormLog } = require('../models'); /** * 搜索请求日志中间件 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 * @param {Function} next - 下一个中间件 */ const searchLogger = async (req, res, next) => { const startTime = Date.now(); const requestId = Math.random().toString(36).substr(2, 9); // 为请求添加唯一ID req.searchRequestId = requestId; console.log(`🌐 [搜索中间件] 请求开始:`, { requestId: requestId, method: req.method, url: req.originalUrl, query: req.query, body: req.body, headers: { 'user-agent': req.get('User-Agent'), 'content-type': req.get('Content-Type'), 'accept': req.get('Accept'), 'referer': req.get('Referer') }, ip: req.ip || req.connection.remoteAddress, timestamp: new Date().toISOString() }); // 记录请求日志到数据库 try { await FormLog.create({ action: 'search_request', module: 'farm_search', userId: req.user ? req.user.id : null, formData: JSON.stringify({ requestId: requestId, method: req.method, url: req.originalUrl, query: req.query, body: req.body, userAgent: req.get('User-Agent'), clientIP: req.ip || req.connection.remoteAddress, timestamp: new Date().toISOString() }), oldValues: null, newValues: JSON.stringify(req.query), success: true, errorMessage: null }); } catch (logError) { console.error('❌ [搜索中间件] 记录请求日志失败:', logError); } // 监听响应 const originalSend = res.send; res.send = function(data) { const endTime = Date.now(); const responseTime = endTime - startTime; console.log(`📤 [搜索中间件] 响应完成:`, { requestId: requestId, statusCode: res.statusCode, responseTime: responseTime + 'ms', dataSize: data ? data.length : 0, timestamp: new Date().toISOString() }); // 记录响应日志到数据库 try { let responseData; try { responseData = JSON.parse(data); } catch (e) { responseData = { raw: data }; } FormLog.create({ action: 'search_response', module: 'farm_search', userId: req.user ? req.user.id : null, formData: JSON.stringify({ requestId: requestId, statusCode: res.statusCode, responseTime: responseTime, dataSize: data ? data.length : 0, success: res.statusCode < 400, timestamp: new Date().toISOString() }), oldValues: null, newValues: JSON.stringify(responseData), success: res.statusCode < 400, errorMessage: res.statusCode >= 400 ? `HTTP ${res.statusCode}` : null }); } catch (logError) { console.error('❌ [搜索中间件] 记录响应日志失败:', logError); } // 调用原始send方法 originalSend.call(this, data); }; next(); }; module.exports = searchLogger;