/** * 栏舍控制器 * @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 }); } };