优化项目bug
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
const { CattleBatch, IotCattle, Farm, CattleBatchAnimal, User } = require('../models');
|
||||
const { CattleBatch, IotCattle, Farm, CattleBatchAnimal, User, CattleType, CattleUser, CattlePen } = require('../models');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
/**
|
||||
@@ -386,6 +386,9 @@ class CattleBatchController {
|
||||
const { page = 1, pageSize = 10 } = req.query;
|
||||
const offset = (page - 1) * pageSize;
|
||||
|
||||
console.log('🔍 开始获取批次牛只数据');
|
||||
console.log('📋 批次信息:', { id, page, pageSize, offset });
|
||||
|
||||
// 检查批次是否存在
|
||||
const batch = await CattleBatch.findByPk(id);
|
||||
if (!batch) {
|
||||
@@ -395,31 +398,127 @@ class CattleBatchController {
|
||||
});
|
||||
}
|
||||
|
||||
// 获取批次中的牛只
|
||||
console.log('✅ 批次存在:', batch.name);
|
||||
|
||||
// 获取批次中的牛只(直接通过batchId字段查询)
|
||||
const { count, rows } = await IotCattle.findAndCountAll({
|
||||
where: { batchId: id },
|
||||
attributes: [
|
||||
'id',
|
||||
'earNumber',
|
||||
'sex',
|
||||
'strain',
|
||||
'varieties',
|
||||
'birthday',
|
||||
'parity',
|
||||
'orgId',
|
||||
'penId'
|
||||
],
|
||||
include: [
|
||||
{
|
||||
model: CattleBatchAnimal,
|
||||
as: 'batchAnimals',
|
||||
where: { batchId: id },
|
||||
attributes: ['id', 'joinDate', 'notes']
|
||||
},
|
||||
{
|
||||
model: Farm,
|
||||
as: 'farm',
|
||||
attributes: ['id', 'name']
|
||||
}
|
||||
],
|
||||
attributes: ['id', 'earNumber', 'sex', 'strain', 'orgId'],
|
||||
limit: parseInt(pageSize),
|
||||
offset: offset,
|
||||
order: [['earNumber', 'ASC']]
|
||||
});
|
||||
|
||||
console.log(`📊 查询结果: 总记录数=${count}, 返回记录数=${rows.length}`);
|
||||
|
||||
// 获取品种和品系映射数据
|
||||
const typeIds = [...new Set(rows.map(cattle => cattle.varieties).filter(id => id))];
|
||||
const strainIds = [...new Set(rows.map(cattle => cattle.strain).filter(id => id))];
|
||||
const penIds = [...new Set(rows.map(cattle => cattle.penId).filter(id => id))];
|
||||
|
||||
const typeNames = {};
|
||||
if (typeIds.length > 0) {
|
||||
const types = await CattleType.findAll({
|
||||
where: { id: typeIds },
|
||||
attributes: ['id', 'name']
|
||||
});
|
||||
types.forEach(type => {
|
||||
typeNames[type.id] = type.name;
|
||||
});
|
||||
}
|
||||
|
||||
const userNames = {};
|
||||
if (strainIds.length > 0) {
|
||||
const users = await CattleUser.findAll({
|
||||
where: { id: strainIds },
|
||||
attributes: ['id', 'name']
|
||||
});
|
||||
users.forEach(user => {
|
||||
userNames[user.id] = user.name;
|
||||
});
|
||||
}
|
||||
|
||||
const penNames = {};
|
||||
if (penIds.length > 0) {
|
||||
const pens = await CattlePen.findAll({
|
||||
where: { id: penIds },
|
||||
attributes: ['id', 'name']
|
||||
});
|
||||
pens.forEach(pen => {
|
||||
penNames[pen.id] = pen.name;
|
||||
});
|
||||
}
|
||||
|
||||
// 转换数据格式,添加计算字段
|
||||
const transformedRows = rows.map(cattle => {
|
||||
// 计算月龄(基于出生日期)
|
||||
let ageInMonths = 0;
|
||||
if (cattle.birthday) {
|
||||
const birthDate = new Date(cattle.birthday * 1000);
|
||||
const now = new Date();
|
||||
ageInMonths = Math.floor((now - birthDate) / (1000 * 60 * 60 * 24 * 30));
|
||||
}
|
||||
|
||||
// 性别转换
|
||||
const genderMap = { 1: '公', 2: '母', 0: '未知' };
|
||||
const gender = genderMap[cattle.sex] || '未知';
|
||||
|
||||
// 品种转换(动态查询)
|
||||
const breed = typeNames[cattle.varieties] || `品种ID:${cattle.varieties}`;
|
||||
|
||||
// 生理阶段判断
|
||||
let physiologicalStage = '未知';
|
||||
if (ageInMonths < 6) {
|
||||
physiologicalStage = '犊牛';
|
||||
} else if (ageInMonths < 12) {
|
||||
physiologicalStage = '育成牛';
|
||||
} else if (ageInMonths < 24) {
|
||||
physiologicalStage = '青年牛';
|
||||
} else if (cattle.sex === 2) {
|
||||
if (cattle.parity > 0) {
|
||||
physiologicalStage = '泌乳牛';
|
||||
} else {
|
||||
physiologicalStage = '后备母牛';
|
||||
}
|
||||
} else {
|
||||
physiologicalStage = '种公牛';
|
||||
}
|
||||
|
||||
return {
|
||||
id: cattle.id,
|
||||
earTag: cattle.earNumber,
|
||||
breed: breed,
|
||||
gender: gender,
|
||||
ageInMonths: ageInMonths,
|
||||
physiologicalStage: physiologicalStage,
|
||||
pen: cattle.penId ? (penNames[cattle.penId] || `栏舍ID:${cattle.penId}`) : '未分配栏舍',
|
||||
farm: cattle.farm
|
||||
};
|
||||
});
|
||||
|
||||
console.log('🔄 转换后的数据示例:', transformedRows.slice(0, 2));
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
list: rows,
|
||||
list: transformedRows,
|
||||
total: count,
|
||||
page: parseInt(page),
|
||||
pageSize: parseInt(pageSize)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { CattlePen, Farm, IotCattle } = require('../models');
|
||||
const { CattlePen, Farm, IotCattle, CattleType, CattleUser } = require('../models');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
/**
|
||||
@@ -378,7 +378,16 @@ class CattlePenController {
|
||||
// 获取栏舍中的牛只
|
||||
const { count, rows } = await IotCattle.findAndCountAll({
|
||||
where: { penId: id },
|
||||
attributes: ['id', 'earNumber', 'sex', 'strain', 'orgId'],
|
||||
attributes: [
|
||||
'id',
|
||||
'earNumber',
|
||||
'sex',
|
||||
'strain',
|
||||
'varieties',
|
||||
'birthday',
|
||||
'parity',
|
||||
'orgId'
|
||||
],
|
||||
include: [
|
||||
{
|
||||
model: Farm,
|
||||
@@ -391,10 +400,82 @@ class CattlePenController {
|
||||
order: [['earNumber', 'ASC']]
|
||||
});
|
||||
|
||||
// 获取品种和品系映射数据
|
||||
const typeIds = [...new Set(rows.map(cattle => cattle.varieties).filter(id => id))];
|
||||
const strainIds = [...new Set(rows.map(cattle => cattle.strain).filter(id => id))];
|
||||
|
||||
const typeNames = {};
|
||||
if (typeIds.length > 0) {
|
||||
const types = await CattleType.findAll({
|
||||
where: { id: typeIds },
|
||||
attributes: ['id', 'name']
|
||||
});
|
||||
types.forEach(type => {
|
||||
typeNames[type.id] = type.name;
|
||||
});
|
||||
}
|
||||
|
||||
const userNames = {};
|
||||
if (strainIds.length > 0) {
|
||||
const users = await CattleUser.findAll({
|
||||
where: { id: strainIds },
|
||||
attributes: ['id', 'name']
|
||||
});
|
||||
users.forEach(user => {
|
||||
userNames[user.id] = user.name;
|
||||
});
|
||||
}
|
||||
|
||||
// 转换数据格式,添加计算字段
|
||||
const transformedRows = rows.map(cattle => {
|
||||
// 计算月龄(基于出生日期)
|
||||
let ageInMonths = 0;
|
||||
if (cattle.birthday) {
|
||||
const birthDate = new Date(cattle.birthday * 1000); // 假设birthday是Unix时间戳
|
||||
const now = new Date();
|
||||
ageInMonths = Math.floor((now - birthDate) / (1000 * 60 * 60 * 24 * 30));
|
||||
}
|
||||
|
||||
// 性别转换
|
||||
const genderMap = { 1: '公', 2: '母', 0: '未知' };
|
||||
const gender = genderMap[cattle.sex] || '未知';
|
||||
|
||||
// 品种转换(动态查询)
|
||||
const breed = typeNames[cattle.varieties] || `品种ID:${cattle.varieties}`;
|
||||
|
||||
// 生理阶段判断(基于月龄和性别)
|
||||
let physiologicalStage = '未知';
|
||||
if (ageInMonths < 6) {
|
||||
physiologicalStage = '犊牛';
|
||||
} else if (ageInMonths < 12) {
|
||||
physiologicalStage = '育成牛';
|
||||
} else if (ageInMonths < 24) {
|
||||
physiologicalStage = '青年牛';
|
||||
} else if (cattle.sex === 2) { // 母牛
|
||||
if (cattle.parity > 0) {
|
||||
physiologicalStage = '泌乳牛';
|
||||
} else {
|
||||
physiologicalStage = '后备母牛';
|
||||
}
|
||||
} else { // 公牛
|
||||
physiologicalStage = '种公牛';
|
||||
}
|
||||
|
||||
return {
|
||||
id: cattle.id,
|
||||
earTag: cattle.earNumber, // 映射到前端期望的字段名
|
||||
breed: breed,
|
||||
gender: gender,
|
||||
ageInMonths: ageInMonths,
|
||||
physiologicalStage: physiologicalStage,
|
||||
farm: cattle.farm
|
||||
};
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
list: rows,
|
||||
list: transformedRows,
|
||||
total: count,
|
||||
page: parseInt(page),
|
||||
pageSize: parseInt(pageSize)
|
||||
|
||||
@@ -24,15 +24,15 @@ const calculateAgeInMonths = (birthday) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* 类别中文映射
|
||||
* 类别中文映射(与前端保持一致)
|
||||
*/
|
||||
const getCategoryName = (cate) => {
|
||||
const categoryMap = {
|
||||
1: '犊牛',
|
||||
2: '繁殖牛',
|
||||
3: '基础母牛',
|
||||
4: '隔离牛',
|
||||
5: '治疗牛',
|
||||
2: '育成母牛',
|
||||
3: '架子牛',
|
||||
4: '青年牛',
|
||||
5: '基础母牛',
|
||||
6: '育肥牛'
|
||||
};
|
||||
return categoryMap[cate] || '未知';
|
||||
@@ -128,10 +128,20 @@ class IotCattleController {
|
||||
|
||||
// 搜索条件
|
||||
if (search) {
|
||||
whereConditions[Op.or] = [
|
||||
{ earNumber: { [Op.like]: `%${search}%` } },
|
||||
{ strain: { [Op.like]: `%${search}%` } }
|
||||
];
|
||||
// 尝试将搜索词转换为数字,如果成功则按数字搜索,否则按字符串搜索
|
||||
const searchNumber = parseInt(search);
|
||||
if (!isNaN(searchNumber)) {
|
||||
// 数字搜索:精确匹配耳号
|
||||
whereConditions[Op.or] = [
|
||||
{ earNumber: searchNumber },
|
||||
{ strain: { [Op.like]: `%${search}%` } }
|
||||
];
|
||||
} else {
|
||||
// 字符串搜索:模糊匹配
|
||||
whereConditions[Op.or] = [
|
||||
{ strain: { [Op.like]: `%${search}%` } }
|
||||
];
|
||||
}
|
||||
console.log('=== 搜索条件构建 ===');
|
||||
console.log('搜索关键词:', search);
|
||||
console.log('搜索条件对象:', JSON.stringify(whereConditions, null, 2));
|
||||
@@ -159,16 +169,13 @@ class IotCattleController {
|
||||
console.log('完整查询条件:', JSON.stringify(whereConditions, null, 2));
|
||||
console.log('分页参数:', { offset, limit: pageSize });
|
||||
|
||||
// 先获取总数(严格查询未删除的记录)
|
||||
// 先获取总数
|
||||
console.log('=== 开始数据库查询 ===');
|
||||
console.log('查询时间:', new Date().toISOString());
|
||||
|
||||
const countStartTime = Date.now();
|
||||
const totalCount = await IotCattle.count({
|
||||
where: {
|
||||
...whereConditions,
|
||||
isDelete: 0 // 确保只统计未删除的记录
|
||||
}
|
||||
where: whereConditions
|
||||
});
|
||||
const countEndTime = Date.now();
|
||||
|
||||
@@ -176,13 +183,10 @@ class IotCattleController {
|
||||
console.log('查询耗时:', countEndTime - countStartTime, 'ms');
|
||||
console.log('总记录数:', totalCount);
|
||||
|
||||
// 获取分页数据(严格查询未删除的记录)
|
||||
// 获取分页数据
|
||||
const dataStartTime = Date.now();
|
||||
const rows = await IotCattle.findAll({
|
||||
where: {
|
||||
...whereConditions,
|
||||
isDelete: 0 // 确保只查询未删除的记录
|
||||
},
|
||||
where: whereConditions,
|
||||
attributes: [
|
||||
'id', 'earNumber', 'sex', 'strain', 'varieties', 'cate',
|
||||
'birthWeight', 'birthday', 'penId', 'batchId', 'orgId',
|
||||
|
||||
Reference in New Issue
Block a user