2025-08-25 15:00:46 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 养殖场控制器
|
|
|
|
|
|
* @file farmController.js
|
|
|
|
|
|
* @description 处理养殖场相关的请求
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
const { Farm, Animal, Device } = require('../models');
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取所有养殖场
|
|
|
|
|
|
* @param {Object} req - 请求对象
|
|
|
|
|
|
* @param {Object} res - 响应对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
exports.getAllFarms = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const farms = await Farm.findAll({
|
|
|
|
|
|
include: [
|
|
|
|
|
|
{
|
|
|
|
|
|
model: Animal,
|
|
|
|
|
|
as: 'animals',
|
|
|
|
|
|
attributes: ['id', 'type', 'count', 'health_status']
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
model: Device,
|
|
|
|
|
|
as: 'devices',
|
|
|
|
|
|
attributes: ['id', 'name', 'type', 'status']
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
});
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
data: farms
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取养殖场列表失败:', error);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '获取养殖场列表失败',
|
|
|
|
|
|
error: error.message
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取单个养殖场
|
|
|
|
|
|
* @param {Object} req - 请求对象
|
|
|
|
|
|
* @param {Object} res - 响应对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
exports.getFarmById = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
|
const farm = await Farm.findByPk(id);
|
|
|
|
|
|
|
|
|
|
|
|
if (!farm) {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '养殖场不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
data: farm
|
|
|
|
|
|
});
|
|
|
|
|
|
} 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.createFarm = async (req, res) => {
|
|
|
|
|
|
try {
|
2025-08-27 15:36:36 +08:00
|
|
|
|
const { name, type, owner, longitude, latitude, address, phone, area, capacity, status, description } = req.body;
|
2025-08-25 15:00:46 +08:00
|
|
|
|
|
|
|
|
|
|
// 验证必填字段
|
2025-08-27 15:36:36 +08:00
|
|
|
|
if (!name || !type) {
|
|
|
|
|
|
return res.status(400).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '名称、类型和位置为必填项'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 构建location对象
|
|
|
|
|
|
const location = {};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理经度
|
|
|
|
|
|
if (longitude !== undefined && longitude !== null && longitude !== '') {
|
|
|
|
|
|
const lng = parseFloat(longitude);
|
|
|
|
|
|
if (!isNaN(lng)) {
|
|
|
|
|
|
location.lng = lng;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理纬度
|
|
|
|
|
|
if (latitude !== undefined && latitude !== null && latitude !== '') {
|
|
|
|
|
|
const lat = parseFloat(latitude);
|
|
|
|
|
|
if (!isNaN(lat)) {
|
|
|
|
|
|
location.lat = lat;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证location对象不能为空(至少需要经纬度之一)
|
|
|
|
|
|
if (Object.keys(location).length === 0) {
|
2025-08-25 15:00:46 +08:00
|
|
|
|
return res.status(400).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '名称、类型和位置为必填项'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const farm = await Farm.create({
|
|
|
|
|
|
name,
|
|
|
|
|
|
type,
|
|
|
|
|
|
location,
|
|
|
|
|
|
address,
|
2025-08-27 15:36:36 +08:00
|
|
|
|
contact: owner,
|
2025-08-25 15:00:46 +08:00
|
|
|
|
phone,
|
2025-08-27 15:36:36 +08:00
|
|
|
|
status: status || 'active'
|
2025-08-25 15:00:46 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(201).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
message: '养殖场创建成功',
|
|
|
|
|
|
data: farm
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('创建养殖场失败:', error);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '创建养殖场失败',
|
|
|
|
|
|
error: error.message
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 更新养殖场
|
|
|
|
|
|
* @param {Object} req - 请求对象
|
|
|
|
|
|
* @param {Object} res - 响应对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
exports.updateFarm = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { id } = req.params;
|
2025-08-27 15:36:36 +08:00
|
|
|
|
const { name, owner, longitude, latitude, address, phone, area, capacity, status, description } = req.body;
|
2025-08-25 15:00:46 +08:00
|
|
|
|
|
|
|
|
|
|
const farm = await Farm.findByPk(id);
|
|
|
|
|
|
|
|
|
|
|
|
if (!farm) {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '养殖场不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 15:36:36 +08:00
|
|
|
|
// 构建location对象 - 创建新对象以确保Sequelize检测到变化
|
|
|
|
|
|
const location = { ...(farm.location || {}) };
|
|
|
|
|
|
|
|
|
|
|
|
// 处理经度
|
|
|
|
|
|
if (longitude !== undefined) {
|
|
|
|
|
|
if (longitude !== null && longitude !== '') {
|
|
|
|
|
|
location.lng = parseFloat(longitude);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
delete location.lng; // 清空经度
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理纬度
|
|
|
|
|
|
if (latitude !== undefined) {
|
|
|
|
|
|
if (latitude !== null && latitude !== '') {
|
|
|
|
|
|
location.lat = parseFloat(latitude);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
delete location.lat; // 清空纬度
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-25 15:00:46 +08:00
|
|
|
|
await farm.update({
|
|
|
|
|
|
name,
|
2025-08-27 15:36:36 +08:00
|
|
|
|
type: farm.type || 'farm',
|
2025-08-25 15:00:46 +08:00
|
|
|
|
location,
|
|
|
|
|
|
address,
|
2025-08-27 15:36:36 +08:00
|
|
|
|
contact: owner,
|
2025-08-25 15:00:46 +08:00
|
|
|
|
phone,
|
2025-08-27 15:36:36 +08:00
|
|
|
|
status: status || 'active'
|
2025-08-25 15:00:46 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
message: '养殖场更新成功',
|
|
|
|
|
|
data: farm
|
|
|
|
|
|
});
|
|
|
|
|
|
} 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.deleteFarm = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
|
const farm = await Farm.findByPk(id);
|
|
|
|
|
|
|
|
|
|
|
|
if (!farm) {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '养殖场不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await farm.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.getFarmAnimals = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
|
const farm = await Farm.findByPk(id);
|
|
|
|
|
|
|
|
|
|
|
|
if (!farm) {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '养殖场不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const animals = await Animal.findAll({
|
|
|
|
|
|
where: { farm_id: id }
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
data: animals
|
|
|
|
|
|
});
|
|
|
|
|
|
} 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.getFarmDevices = async (req, res) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
|
const farm = await Farm.findByPk(id);
|
|
|
|
|
|
|
|
|
|
|
|
if (!farm) {
|
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '养殖场不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const devices = await Device.findAll({
|
|
|
|
|
|
where: { farm_id: id }
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
data: devices
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(`获取养殖场(ID: ${req.params.id})的设备数据失败:`, error);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '获取养殖场设备数据失败',
|
|
|
|
|
|
error: error.message
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|