/** * 预警控制器 * @file alertController.js * @description 处理预警相关的请求 */ const { Alert, Farm, Device } = require('../models'); const { Sequelize } = require('sequelize'); /** * 获取所有预警 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getAllAlerts = async (req, res) => { try { const alerts = await Alert.findAll({ include: [ { model: Farm, as: 'farm', attributes: ['id', 'name', 'location'] }, { model: Device, as: 'device', attributes: ['id', 'name', 'type'] } ], order: [['created_at', 'DESC']] }); res.status(200).json({ success: true, data: alerts }); } catch (error) { console.error('获取预警列表失败:', error); res.status(500).json({ success: false, message: '获取预警列表失败', error: error.message }); } }; /** * 根据养殖场名称搜索预警 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.searchAlertsByFarmName = async (req, res) => { try { const { farmName } = req.query; if (!farmName) { return res.status(400).json({ success: false, message: '请提供养殖场名称参数' }); } console.log(`开始搜索养殖场名称包含 "${farmName}" 的预警...`); // 首先找到匹配的养殖场 const farms = await Farm.findAll({ where: { name: { [require('sequelize').Op.like]: `%${farmName}%` } }, attributes: ['id', 'name'] }); if (farms.length === 0) { return res.status(200).json({ success: true, data: [], message: '未找到匹配的养殖场' }); } const farmIds = farms.map(farm => farm.id); // 根据养殖场ID查找预警 const alerts = await Alert.findAll({ where: { farm_id: { [require('sequelize').Op.in]: farmIds } }, include: [ { model: Farm, as: 'farm', attributes: ['id', 'name', 'location'] }, { model: Device, as: 'device', attributes: ['id', 'name', 'type'] } ], order: [['created_at', 'DESC']] }); console.log(`找到 ${alerts.length} 个匹配的预警`); res.status(200).json({ success: true, data: alerts, message: `找到 ${alerts.length} 个养殖场名称包含 "${farmName}" 的预警` }); } catch (error) { console.error('根据养殖场名称搜索预警失败:', error); res.status(500).json({ success: false, message: '搜索预警失败', error: error.message }); } }; /** * 获取单个预警 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getAlertById = async (req, res) => { try { const { id } = req.params; const alert = await Alert.findByPk(id, { include: [ { model: Farm, as: 'farm', attributes: ['id', 'name'] }, { model: Device, as: 'device', attributes: ['id', 'name', 'type'] } ] }); if (!alert) { return res.status(404).json({ success: false, message: '预警不存在' }); } res.status(200).json({ success: true, data: alert }); } catch (error) { console.error(`获取预警(ID: ${req.params.id})失败:`, error); res.status(500).json({ success: false, message: '获取预警详情失败', error: error.message }); } }; /** * 创建预警 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.createAlert = async (req, res) => { try { const { type, level, message, status, farm_id, device_id } = req.body; // 验证必填字段 if (!type || !message || !farm_id) { return res.status(400).json({ success: false, message: '类型、消息内容和养殖场ID为必填项' }); } // 验证养殖场是否存在 const farm = await Farm.findByPk(farm_id); if (!farm) { return res.status(404).json({ success: false, message: '指定的养殖场不存在' }); } // 如果提供了设备ID,验证设备是否存在 if (device_id) { const device = await Device.findByPk(device_id); if (!device) { return res.status(404).json({ success: false, message: '指定的设备不存在' }); } } const alert = await Alert.create({ type, level, message, status, farm_id, device_id }); res.status(201).json({ success: true, message: '预警创建成功', data: alert }); } catch (error) { console.error('创建预警失败:', error); res.status(500).json({ success: false, message: '创建预警失败', error: error.message }); } }; /** * 更新预警 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.updateAlert = async (req, res) => { try { const { id } = req.params; const { type, level, message, status, farm_id, device_id, resolved_at, resolved_by, resolution_notes } = req.body; const alert = await Alert.findByPk(id); if (!alert) { return res.status(404).json({ success: false, message: '预警不存在' }); } // 如果更新了养殖场ID,验证养殖场是否存在 if (farm_id && farm_id !== alert.farm_id) { const farm = await Farm.findByPk(farm_id); if (!farm) { return res.status(404).json({ success: false, message: '指定的养殖场不存在' }); } } // 如果更新了设备ID,验证设备是否存在 if (device_id && device_id !== alert.device_id) { const device = await Device.findByPk(device_id); if (!device) { return res.status(404).json({ success: false, message: '指定的设备不存在' }); } } // 如果状态更新为已解决,自动设置解决时间 let updateData = { type, level, message, status, farm_id, device_id, resolved_at, resolved_by, resolution_notes }; // 只更新提供的字段 Object.keys(updateData).forEach(key => { if (updateData[key] === undefined) { delete updateData[key]; } }) if (status === 'resolved' && !resolved_at) { updateData.resolved_at = new Date(); } await alert.update(updateData); res.status(200).json({ success: true, message: '预警更新成功', data: alert }); } catch (error) { console.error(`更新预警(ID: ${req.params.id})失败:`, error); res.status(500).json({ success: false, message: '更新预警失败', error: error.message }); } }; /** * 删除预警 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.deleteAlert = async (req, res) => { try { const { id } = req.params; const alert = await Alert.findByPk(id); if (!alert) { return res.status(404).json({ success: false, message: '预警不存在' }); } await alert.destroy(); res.status(200).json({ success: true, message: '预警删除成功' }); } catch (error) { console.error(`删除预警(ID: ${req.params.id})失败:`, error); res.status(500).json({ success: false, message: '删除预警失败', error: error.message }); } }; /** * 按类型统计预警数量 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getAlertStatsByType = async (req, res) => { try { const { sequelize } = require('../config/database-simple'); const stats = await Alert.findAll({ attributes: [ 'type', [sequelize.fn('COUNT', sequelize.col('id')), 'count'] ], group: ['type'], raw: true }); // 格式化数据 const formattedStats = stats.map(item => ({ type: item.type, count: parseInt(item.count) || 0 })); res.status(200).json({ success: true, data: formattedStats }); } catch (error) { console.error('获取预警类型统计失败:', error); res.status(500).json({ success: false, message: '获取预警类型统计失败', error: error.message }); } }; /** * 按级别统计预警数量 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getAlertStatsByLevel = async (req, res) => { try { const { sequelize } = require('../config/database-simple'); const stats = await Alert.findAll({ attributes: [ 'level', [sequelize.fn('COUNT', sequelize.col('id')), 'count'] ], group: ['level'], raw: true }); // 格式化数据 const formattedStats = stats.map(item => ({ level: item.level, count: parseInt(item.count) || 0 })); res.status(200).json({ success: true, data: formattedStats }); } catch (error) { console.error('获取预警级别统计失败:', error); res.status(500).json({ success: false, message: '获取预警级别统计失败', error: error.message }); } }; /** * 按状态统计预警数量 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getAlertStatsByStatus = async (req, res) => { try { const { sequelize } = require('../config/database-simple'); const stats = await Alert.findAll({ attributes: [ 'status', [sequelize.fn('COUNT', sequelize.col('id')), 'count'] ], group: ['status'], raw: true }); // 格式化数据 const formattedStats = stats.map(item => ({ status: item.status, count: parseInt(item.count) || 0 })); res.status(200).json({ success: true, data: formattedStats }); } catch (error) { console.error('获取预警状态统计失败:', error); res.status(500).json({ success: false, message: '获取预警状态统计失败', error: error.message }); } };