361 lines
8.4 KiB
JavaScript
361 lines
8.4 KiB
JavaScript
/**
|
||
* 预警控制器
|
||
* @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.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
|
||
});
|
||
}
|
||
}; |