buider
This commit is contained in:
@@ -79,10 +79,37 @@ exports.getFarmById = async (req, res) => {
|
||||
*/
|
||||
exports.createFarm = async (req, res) => {
|
||||
try {
|
||||
const { name, type, location, address, contact, phone, status } = req.body;
|
||||
const { name, type, owner, longitude, latitude, address, phone, area, capacity, status, description } = req.body;
|
||||
|
||||
// 验证必填字段
|
||||
if (!name || !type || !location) {
|
||||
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) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '名称、类型和位置为必填项'
|
||||
@@ -94,9 +121,9 @@ exports.createFarm = async (req, res) => {
|
||||
type,
|
||||
location,
|
||||
address,
|
||||
contact,
|
||||
contact: owner,
|
||||
phone,
|
||||
status
|
||||
status: status || 'active'
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
@@ -122,7 +149,7 @@ exports.createFarm = async (req, res) => {
|
||||
exports.updateFarm = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, type, location, address, contact, phone, status } = req.body;
|
||||
const { name, owner, longitude, latitude, address, phone, area, capacity, status, description } = req.body;
|
||||
|
||||
const farm = await Farm.findByPk(id);
|
||||
|
||||
@@ -133,14 +160,35 @@ exports.updateFarm = async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
// 构建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; // 清空纬度
|
||||
}
|
||||
}
|
||||
|
||||
await farm.update({
|
||||
name,
|
||||
type,
|
||||
type: farm.type || 'farm',
|
||||
location,
|
||||
address,
|
||||
contact,
|
||||
contact: owner,
|
||||
phone,
|
||||
status
|
||||
status: status || 'active'
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
|
||||
@@ -8,6 +8,231 @@ const { Farm, Animal, Device, Alert, SensorData } = require('../models');
|
||||
const { sequelize } = require('../config/database-simple');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
/**
|
||||
* 获取动物总数统计(实时数据库查询)
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
exports.getAnimalCount = async (req, res) => {
|
||||
try {
|
||||
// 测试数据库连接状态
|
||||
await sequelize.authenticate();
|
||||
|
||||
// 执行精确的SQL查询统计动物总数
|
||||
const animalCountResult = await sequelize.query(
|
||||
'SELECT SUM(count) as total_animals FROM animals',
|
||||
{
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
raw: true
|
||||
}
|
||||
);
|
||||
|
||||
// 获取按类型分组的动物数量
|
||||
const animalsByTypeResult = await sequelize.query(
|
||||
'SELECT type, SUM(count) as total_count FROM animals GROUP BY type',
|
||||
{
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
raw: true
|
||||
}
|
||||
);
|
||||
|
||||
// 获取按健康状态分组的动物数量
|
||||
const animalsByHealthResult = await sequelize.query(
|
||||
'SELECT health_status, SUM(count) as total_count FROM animals GROUP BY health_status',
|
||||
{
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
raw: true
|
||||
}
|
||||
);
|
||||
|
||||
// 获取按农场分组的动物数量
|
||||
const animalsByFarmResult = await sequelize.query(
|
||||
'SELECT farm_id, SUM(count) as total_count FROM animals GROUP BY farm_id',
|
||||
{
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
raw: true
|
||||
}
|
||||
);
|
||||
|
||||
const totalAnimals = animalCountResult[0]?.total_animals || 0;
|
||||
|
||||
// 格式化类型统计数据
|
||||
const typeStats = {};
|
||||
animalsByTypeResult.forEach(item => {
|
||||
typeStats[item.type] = parseInt(item.total_count);
|
||||
});
|
||||
|
||||
// 格式化健康状态统计数据
|
||||
const healthStats = {
|
||||
healthy: 0,
|
||||
sick: 0,
|
||||
quarantine: 0,
|
||||
treatment: 0
|
||||
};
|
||||
|
||||
animalsByHealthResult.forEach(item => {
|
||||
healthStats[item.health_status] = parseInt(item.total_count);
|
||||
});
|
||||
|
||||
// 格式化农场统计数据
|
||||
const farmStats = {};
|
||||
animalsByFarmResult.forEach(item => {
|
||||
farmStats[`farm_${item.farm_id}`] = parseInt(item.total_count);
|
||||
});
|
||||
|
||||
const response = {
|
||||
totalAnimals: parseInt(totalAnimals),
|
||||
animalsByType: typeStats,
|
||||
animalsByHealth: healthStats,
|
||||
animalsByFarm: farmStats,
|
||||
lastUpdated: new Date().toISOString(),
|
||||
dataSource: 'mysql_realtime'
|
||||
};
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: response
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取动物总数统计失败:', error);
|
||||
|
||||
// 数据库连接错误处理
|
||||
if (error.name === 'SequelizeConnectionError' ||
|
||||
error.name === 'SequelizeConnectionRefusedError' ||
|
||||
error.name === 'SequelizeHostNotFoundError') {
|
||||
return res.status(503).json({
|
||||
success: false,
|
||||
message: '数据库连接失败,无法获取实时数据',
|
||||
error: 'DATABASE_CONNECTION_ERROR',
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
|
||||
// 其他数据库错误
|
||||
if (error.name && error.name.startsWith('Sequelize')) {
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
message: '数据库查询错误',
|
||||
error: 'DATABASE_QUERY_ERROR',
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
|
||||
// 通用错误处理
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取动物总数统计失败',
|
||||
error: 'INTERNAL_SERVER_ERROR',
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取农场总数统计(实时数据库查询)
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
exports.getFarmCount = async (req, res) => {
|
||||
try {
|
||||
// 测试数据库连接状态
|
||||
await sequelize.authenticate();
|
||||
|
||||
// 执行精确的SQL查询统计农场总数
|
||||
const farmCountResult = await sequelize.query(
|
||||
'SELECT COUNT(*) as total_farms FROM farms',
|
||||
{
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
raw: true
|
||||
}
|
||||
);
|
||||
|
||||
// 获取按状态分组的农场数量
|
||||
const farmsByStatusResult = await sequelize.query(
|
||||
'SELECT status, COUNT(*) as count FROM farms GROUP BY status',
|
||||
{
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
raw: true
|
||||
}
|
||||
);
|
||||
|
||||
// 获取按类型分组的农场数量
|
||||
const farmsByTypeResult = await sequelize.query(
|
||||
'SELECT type, COUNT(*) as count FROM farms GROUP BY type',
|
||||
{
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
raw: true
|
||||
}
|
||||
);
|
||||
|
||||
const totalFarms = farmCountResult[0]?.total_farms || 0;
|
||||
|
||||
// 格式化状态统计数据
|
||||
const statusStats = {
|
||||
active: 0,
|
||||
inactive: 0,
|
||||
maintenance: 0
|
||||
};
|
||||
|
||||
farmsByStatusResult.forEach(item => {
|
||||
statusStats[item.status] = parseInt(item.count);
|
||||
});
|
||||
|
||||
// 格式化类型统计数据
|
||||
const typeStats = {};
|
||||
farmsByTypeResult.forEach(item => {
|
||||
typeStats[item.type] = parseInt(item.count);
|
||||
});
|
||||
|
||||
const response = {
|
||||
totalFarms: parseInt(totalFarms),
|
||||
farmsByStatus: statusStats,
|
||||
farmsByType: typeStats,
|
||||
lastUpdated: new Date().toISOString(),
|
||||
dataSource: 'mysql_realtime'
|
||||
};
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: response
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取农场总数统计失败:', error);
|
||||
|
||||
// 数据库连接错误处理
|
||||
if (error.name === 'SequelizeConnectionError' ||
|
||||
error.name === 'SequelizeConnectionRefusedError' ||
|
||||
error.name === 'SequelizeHostNotFoundError') {
|
||||
return res.status(503).json({
|
||||
success: false,
|
||||
message: '数据库连接失败,无法获取实时数据',
|
||||
error: 'DATABASE_CONNECTION_ERROR',
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
|
||||
// 其他数据库错误
|
||||
if (error.name && error.name.startsWith('Sequelize')) {
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
message: '数据库查询错误',
|
||||
error: 'DATABASE_QUERY_ERROR',
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
|
||||
// 通用错误处理
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取农场总数统计失败',
|
||||
error: 'INTERNAL_SERVER_ERROR',
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取仪表盘统计数据
|
||||
* @param {Object} req - 请求对象
|
||||
|
||||
Reference in New Issue
Block a user