Files
nxxmdata/backend/controllers/alertController.js

430 lines
10 KiB
JavaScript
Raw Normal View History

/**
* 预警控制器
* @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
});
}
};
2025-09-12 20:08:42 +08:00
/**
* 根据养殖场名称搜索预警
* @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
});
}
};