Files
nxxmdata/backend/controllers/penController.js
2025-09-12 20:08:42 +08:00

527 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 栏舍控制器
* @file penController.js
* @description 处理栏舍管理相关的请求
*/
const { Pen, Farm } = require('../models');
const { Op } = require('sequelize');
const logger = require('../utils/logger');
/**
* 获取栏舍列表
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
exports.getPens = async (req, res) => {
try {
const {
page = 1,
pageSize = 10,
search = '',
animalType = '',
status = '',
farmId = ''
} = req.query;
// 输出所有请求参数
logger.info('=== 栏舍搜索请求 ===');
logger.info('请求参数:', {
page,
pageSize,
search,
animalType,
status,
farmId
});
logger.info('搜索关键词详情:', {
search: search,
searchType: typeof search,
searchEmpty: !search,
searchTrimmed: search?.trim()
});
// 构建查询条件
const where = {};
if (search) {
logger.info('🔍 执行搜索,关键词:', search);
where[Op.or] = [
{ name: { [Op.like]: `%${search}%` } },
{ pen_type: { [Op.like]: `%${search}%` } },
{ responsible: { [Op.like]: `%${search}%` } },
{ description: { [Op.like]: `%${search}%` } }
];
logger.info('搜索条件:', where);
} else {
logger.info('📋 显示所有数据(无搜索条件)');
}
if (animalType) {
where.animal_type = animalType;
}
if (status !== '') {
where.status = status === 'true';
}
if (farmId) {
where.farm_id = farmId;
}
// 分页参数
const offset = (page - 1) * pageSize;
const limit = parseInt(pageSize);
// 查询数据
const { count, rows } = await Pen.findAndCountAll({
where,
include: [
{
model: Farm,
as: 'farm',
attributes: ['id', 'name']
}
],
order: [['created_at', 'DESC']],
offset,
limit
});
// 输出查询结果
logger.info('查询结果:', {
totalCount: count,
returnedCount: rows.length,
searchApplied: !!search,
searchKeyword: search || '无'
});
logger.info('返回的栏舍数据:', rows.map(item => ({
id: item.id,
name: item.name,
animal_type: item.animal_type,
pen_type: item.pen_type,
responsible: item.responsible
})));
logger.info('=== 栏舍搜索请求结束 ===\n');
res.status(200).json({
success: true,
data: {
list: rows,
pagination: {
current: parseInt(page),
pageSize: limit,
total: count,
totalPages: Math.ceil(count / limit)
}
}
});
} catch (error) {
console.error('获取栏舍列表失败:', error);
res.status(500).json({
success: false,
message: '获取栏舍列表失败',
error: error.message
});
}
};
/**
* 获取栏舍详情
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
exports.getPenById = async (req, res) => {
try {
const { id } = req.params;
const pen = await Pen.findByPk(id, {
include: [
{
model: Farm,
as: 'farm',
attributes: ['id', 'name']
}
]
});
if (!pen) {
return res.status(404).json({
success: false,
message: '栏舍不存在'
});
}
res.status(200).json({
success: true,
data: pen
});
} catch (error) {
console.error('获取栏舍详情失败:', error);
res.status(500).json({
success: false,
message: '获取栏舍详情失败',
error: error.message
});
}
};
/**
* 创建栏舍
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
exports.createPen = async (req, res) => {
try {
console.log('=== 后端:开始创建栏舍 ===');
console.log('请求体数据:', req.body);
console.log('用户信息:', req.user);
const {
name,
animal_type,
pen_type,
responsible,
capacity,
status = true,
description,
farm_id
} = req.body;
console.log('接收到的字段详情:');
console.log('- 栏舍名 (name):', name);
console.log('- 动物类型 (animal_type):', animal_type);
console.log('- 栏舍类型 (pen_type):', pen_type);
console.log('- 负责人 (responsible):', responsible);
console.log('- 容量 (capacity):', capacity, typeof capacity);
console.log('- 状态 (status):', status, typeof status);
console.log('- 描述 (description):', description);
console.log('- 农场ID (farm_id):', farm_id);
// 验证必填字段
if (!name || !animal_type || !responsible || !capacity) {
console.log('❌ 必填字段验证失败');
console.log('- name:', name ? '✅' : '❌');
console.log('- animal_type:', animal_type ? '✅' : '❌');
console.log('- responsible:', responsible ? '✅' : '❌');
console.log('- capacity:', capacity ? '✅' : '❌');
return res.status(400).json({
success: false,
message: '栏舍名称、动物类型、负责人和容量为必填项'
});
}
console.log('✅ 必填字段验证通过');
// 检查栏舍名称是否重复
console.log('检查栏舍名称是否重复:', name);
const existingPen = await Pen.findOne({
where: { name }
});
if (existingPen) {
console.log('❌ 栏舍名称已存在:', name);
return res.status(400).json({
success: false,
message: '栏舍名称已存在'
});
}
console.log('✅ 栏舍名称可用');
// 创建栏舍
console.log('开始创建栏舍...');
const pen = await Pen.create({
name,
animal_type,
pen_type,
responsible,
capacity: parseInt(capacity),
status: Boolean(status),
description,
farm_id: farm_id ? parseInt(farm_id) : null,
creator: req.user?.username || 'admin'
});
console.log('✅ 栏舍创建成功');
console.log('创建的数据:', {
id: pen.id,
name: pen.name,
animal_type: pen.animal_type,
pen_type: pen.pen_type,
responsible: pen.responsible,
capacity: pen.capacity,
status: pen.status,
description: pen.description,
creator: pen.creator,
created_at: pen.created_at,
updated_at: pen.updated_at
});
res.status(201).json({
success: true,
message: '栏舍创建成功',
data: pen
});
console.log('=== 后端:栏舍创建完成 ===');
} catch (error) {
console.error('❌ 创建栏舍失败:', error);
console.error('错误详情:', error.message);
res.status(500).json({
success: false,
message: '创建栏舍失败',
error: error.message
});
}
};
/**
* 更新栏舍
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
exports.updatePen = async (req, res) => {
try {
console.log('=== 后端:开始更新栏舍 ===');
console.log('请求参数 - ID:', req.params.id);
console.log('请求体数据:', req.body);
console.log('用户信息:', req.user);
const { id } = req.params;
const updateData = req.body;
console.log('准备更新的字段详情:');
console.log('- 栏舍名 (name):', updateData.name);
console.log('- 动物类型 (animal_type):', updateData.animal_type);
console.log('- 栏舍类型 (pen_type):', updateData.pen_type);
console.log('- 负责人 (responsible):', updateData.responsible);
console.log('- 容量 (capacity):', updateData.capacity, typeof updateData.capacity);
console.log('- 状态 (status):', updateData.status, typeof updateData.status);
console.log('- 描述 (description):', updateData.description);
// 查找栏舍
console.log('查找栏舍ID:', id);
const pen = await Pen.findByPk(id);
if (!pen) {
console.log('❌ 栏舍不存在ID:', id);
return res.status(404).json({
success: false,
message: '栏舍不存在'
});
}
console.log('✅ 找到栏舍,当前数据:', {
id: pen.id,
name: pen.name,
animal_type: pen.animal_type,
pen_type: pen.pen_type,
responsible: pen.responsible,
capacity: pen.capacity,
status: pen.status,
description: pen.description
});
// 如果更新名称,检查是否重复
if (updateData.name && updateData.name !== pen.name) {
console.log('检查栏舍名称是否重复:', updateData.name);
const existingPen = await Pen.findOne({
where: {
name: updateData.name,
id: { [Op.ne]: id }
}
});
if (existingPen) {
console.log('❌ 栏舍名称已存在:', updateData.name);
return res.status(400).json({
success: false,
message: '栏舍名称已存在'
});
}
console.log('✅ 栏舍名称可用');
}
// 更新栏舍
console.log('开始更新栏舍数据...');
await pen.update(updateData);
// 重新从数据库获取最新数据
console.log('重新获取最新数据...');
await pen.reload();
console.log('✅ 栏舍更新成功');
console.log('更新后的数据:', {
id: pen.id,
name: pen.name,
animal_type: pen.animal_type,
pen_type: pen.pen_type,
responsible: pen.responsible,
capacity: pen.capacity,
status: pen.status,
description: pen.description,
creator: pen.creator,
created_at: pen.created_at,
updated_at: pen.updated_at
});
res.status(200).json({
success: true,
message: '栏舍更新成功',
data: pen
});
console.log('=== 后端:栏舍更新完成 ===');
} catch (error) {
console.error('❌ 更新栏舍失败:', error);
console.error('错误详情:', error.message);
res.status(500).json({
success: false,
message: '更新栏舍失败',
error: error.message
});
}
};
/**
* 删除栏舍
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
exports.deletePen = async (req, res) => {
try {
const { id } = req.params;
// 查找栏舍
const pen = await Pen.findByPk(id);
if (!pen) {
return res.status(404).json({
success: false,
message: '栏舍不存在'
});
}
// 删除栏舍
await pen.destroy();
res.status(200).json({
success: true,
message: '栏舍删除成功'
});
} catch (error) {
console.error('删除栏舍失败:', error);
res.status(500).json({
success: false,
message: '删除栏舍失败',
error: error.message
});
}
};
/**
* 批量删除栏舍
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
exports.batchDeletePens = async (req, res) => {
try {
const { ids } = req.body;
if (!ids || !Array.isArray(ids) || ids.length === 0) {
return res.status(400).json({
success: false,
message: '请选择要删除的栏舍'
});
}
// 批量删除
const deletedCount = await Pen.destroy({
where: {
id: {
[Op.in]: ids
}
}
});
res.status(200).json({
success: true,
message: `成功删除 ${deletedCount} 个栏舍`
});
} catch (error) {
console.error('批量删除栏舍失败:', error);
res.status(500).json({
success: false,
message: '批量删除栏舍失败',
error: error.message
});
}
};
/**
* 获取栏舍统计信息
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
exports.getPenStats = async (req, res) => {
try {
const { farmId } = req.query;
const where = {};
if (farmId) {
where.farm_id = farmId;
}
// 获取总数统计
const totalPens = await Pen.count({ where });
const activePens = await Pen.count({ where: { ...where, status: true } });
const inactivePens = await Pen.count({ where: { ...where, status: false } });
// 按动物类型统计
const pensByAnimalType = await Pen.findAll({
attributes: [
'animal_type',
[Pen.sequelize.fn('COUNT', Pen.sequelize.col('id')), 'count']
],
where,
group: ['animal_type'],
raw: true
});
// 按农场统计
const pensByFarm = await Pen.findAll({
attributes: [
'farm_id',
[Pen.sequelize.fn('COUNT', Pen.sequelize.col('id')), 'count']
],
where,
group: ['farm_id'],
include: [
{
model: Farm,
as: 'farm',
attributes: ['name']
}
],
raw: true
});
res.status(200).json({
success: true,
data: {
totalPens,
activePens,
inactivePens,
pensByAnimalType,
pensByFarm
}
});
} catch (error) {
console.error('获取栏舍统计信息失败:', error);
res.status(500).json({
success: false,
message: '获取栏舍统计信息失败',
error: error.message
});
}
};