修改管理后台
This commit is contained in:
526
backend/controllers/penController.js
Normal file
526
backend/controllers/penController.js
Normal file
@@ -0,0 +1,526 @@
|
||||
/**
|
||||
* 栏舍控制器
|
||||
* @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
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user