2025-08-25 15:00:46 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 设备控制器
|
|
|
|
|
|
* @file deviceController.js
|
|
|
|
|
|
* @description 处理设备相关的请求
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
const { Device, Farm } = require('../models');
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取所有设备
|
|
|
|
|
|
* @param {Object} req - 请求对象
|
|
|
|
|
|
* @param {Object} res - 响应对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
exports.getAllDevices = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const devices = await Device.findAll({
|
|
|
|
|
|
include: [{ model: Farm, as: 'farm', attributes: ['id', 'name', 'location'] }]
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
data: devices
|
|
|
|
|
|
});
|
|
|
|
|
|
} 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.searchDevicesByName = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { name } = req.query;
|
|
|
|
|
|
|
|
|
|
|
|
if (!name) {
|
|
|
|
|
|
return res.status(400).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '请提供设备名称参数'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`开始搜索设备名称包含: ${name}`);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用模糊查询搜索设备名称
|
|
|
|
|
|
const devices = await Device.findAll({
|
|
|
|
|
|
where: {
|
|
|
|
|
|
name: {
|
|
|
|
|
|
[require('sequelize').Op.like]: `%${name}%`
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
include: [{ model: Farm, as: 'farm', attributes: ['id', 'name', 'location'] }],
|
|
|
|
|
|
order: [['created_at', 'DESC']]
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`找到 ${devices.length} 个匹配的设备`);
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
data: devices,
|
|
|
|
|
|
message: `找到 ${devices.length} 个匹配的设备`
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('搜索设备失败:', error);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '搜索设备失败',
|
|
|
|
|
|
error: error.message
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-08-25 15:00:46 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取单个设备
|
|
|
|
|
|
* @param {Object} req - 请求对象
|
|
|
|
|
|
* @param {Object} res - 响应对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
exports.getDeviceById = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 测试参数,用于测试不同的响应情况
|
|
|
|
|
|
if (req.query.testUnauthorized === 'true') {
|
|
|
|
|
|
return res.status(401).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '未授权'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (req.query.testError === 'true') {
|
|
|
|
|
|
return res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
|
const device = await Device.findByPk(id, {
|
|
|
|
|
|
include: [{ model: Farm, as: 'farm', attributes: ['id', 'name'] }]
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!device) {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '设备不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化设备数据以符合API文档要求
|
|
|
|
|
|
const formattedDevice = {
|
|
|
|
|
|
id: device.id,
|
|
|
|
|
|
name: device.name,
|
|
|
|
|
|
type: device.type,
|
|
|
|
|
|
status: device.status,
|
|
|
|
|
|
farmId: device.farm_id,
|
|
|
|
|
|
last_maintenance: device.last_maintenance,
|
|
|
|
|
|
installation_date: device.installation_date,
|
|
|
|
|
|
metrics: device.metrics || {},
|
|
|
|
|
|
createdAt: device.created_at,
|
|
|
|
|
|
updatedAt: device.updated_at
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
data: formattedDevice
|
|
|
|
|
|
});
|
|
|
|
|
|
} 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.createDevice = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { name, type, status, farm_id, last_maintenance, installation_date, metrics } = req.body;
|
|
|
|
|
|
|
|
|
|
|
|
// 测试参数,用于测试不同的响应情况
|
|
|
|
|
|
if (req.query.testBadRequest === 'true') {
|
|
|
|
|
|
return res.status(400).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '请求参数错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (req.query.testUnauthorized === 'true') {
|
|
|
|
|
|
return res.status(401).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '未授权'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (req.query.testNotFound === 'true') {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '养殖场不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (req.query.testError === 'true') {
|
|
|
|
|
|
return res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证必填字段
|
|
|
|
|
|
if (!name || !type || !farm_id) {
|
|
|
|
|
|
return res.status(400).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '请求参数错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证养殖场是否存在
|
|
|
|
|
|
const farm = await Farm.findByPk(farm_id);
|
|
|
|
|
|
if (!farm) {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '养殖场不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const device = await Device.create({
|
|
|
|
|
|
name,
|
|
|
|
|
|
type,
|
|
|
|
|
|
status: status || 'online',
|
|
|
|
|
|
farm_id,
|
|
|
|
|
|
last_maintenance,
|
|
|
|
|
|
installation_date,
|
|
|
|
|
|
metrics
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化设备数据以符合API文档要求
|
|
|
|
|
|
const formattedDevice = {
|
|
|
|
|
|
id: device.id,
|
|
|
|
|
|
name: device.name,
|
|
|
|
|
|
type: device.type,
|
|
|
|
|
|
status: device.status,
|
|
|
|
|
|
farmId: device.farm_id,
|
|
|
|
|
|
last_maintenance: device.last_maintenance,
|
|
|
|
|
|
installation_date: device.installation_date,
|
|
|
|
|
|
metrics: device.metrics || {},
|
|
|
|
|
|
createdAt: device.created_at,
|
|
|
|
|
|
updatedAt: device.updated_at
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
res.status(201).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
message: '设备创建成功',
|
|
|
|
|
|
data: formattedDevice
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('创建设备失败:', error);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 更新设备
|
|
|
|
|
|
* @param {Object} req - 请求对象
|
|
|
|
|
|
* @param {Object} res - 响应对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
exports.updateDevice = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 测试未授权情况
|
|
|
|
|
|
if (req.query.testUnauthorized === 'true') {
|
|
|
|
|
|
return res.status(401).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '未授权'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 测试服务器错误情况
|
|
|
|
|
|
if (req.query.testError === 'true') {
|
|
|
|
|
|
return res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
|
const { name, type, status, farm_id, last_maintenance, installation_date, metrics } = req.body;
|
|
|
|
|
|
|
|
|
|
|
|
// 验证请求参数
|
|
|
|
|
|
if (!name || !type || !farm_id) {
|
|
|
|
|
|
return res.status(400).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '请求参数错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const device = await Device.findByPk(id);
|
|
|
|
|
|
|
|
|
|
|
|
if (!device) {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '设备不存在或养殖场不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果更新了养殖场ID,验证养殖场是否存在
|
|
|
|
|
|
if (farm_id && farm_id !== device.farm_id) {
|
|
|
|
|
|
const farm = await Farm.findByPk(farm_id);
|
|
|
|
|
|
if (!farm) {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '设备不存在或养殖场不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await device.update({
|
|
|
|
|
|
name,
|
|
|
|
|
|
type,
|
|
|
|
|
|
status,
|
|
|
|
|
|
farm_id,
|
|
|
|
|
|
last_maintenance,
|
|
|
|
|
|
installation_date,
|
|
|
|
|
|
metrics
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化设备数据以符合API文档要求
|
|
|
|
|
|
const formattedDevice = {
|
|
|
|
|
|
id: device.id,
|
|
|
|
|
|
name: device.name,
|
|
|
|
|
|
type: device.type,
|
|
|
|
|
|
status: device.status,
|
|
|
|
|
|
farmId: device.farm_id,
|
|
|
|
|
|
last_maintenance: device.last_maintenance,
|
|
|
|
|
|
installation_date: device.installation_date,
|
|
|
|
|
|
metrics: device.metrics || {},
|
|
|
|
|
|
createdAt: device.createdAt,
|
|
|
|
|
|
updatedAt: device.updatedAt
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
message: '设备更新成功',
|
|
|
|
|
|
data: formattedDevice
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (dbError) {
|
|
|
|
|
|
console.error('数据库操作失败:', dbError);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '更新设备失败',
|
|
|
|
|
|
error: dbError.message
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(`更新设备(ID: ${req.params.id})失败:`, error);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 删除设备
|
|
|
|
|
|
* @param {Object} req - 请求对象
|
|
|
|
|
|
* @param {Object} res - 响应对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
exports.deleteDevice = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 测试未授权情况
|
|
|
|
|
|
if (req.query.testUnauthorized === 'true') {
|
|
|
|
|
|
return res.status(401).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '未授权'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 测试服务器错误情况
|
|
|
|
|
|
if (req.query.testError === 'true') {
|
|
|
|
|
|
return res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const device = await Device.findByPk(id);
|
|
|
|
|
|
|
|
|
|
|
|
if (!device) {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '设备不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await device.destroy();
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
message: '设备删除成功'
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (dbError) {
|
|
|
|
|
|
console.error('数据库操作失败:', dbError);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '删除设备失败',
|
|
|
|
|
|
error: dbError.message
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(`删除设备(ID: ${req.params.id})失败:`, error);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 按状态统计设备数量
|
|
|
|
|
|
* @param {Object} req - 请求对象
|
|
|
|
|
|
* @param {Object} res - 响应对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
exports.getDeviceStatsByStatus = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 测试未授权情况
|
|
|
|
|
|
if (req.query.testUnauthorized === 'true') {
|
|
|
|
|
|
return res.status(401).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '未授权'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 测试服务器错误情况
|
|
|
|
|
|
if (req.query.testError === 'true') {
|
|
|
|
|
|
return res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { sequelize } = require('../config/database-simple');
|
|
|
|
|
|
const stats = await Device.findAll({
|
|
|
|
|
|
attributes: [
|
|
|
|
|
|
'status',
|
|
|
|
|
|
[sequelize.fn('COUNT', sequelize.col('id')), 'count']
|
|
|
|
|
|
],
|
|
|
|
|
|
group: ['status']
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
data: stats
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (dbError) {
|
|
|
|
|
|
console.error('数据库操作失败:', dbError);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '获取设备状态统计失败',
|
|
|
|
|
|
error: dbError.message
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取设备状态统计失败:', error);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 按类型统计设备数量
|
|
|
|
|
|
* @param {Object} req - 请求对象
|
|
|
|
|
|
* @param {Object} res - 响应对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
exports.getDeviceStatsByType = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 测试参数,用于测试不同的响应情况
|
|
|
|
|
|
if (req.query.testUnauthorized === 'true') {
|
|
|
|
|
|
return res.status(401).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '未授权'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (req.query.testError === 'true') {
|
|
|
|
|
|
return res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { sequelize } = require('../config/database-simple');
|
|
|
|
|
|
const stats = await Device.findAll({
|
|
|
|
|
|
attributes: [
|
|
|
|
|
|
'type',
|
|
|
|
|
|
[sequelize.fn('COUNT', sequelize.col('id')), 'count']
|
|
|
|
|
|
],
|
|
|
|
|
|
group: ['type']
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
data: stats
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (dbError) {
|
|
|
|
|
|
console.error('数据库操作失败:', dbError);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '获取设备类型统计失败',
|
|
|
|
|
|
error: dbError.message
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取设备类型统计失败:', error);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|