689 lines
21 KiB
JavaScript
689 lines
21 KiB
JavaScript
/**
|
||
* 智能项圈预警控制器
|
||
* @file smartCollarAlertController.js
|
||
* @description 处理智能项圈预警相关的请求
|
||
*/
|
||
|
||
const { IotXqClient } = require('../models');
|
||
const { Op } = require('sequelize');
|
||
|
||
/**
|
||
* 获取智能项圈预警统计
|
||
* @param {Object} req - 请求对象
|
||
* @param {Object} res - 响应对象
|
||
*/
|
||
exports.getCollarAlertStats = async (req, res) => {
|
||
try {
|
||
console.log('=== 获取智能项圈预警统计 ===');
|
||
|
||
// 获取项圈设备总数
|
||
const totalDevices = await IotXqClient.count();
|
||
console.log('项圈设备总数:', totalDevices);
|
||
|
||
// 获取所有设备数据用于生成预警统计
|
||
const allDevices = await IotXqClient.findAll({
|
||
order: [['uptime', 'DESC'], ['id', 'DESC']]
|
||
});
|
||
|
||
// 统计各类预警数量
|
||
let stats = {
|
||
totalDevices: totalDevices,
|
||
lowBattery: 0,
|
||
offline: 0,
|
||
highTemperature: 0,
|
||
lowTemperature: 0,
|
||
abnormalMovement: 0,
|
||
wearOff: 0,
|
||
totalAlerts: 0
|
||
};
|
||
|
||
allDevices.forEach(device => {
|
||
const actualBattery = parseInt(device.battery) || 0;
|
||
const actualTemperature = parseFloat(device.temperature) || 0;
|
||
const totalSteps = parseInt(device.steps) || 0;
|
||
const yesterdaySteps = parseInt(device.y_steps) || 0;
|
||
const dailySteps = totalSteps - yesterdaySteps;
|
||
|
||
// 离线预警
|
||
if (device.is_connect === 0) {
|
||
stats.offline++;
|
||
stats.totalAlerts++;
|
||
}
|
||
|
||
// 低电量预警
|
||
if (actualBattery > 0 && actualBattery < 20) {
|
||
stats.lowBattery++;
|
||
stats.totalAlerts++;
|
||
}
|
||
|
||
// 温度预警
|
||
if (actualTemperature > 0) {
|
||
if (actualTemperature < 30) {
|
||
stats.lowTemperature++;
|
||
stats.totalAlerts++;
|
||
} else if (actualTemperature > 40) {
|
||
stats.highTemperature++;
|
||
stats.totalAlerts++;
|
||
}
|
||
}
|
||
|
||
// 异常运动预警
|
||
if (dailySteps === 0 && totalSteps > 0) {
|
||
stats.abnormalMovement++;
|
||
stats.totalAlerts++;
|
||
}
|
||
|
||
// 项圈脱落预警
|
||
if (device.bandge_status === 0) {
|
||
stats.wearOff++;
|
||
stats.totalAlerts++;
|
||
}
|
||
});
|
||
|
||
console.log('预警统计结果:', stats);
|
||
|
||
res.json({
|
||
success: true,
|
||
data: stats,
|
||
message: '获取智能项圈预警统计成功'
|
||
});
|
||
} catch (error) {
|
||
console.error('获取智能项圈预警统计失败:', error);
|
||
res.status(500).json({
|
||
success: false,
|
||
message: '获取智能项圈预警统计失败',
|
||
error: error.message
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 获取智能项圈预警列表
|
||
* @param {Object} req - 请求对象
|
||
* @param {Object} res - 响应对象
|
||
*/
|
||
exports.getCollarAlerts = async (req, res) => {
|
||
try {
|
||
const {
|
||
page = 1,
|
||
limit = 10,
|
||
status,
|
||
search,
|
||
alertType,
|
||
alertLevel,
|
||
startDate,
|
||
endDate
|
||
} = req.query;
|
||
|
||
const offset = (page - 1) * limit;
|
||
|
||
console.log('智能项圈预警API请求参数:', {
|
||
page, limit, status, search, alertType, alertLevel, startDate, endDate
|
||
});
|
||
|
||
// 构建查询条件
|
||
const whereConditions = {};
|
||
|
||
// 状态筛选
|
||
if (status) {
|
||
switch (status) {
|
||
case 'online':
|
||
whereConditions.state = 1;
|
||
break;
|
||
case 'offline':
|
||
whereConditions.state = 0;
|
||
break;
|
||
case 'alarm':
|
||
whereConditions.state = 2;
|
||
break;
|
||
case 'maintenance':
|
||
whereConditions.state = 3;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 搜索条件
|
||
if (search) {
|
||
whereConditions[Op.or] = [
|
||
{ sn: { [Op.like]: `%${search}%` } },
|
||
{ deviceId: { [Op.like]: `%${search}%` } }
|
||
];
|
||
}
|
||
|
||
// 时间范围筛选
|
||
if (startDate || endDate) {
|
||
whereConditions.uptime = {};
|
||
if (startDate) {
|
||
whereConditions.uptime[Op.gte] = new Date(startDate);
|
||
}
|
||
if (endDate) {
|
||
whereConditions.uptime[Op.lte] = new Date(endDate);
|
||
}
|
||
}
|
||
|
||
// 查询所有符合条件的设备数据
|
||
const allDevices = await IotXqClient.findAll({
|
||
where: whereConditions,
|
||
order: [['uptime', 'DESC'], ['id', 'DESC']]
|
||
});
|
||
|
||
// 生成预警数据
|
||
const allAlerts = [];
|
||
|
||
allDevices.forEach(device => {
|
||
const deviceId = device.sn || `COLLAR${device.id}`;
|
||
const alertTime = new Date(device.uptime || Date.now()).toISOString().replace('T', ' ').substring(0, 19);
|
||
|
||
const actualBattery = parseInt(device.battery) || 0;
|
||
const actualTemperature = parseFloat(device.temperature) || 0;
|
||
const totalSteps = parseInt(device.steps) || 0;
|
||
const yesterdaySteps = parseInt(device.y_steps) || 0;
|
||
const dailySteps = totalSteps - yesterdaySteps;
|
||
|
||
// 添加基础信息到预警的函数
|
||
const addBaseInfoToAlert = (alert) => {
|
||
alert.deviceId = device.id;
|
||
alert.deviceName = deviceId;
|
||
alert.collarNumber = deviceId;
|
||
alert.dailySteps = dailySteps;
|
||
alert.totalSteps = totalSteps;
|
||
alert.yesterdaySteps = yesterdaySteps;
|
||
alert.battery = actualBattery;
|
||
alert.temperature = actualTemperature;
|
||
alert.alertTime = alertTime;
|
||
alert.deviceStatus = device.is_connect === 1 ? '在线' : '离线';
|
||
alert.gpsSignal = device.is_connect === 1 ? '强' : '无';
|
||
alert.wearStatus = device.bandge_status === 1 ? '已佩戴' : '未佩戴';
|
||
alert.longitude = 116.3974 + (device.id % 100) * 0.0001;
|
||
alert.latitude = 39.9093 + (device.id % 100) * 0.0001;
|
||
return alert;
|
||
};
|
||
|
||
// 离线预警
|
||
if (device.is_connect === 0) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_offline`,
|
||
alertType: 'offline',
|
||
alertLevel: 'high',
|
||
description: '设备已离线超过30分钟',
|
||
movementStatus: '静止'
|
||
}));
|
||
}
|
||
|
||
// 低电量预警
|
||
if (actualBattery > 0 && actualBattery < 20) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_battery`,
|
||
alertType: 'battery',
|
||
alertLevel: actualBattery < 10 ? 'high' : 'medium',
|
||
description: `设备电量低于20%,当前电量${actualBattery}%`,
|
||
movementStatus: '正常'
|
||
}));
|
||
}
|
||
|
||
// 温度预警
|
||
if (actualTemperature > 0) {
|
||
if (actualTemperature < 30) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_temperature_low`,
|
||
alertType: 'temperature',
|
||
alertLevel: actualTemperature < 20 ? 'high' : 'medium',
|
||
description: `设备温度过低,当前温度${actualTemperature}°C`,
|
||
movementStatus: '正常'
|
||
}));
|
||
} else if (actualTemperature > 40) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_temperature_high`,
|
||
alertType: 'temperature',
|
||
alertLevel: actualTemperature > 45 ? 'high' : 'medium',
|
||
description: `设备温度过高,当前温度${actualTemperature}°C`,
|
||
movementStatus: '正常'
|
||
}));
|
||
}
|
||
}
|
||
|
||
// 异常运动预警
|
||
if (dailySteps === 0 && totalSteps > 0) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_movement_zero`,
|
||
alertType: 'movement',
|
||
alertLevel: 'high',
|
||
description: '检测到步数异常,当日运动量为0步,可能为设备故障或动物异常',
|
||
movementStatus: '异常'
|
||
}));
|
||
}
|
||
|
||
// 项圈脱落预警
|
||
if (device.bandge_status === 0) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_wear`,
|
||
alertType: 'wear',
|
||
alertLevel: 'high',
|
||
description: '设备佩戴状态异常,可能已脱落',
|
||
movementStatus: '正常'
|
||
}));
|
||
}
|
||
});
|
||
|
||
// 预警类型筛选
|
||
let filteredAlerts = allAlerts;
|
||
if (alertType && alertType.trim() !== '') {
|
||
filteredAlerts = allAlerts.filter(alert => alert.alertType === alertType);
|
||
}
|
||
|
||
// 预警级别筛选
|
||
if (alertLevel && alertLevel.trim() !== '') {
|
||
filteredAlerts = filteredAlerts.filter(alert => alert.alertLevel === alertLevel);
|
||
}
|
||
|
||
// 计算统计数据
|
||
const stats = {
|
||
lowBattery: filteredAlerts.filter(alert => alert.alertType === 'battery').length,
|
||
offline: filteredAlerts.filter(alert => alert.alertType === 'offline').length,
|
||
highTemperature: filteredAlerts.filter(alert => alert.alertType === 'temperature').length,
|
||
abnormalMovement: filteredAlerts.filter(alert => alert.alertType === 'movement').length,
|
||
wearOff: filteredAlerts.filter(alert => alert.alertType === 'wear').length
|
||
};
|
||
|
||
// 分页处理
|
||
const startIndex = parseInt(offset);
|
||
const endIndex = startIndex + parseInt(limit);
|
||
const paginatedAlerts = filteredAlerts.slice(startIndex, endIndex);
|
||
|
||
res.json({
|
||
success: true,
|
||
data: paginatedAlerts,
|
||
total: filteredAlerts.length,
|
||
stats: stats,
|
||
pagination: {
|
||
page: parseInt(page),
|
||
limit: parseInt(limit),
|
||
total: filteredAlerts.length,
|
||
pages: Math.ceil(filteredAlerts.length / limit)
|
||
},
|
||
message: '获取智能项圈预警列表成功'
|
||
});
|
||
} catch (error) {
|
||
console.error('获取智能项圈预警列表失败:', error);
|
||
res.status(500).json({
|
||
success: false,
|
||
message: '获取智能项圈预警列表失败',
|
||
error: error.message
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 获取单个智能项圈预警详情
|
||
* @param {Object} req - 请求对象
|
||
* @param {Object} res - 响应对象
|
||
*/
|
||
exports.getCollarAlertById = async (req, res) => {
|
||
try {
|
||
const { id } = req.params;
|
||
|
||
// 解析预警ID,格式为 deviceId_alertType
|
||
const [deviceId, alertType] = id.split('_');
|
||
|
||
if (!deviceId || !alertType) {
|
||
return res.status(400).json({
|
||
success: false,
|
||
message: '无效的预警ID格式'
|
||
});
|
||
}
|
||
|
||
// 查找设备
|
||
const device = await IotXqClient.findByPk(deviceId);
|
||
if (!device) {
|
||
return res.status(404).json({
|
||
success: false,
|
||
message: '设备不存在'
|
||
});
|
||
}
|
||
|
||
const deviceNumber = device.sn || `COLLAR${device.id}`;
|
||
const alertTime = new Date(device.uptime || Date.now()).toISOString().replace('T', ' ').substring(0, 19);
|
||
|
||
const actualBattery = parseInt(device.battery) || 0;
|
||
const actualTemperature = parseFloat(device.temperature) || 0;
|
||
const totalSteps = parseInt(device.steps) || 0;
|
||
const yesterdaySteps = parseInt(device.y_steps) || 0;
|
||
const dailySteps = totalSteps - yesterdaySteps;
|
||
|
||
// 根据预警类型生成详情
|
||
let alertDetail = {
|
||
id: id,
|
||
deviceId: device.id,
|
||
deviceName: deviceNumber,
|
||
collarNumber: deviceNumber,
|
||
alertType: alertType,
|
||
alertTime: alertTime,
|
||
battery: actualBattery,
|
||
temperature: actualTemperature,
|
||
dailySteps: dailySteps,
|
||
totalSteps: totalSteps,
|
||
yesterdaySteps: yesterdaySteps,
|
||
deviceStatus: device.state === 1 ? '在线' : '离线',
|
||
gpsSignal: device.state === 1 ? '强' : '无',
|
||
wearStatus: device.bandge_status === 1 ? '已佩戴' : '未佩戴',
|
||
longitude: 116.3974 + (device.id % 100) * 0.0001,
|
||
latitude: 39.9093 + (device.id % 100) * 0.0001,
|
||
movementStatus: '正常'
|
||
};
|
||
|
||
// 根据预警类型设置具体信息
|
||
switch (alertType) {
|
||
case 'offline':
|
||
alertDetail.alertLevel = 'high';
|
||
alertDetail.description = '设备已离线超过30分钟';
|
||
alertDetail.movementStatus = '静止';
|
||
break;
|
||
case 'battery':
|
||
alertDetail.alertLevel = actualBattery < 10 ? 'high' : 'medium';
|
||
alertDetail.description = `设备电量低于20%,当前电量${actualBattery}%`;
|
||
break;
|
||
case 'temperature':
|
||
if (actualTemperature < 30) {
|
||
alertDetail.alertLevel = actualTemperature < 20 ? 'high' : 'medium';
|
||
alertDetail.description = `设备温度过低,当前温度${actualTemperature}°C`;
|
||
} else if (actualTemperature > 40) {
|
||
alertDetail.alertLevel = actualTemperature > 45 ? 'high' : 'medium';
|
||
alertDetail.description = `设备温度过高,当前温度${actualTemperature}°C`;
|
||
}
|
||
break;
|
||
case 'movement':
|
||
alertDetail.alertLevel = 'high';
|
||
alertDetail.description = '检测到步数异常,当日运动量为0步,可能为设备故障或动物异常';
|
||
alertDetail.movementStatus = '异常';
|
||
break;
|
||
case 'wear':
|
||
alertDetail.alertLevel = 'high';
|
||
alertDetail.description = '设备佩戴状态异常,可能已脱落';
|
||
break;
|
||
}
|
||
|
||
res.json({
|
||
success: true,
|
||
data: alertDetail,
|
||
message: '获取智能项圈预警详情成功'
|
||
});
|
||
} catch (error) {
|
||
console.error('获取智能项圈预警详情失败:', error);
|
||
res.status(500).json({
|
||
success: false,
|
||
message: '获取智能项圈预警详情失败',
|
||
error: error.message
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 处理智能项圈预警
|
||
* @param {Object} req - 请求对象
|
||
* @param {Object} res - 响应对象
|
||
*/
|
||
exports.handleCollarAlert = async (req, res) => {
|
||
try {
|
||
const { id } = req.params;
|
||
const { action, notes, handler } = req.body;
|
||
|
||
// 解析预警ID
|
||
const [deviceId, alertType] = id.split('_');
|
||
|
||
if (!deviceId || !alertType) {
|
||
return res.status(400).json({
|
||
success: false,
|
||
message: '无效的预警ID格式'
|
||
});
|
||
}
|
||
|
||
// 这里可以实现预警处理逻辑,比如记录处理历史、发送通知等
|
||
// 目前只是返回成功响应
|
||
const result = {
|
||
alertId: id,
|
||
action: action || 'acknowledged',
|
||
notes: notes || '',
|
||
handler: handler || 'system',
|
||
processedAt: new Date().toISOString(),
|
||
status: 'processed'
|
||
};
|
||
|
||
console.log('处理智能项圈预警:', result);
|
||
|
||
res.json({
|
||
success: true,
|
||
data: result,
|
||
message: '预警处理成功'
|
||
});
|
||
} catch (error) {
|
||
console.error('处理智能项圈预警失败:', error);
|
||
res.status(500).json({
|
||
success: false,
|
||
message: '处理智能项圈预警失败',
|
||
error: error.message
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 批量处理智能项圈预警
|
||
* @param {Object} req - 请求对象
|
||
* @param {Object} res - 响应对象
|
||
*/
|
||
exports.batchHandleCollarAlerts = async (req, res) => {
|
||
try {
|
||
const { alertIds, action, notes, handler } = req.body;
|
||
|
||
if (!alertIds || !Array.isArray(alertIds) || alertIds.length === 0) {
|
||
return res.status(400).json({
|
||
success: false,
|
||
message: '请提供有效的预警ID列表'
|
||
});
|
||
}
|
||
|
||
const results = [];
|
||
|
||
for (const alertId of alertIds) {
|
||
const [deviceId, alertType] = alertId.split('_');
|
||
|
||
if (deviceId && alertType) {
|
||
results.push({
|
||
alertId: alertId,
|
||
action: action || 'acknowledged',
|
||
notes: notes || '',
|
||
handler: handler || 'system',
|
||
processedAt: new Date().toISOString(),
|
||
status: 'processed'
|
||
});
|
||
}
|
||
}
|
||
|
||
console.log('批量处理智能项圈预警:', results);
|
||
|
||
res.json({
|
||
success: true,
|
||
data: {
|
||
processedCount: results.length,
|
||
results: results
|
||
},
|
||
message: `成功处理 ${results.length} 个预警`
|
||
});
|
||
} catch (error) {
|
||
console.error('批量处理智能项圈预警失败:', error);
|
||
res.status(500).json({
|
||
success: false,
|
||
message: '批量处理智能项圈预警失败',
|
||
error: error.message
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 导出智能项圈预警数据
|
||
* @param {Object} req - 请求对象
|
||
* @param {Object} res - 响应对象
|
||
*/
|
||
exports.exportCollarAlerts = async (req, res) => {
|
||
try {
|
||
const {
|
||
search,
|
||
alertType,
|
||
alertLevel,
|
||
startDate,
|
||
endDate,
|
||
format = 'json'
|
||
} = req.query;
|
||
|
||
// 构建查询条件(与获取列表相同的逻辑)
|
||
const whereConditions = {};
|
||
|
||
if (search) {
|
||
whereConditions[Op.or] = [
|
||
{ sn: { [Op.like]: `%${search}%` } },
|
||
{ deviceId: { [Op.like]: `%${search}%` } }
|
||
];
|
||
}
|
||
|
||
if (startDate || endDate) {
|
||
whereConditions.uptime = {};
|
||
if (startDate) {
|
||
whereConditions.uptime[Op.gte] = new Date(startDate);
|
||
}
|
||
if (endDate) {
|
||
whereConditions.uptime[Op.lte] = new Date(endDate);
|
||
}
|
||
}
|
||
|
||
// 获取所有设备数据
|
||
const allDevices = await IotXqClient.findAll({
|
||
where: whereConditions,
|
||
order: [['uptime', 'DESC'], ['id', 'DESC']]
|
||
});
|
||
|
||
// 生成预警数据(与获取列表相同的逻辑)
|
||
const allAlerts = [];
|
||
|
||
allDevices.forEach(device => {
|
||
const deviceId = device.sn || `COLLAR${device.id}`;
|
||
const alertTime = new Date(device.uptime || Date.now()).toISOString().replace('T', ' ').substring(0, 19);
|
||
|
||
const actualBattery = parseInt(device.battery) || 0;
|
||
const actualTemperature = parseFloat(device.temperature) || 0;
|
||
const totalSteps = parseInt(device.steps) || 0;
|
||
const yesterdaySteps = parseInt(device.y_steps) || 0;
|
||
const dailySteps = totalSteps - yesterdaySteps;
|
||
|
||
// 添加基础信息到预警的函数
|
||
const addBaseInfoToAlert = (alert) => {
|
||
alert.deviceId = device.id;
|
||
alert.deviceName = deviceId;
|
||
alert.collarNumber = deviceId;
|
||
alert.dailySteps = dailySteps;
|
||
alert.totalSteps = totalSteps;
|
||
alert.yesterdaySteps = yesterdaySteps;
|
||
alert.battery = actualBattery;
|
||
alert.temperature = actualTemperature;
|
||
alert.alertTime = alertTime;
|
||
alert.deviceStatus = device.is_connect === 1 ? '在线' : '离线';
|
||
alert.gpsSignal = device.is_connect === 1 ? '强' : '无';
|
||
alert.wearStatus = device.bandge_status === 1 ? '已佩戴' : '未佩戴';
|
||
alert.longitude = 116.3974 + (device.id % 100) * 0.0001;
|
||
alert.latitude = 39.9093 + (device.id % 100) * 0.0001;
|
||
return alert;
|
||
};
|
||
|
||
// 生成各类预警(与获取列表相同的逻辑)
|
||
if (device.state === 0) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_offline`,
|
||
alertType: 'offline',
|
||
alertLevel: 'high',
|
||
description: '设备已离线超过30分钟',
|
||
movementStatus: '静止'
|
||
}));
|
||
}
|
||
|
||
if (actualBattery > 0 && actualBattery < 20) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_battery`,
|
||
alertType: 'battery',
|
||
alertLevel: actualBattery < 10 ? 'high' : 'medium',
|
||
description: `设备电量低于20%,当前电量${actualBattery}%`,
|
||
movementStatus: '正常'
|
||
}));
|
||
}
|
||
|
||
if (actualTemperature > 0) {
|
||
if (actualTemperature < 30) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_temperature_low`,
|
||
alertType: 'temperature',
|
||
alertLevel: actualTemperature < 20 ? 'high' : 'medium',
|
||
description: `设备温度过低,当前温度${actualTemperature}°C`,
|
||
movementStatus: '正常'
|
||
}));
|
||
} else if (actualTemperature > 40) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_temperature_high`,
|
||
alertType: 'temperature',
|
||
alertLevel: actualTemperature > 45 ? 'high' : 'medium',
|
||
description: `设备温度过高,当前温度${actualTemperature}°C`,
|
||
movementStatus: '正常'
|
||
}));
|
||
}
|
||
}
|
||
|
||
if (dailySteps === 0 && totalSteps > 0) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_movement_zero`,
|
||
alertType: 'movement',
|
||
alertLevel: 'high',
|
||
description: '检测到步数异常,当日运动量为0步,可能为设备故障或动物异常',
|
||
movementStatus: '异常'
|
||
}));
|
||
}
|
||
|
||
if (device.bandge_status === 0) {
|
||
allAlerts.push(addBaseInfoToAlert({
|
||
id: `${device.id}_wear`,
|
||
alertType: 'wear',
|
||
alertLevel: 'high',
|
||
description: '设备佩戴状态异常,可能已脱落',
|
||
movementStatus: '正常'
|
||
}));
|
||
}
|
||
});
|
||
|
||
// 应用筛选条件
|
||
let filteredAlerts = allAlerts;
|
||
if (alertType && alertType.trim() !== '') {
|
||
filteredAlerts = allAlerts.filter(alert => alert.alertType === alertType);
|
||
}
|
||
if (alertLevel && alertLevel.trim() !== '') {
|
||
filteredAlerts = filteredAlerts.filter(alert => alert.alertLevel === alertLevel);
|
||
}
|
||
|
||
// 根据格式返回数据
|
||
if (format === 'csv') {
|
||
// 这里可以实现CSV格式导出
|
||
res.setHeader('Content-Type', 'text/csv');
|
||
res.setHeader('Content-Disposition', 'attachment; filename="collar_alerts.csv"');
|
||
res.send('CSV格式导出功能待实现');
|
||
} else {
|
||
res.json({
|
||
success: true,
|
||
data: filteredAlerts,
|
||
total: filteredAlerts.length,
|
||
message: '导出智能项圈预警数据成功'
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error('导出智能项圈预警数据失败:', error);
|
||
res.status(500).json({
|
||
success: false,
|
||
message: '导出智能项圈预警数据失败',
|
||
error: error.message
|
||
});
|
||
}
|
||
};
|