527 lines
13 KiB
JavaScript
527 lines
13 KiB
JavaScript
/**
|
||
* 栏舍控制器
|
||
* @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
|
||
});
|
||
}
|
||
};
|