修改管理后台
This commit is contained in:
@@ -1,462 +1,241 @@
|
||||
/**
|
||||
* 动物路由
|
||||
* @file animals.js
|
||||
* @description 定义动物相关的API路由
|
||||
* 动物信息路由
|
||||
*/
|
||||
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const animalController = require('../controllers/animalController');
|
||||
const { verifyToken } = require('../middleware/auth');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const { Op } = require('sequelize');
|
||||
const Animal = require('../models/Animal');
|
||||
const { verifyToken, requirePermission } = require('../middleware/auth');
|
||||
|
||||
// 公开API路由,不需要验证token
|
||||
// 公开路由,不需要认证
|
||||
const publicRoutes = express.Router();
|
||||
router.use('/public', publicRoutes);
|
||||
|
||||
// 公开获取所有动物数据
|
||||
// 公开API:获取所有动物列表
|
||||
publicRoutes.get('/', async (req, res) => {
|
||||
try {
|
||||
// 尝试从数据库获取数据
|
||||
const { Animal, Farm } = require('../models');
|
||||
const animals = await Animal.findAll({
|
||||
include: [{ model: Farm, as: 'farm', attributes: ['id', 'name'] }]
|
||||
});
|
||||
const { IotCattle } = require('../models');
|
||||
|
||||
res.status(200).json({
|
||||
// 获取所有牛只档案数据
|
||||
const animals = await IotCattle.findAll({
|
||||
attributes: [
|
||||
'id', 'org_id', 'ear_number', 'sex', 'strain', 'varieties', 'cate',
|
||||
'birth_weight', 'birthday', 'pen_id', 'into_time', 'parity', 'source',
|
||||
'source_day', 'source_weight', 'weight', 'event', 'event_time',
|
||||
'lactation_day', 'semen_num', 'is_wear', 'batch_id', 'imgs',
|
||||
'is_ele_auth', 'is_qua_auth', 'is_delete', 'is_out', 'create_uid',
|
||||
'create_time', 'algebra', 'colour', 'info_weight', 'descent',
|
||||
'is_vaccin', 'is_insemination', 'is_insure', 'is_mortgage',
|
||||
'update_time', 'breed_bull_time', 'level', 'six_weight',
|
||||
'eighteen_weight', 'twelve_day_weight', 'eighteen_day_weight',
|
||||
'xxiv_day_weight', 'semen_breed_imgs', 'sell_status',
|
||||
'weight_calculate_time', 'day_of_birthday', 'user_id'
|
||||
],
|
||||
where: {
|
||||
is_delete: 0, // 只获取未删除的记录
|
||||
is_out: 0 // 只获取未出栏的记录
|
||||
},
|
||||
order: [['create_time', 'DESC']]
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: animals,
|
||||
source: 'database'
|
||||
message: '获取动物列表成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('从数据库获取动物列表失败,使用模拟数据:', error.message);
|
||||
// 数据库不可用时返回模拟数据
|
||||
const mockAnimals = [
|
||||
{ id: 1, name: '牛001', type: '肉牛', breed: '西门塔尔牛', age: 2, weight: 450, status: 'healthy', farmId: 1, farm: { id: 1, name: '宁夏农场1' } },
|
||||
{ id: 2, name: '牛002', type: '肉牛', breed: '安格斯牛', age: 3, weight: 500, status: 'healthy', farmId: 1, farm: { id: 1, name: '宁夏农场1' } },
|
||||
{ id: 3, name: '羊001', type: '肉羊', breed: '小尾寒羊', age: 1, weight: 70, status: 'sick', farmId: 2, farm: { id: 2, name: '宁夏农场2' } }
|
||||
];
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: mockAnimals,
|
||||
source: 'mock',
|
||||
message: '数据库不可用,使用模拟数据'
|
||||
console.error('获取动物列表失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取动物列表失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* tags:
|
||||
* name: Animals
|
||||
* description: 动物管理API
|
||||
*/
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/animals:
|
||||
* get:
|
||||
* summary: 获取所有动物
|
||||
* tags: [Animals]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 成功获取动物列表
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* data:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/components/schemas/Animal'
|
||||
* 401:
|
||||
* description: 未授权
|
||||
* 500:
|
||||
* description: 服务器错误
|
||||
*/
|
||||
router.get('/', (req, res) => {
|
||||
// 从请求头获取token
|
||||
const authHeader = req.headers['authorization'];
|
||||
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
message: '访问令牌缺失'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取动物绑定信息
|
||||
router.get('/binding-info/:collarNumber', async (req, res) => {
|
||||
try {
|
||||
// 验证token
|
||||
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'your_jwt_secret_key');
|
||||
const { collarNumber } = req.params;
|
||||
|
||||
// 将用户信息添加到请求对象中
|
||||
req.user = decoded;
|
||||
console.log(`查询项圈编号 ${collarNumber} 的动物绑定信息`);
|
||||
|
||||
// 调用控制器方法获取数据
|
||||
animalController.getAllAnimals(req, res);
|
||||
} catch (error) {
|
||||
if (error.name === 'JsonWebTokenError' || error.name === 'TokenExpiredError') {
|
||||
return res.status(401).json({
|
||||
// 使用新的绑定API逻辑
|
||||
const { IotJbqClient, IotCattle, Farm, CattlePen, CattleBatch } = require('../models');
|
||||
|
||||
// 查询耳标信息
|
||||
const jbqDevice = await IotJbqClient.findOne({
|
||||
where: { cid: collarNumber },
|
||||
attributes: [
|
||||
'id', 'cid', 'aaid', 'org_id', 'uid', 'time', 'uptime', 'sid',
|
||||
'walk', 'y_steps', 'r_walk', 'lat', 'lon', 'gps_state', 'voltage',
|
||||
'temperature', 'temperature_two', 'state', 'type', 'sort', 'ver',
|
||||
'weight', 'start_time', 'run_days', 'zenowalk', 'zenotime',
|
||||
'is_read', 'read_end_time', 'bank_userid', 'bank_item_id',
|
||||
'bank_house', 'bank_lanwei', 'bank_place', 'is_home',
|
||||
'distribute_time', 'bandge_status', 'is_wear', 'is_temperature',
|
||||
'source_id', 'expire_time'
|
||||
]
|
||||
});
|
||||
|
||||
if (!jbqDevice) {
|
||||
return res.json({
|
||||
success: false,
|
||||
message: '访问令牌无效'
|
||||
message: '未找到指定的耳标设备',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
|
||||
// 查询绑定的牛只档案信息(简化版本,不使用关联查询)
|
||||
const cattleInfo = await IotCattle.findOne({
|
||||
where: { earNumber: collarNumber },
|
||||
attributes: [
|
||||
'id', 'orgId', 'earNumber', 'sex', 'strain', 'varieties', 'cate',
|
||||
'birthWeight', 'birthday', 'penId', 'intoTime', 'parity', 'source',
|
||||
'sourceDay', 'sourceWeight', 'weight', 'event', 'eventTime',
|
||||
'lactationDay', 'semenNum', 'isWear', 'batchId', 'imgs',
|
||||
'isEleAuth', 'isQuaAuth', 'isDelete', 'isOut', 'createUid',
|
||||
'createTime', 'algebra', 'colour', 'infoWeight', 'descent',
|
||||
'isVaccin', 'isInsemination', 'isInsure', 'isMortgage',
|
||||
'updateTime', 'breedBullTime', 'level', 'sixWeight',
|
||||
'eighteenWeight', 'twelveDayWeight', 'eighteenDayWeight',
|
||||
'xxivDayWeight', 'semenBreedImgs', 'sellStatus',
|
||||
'weightCalculateTime', 'dayOfBirthday'
|
||||
]
|
||||
});
|
||||
|
||||
if (!cattleInfo) {
|
||||
return res.json({
|
||||
success: false,
|
||||
message: '该耳标未绑定动物,暂无绑定信息',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
|
||||
// 返回模拟数据
|
||||
const mockAnimals = [
|
||||
{ id: 1, name: '牛001', type: '肉牛', breed: '西门塔尔牛', age: 2, weight: 450, status: 'healthy', farmId: 1, farm: { id: 1, name: '示例养殖场1' } },
|
||||
{ id: 2, name: '牛002', type: '肉牛', breed: '安格斯牛', age: 3, weight: 500, status: 'healthy', farmId: 1, farm: { id: 1, name: '示例养殖场1' } },
|
||||
{ id: 3, name: '羊001', type: '肉羊', breed: '小尾寒羊', age: 1, weight: 70, status: 'sick', farmId: 2, farm: { id: 2, name: '示例养殖场2' } }
|
||||
];
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: mockAnimals
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/animals/{id}:
|
||||
* get:
|
||||
* summary: 获取单个动物
|
||||
* tags: [Animals]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: 动物ID
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 成功获取动物详情
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* data:
|
||||
* $ref: '#/components/schemas/Animal'
|
||||
* 401:
|
||||
* description: 未授权
|
||||
* 404:
|
||||
* description: 动物不存在
|
||||
* 500:
|
||||
* description: 服务器错误
|
||||
*/
|
||||
router.get('/:id', (req, res) => {
|
||||
// 从请求头获取token
|
||||
const authHeader = req.headers['authorization'];
|
||||
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
message: '访问令牌缺失'
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
// 验证token
|
||||
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'your_jwt_secret_key');
|
||||
|
||||
// 将用户信息添加到请求对象中
|
||||
req.user = decoded;
|
||||
|
||||
// 调用控制器方法获取数据
|
||||
animalController.getAnimalById(req, res);
|
||||
} catch (error) {
|
||||
if (error.name === 'JsonWebTokenError' || error.name === 'TokenExpiredError') {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
message: '访问令牌无效'
|
||||
});
|
||||
}
|
||||
|
||||
// 返回模拟数据
|
||||
const animalId = parseInt(req.params.id);
|
||||
const mockAnimal = {
|
||||
id: animalId,
|
||||
name: `动物${animalId}`,
|
||||
type: animalId % 2 === 0 ? '肉牛' : '肉羊',
|
||||
breed: animalId % 2 === 0 ? '西门塔尔牛' : '小尾寒羊',
|
||||
age: Math.floor(Math.random() * 5) + 1,
|
||||
weight: animalId % 2 === 0 ? Math.floor(Math.random() * 200) + 400 : Math.floor(Math.random() * 50) + 50,
|
||||
status: Math.random() > 0.7 ? 'sick' : 'healthy',
|
||||
farmId: Math.ceil(animalId / 3),
|
||||
farm: { id: Math.ceil(animalId / 3), name: `示例养殖场${Math.ceil(animalId / 3)}` }
|
||||
// 格式化数据以匹配前端UI需求
|
||||
const bindingInfo = {
|
||||
// 基础信息
|
||||
basicInfo: {
|
||||
collarNumber: jbqDevice.cid,
|
||||
category: cattleInfo.cate || '奶牛',
|
||||
calvingCount: cattleInfo.parity || 0,
|
||||
earTag: cattleInfo.earNumber,
|
||||
animalType: cattleInfo.sex === 1 ? '公牛' : cattleInfo.sex === 2 ? '母牛' : '未知',
|
||||
breed: cattleInfo.varieties || '荷斯坦',
|
||||
sourceType: cattleInfo.source || '自繁'
|
||||
},
|
||||
// 出生信息
|
||||
birthInfo: {
|
||||
birthDate: cattleInfo.birthday ? new Date(cattleInfo.birthday * 1000).toISOString().split('T')[0] : '',
|
||||
birthWeight: cattleInfo.birthWeight ? parseFloat(cattleInfo.birthWeight).toFixed(2) : '0.00',
|
||||
weaningWeight: cattleInfo.infoWeight ? parseFloat(cattleInfo.infoWeight).toFixed(2) : '0.00',
|
||||
rightTeatCount: '',
|
||||
entryDate: cattleInfo.intoTime ? new Date(cattleInfo.intoTime * 1000).toISOString().split('T')[0] : '',
|
||||
weaningAge: 0,
|
||||
leftTeatCount: ''
|
||||
},
|
||||
// 族谱信息
|
||||
pedigreeInfo: {
|
||||
fatherId: cattleInfo.descent || 'F001',
|
||||
motherId: 'M001',
|
||||
grandfatherId: 'GF001',
|
||||
grandmotherId: 'GM001',
|
||||
bloodline: cattleInfo.algebra || '纯种',
|
||||
generation: 'F3'
|
||||
},
|
||||
// 保险信息
|
||||
insuranceInfo: {
|
||||
policyNumber: 'INS2024001',
|
||||
insuranceCompany: '中国平安',
|
||||
coverageAmount: '50000',
|
||||
premium: '500',
|
||||
startDate: '2024-01-01',
|
||||
endDate: '2024-12-31',
|
||||
status: cattleInfo.isInsure ? '有效' : '未投保'
|
||||
},
|
||||
// 贷款信息
|
||||
loanInfo: {
|
||||
loanNumber: 'LOAN2024001',
|
||||
bankName: '中国农业银行',
|
||||
loanAmount: '100000',
|
||||
interestRate: '4.5%',
|
||||
loanDate: '2024-01-01',
|
||||
maturityDate: '2025-01-01',
|
||||
status: cattleInfo.isMortgage ? '正常' : '无贷款'
|
||||
},
|
||||
// 设备信息
|
||||
deviceInfo: {
|
||||
deviceId: jbqDevice.id,
|
||||
batteryLevel: jbqDevice.voltage,
|
||||
temperature: jbqDevice.temperature,
|
||||
status: jbqDevice.state === 1 ? '在线' : '离线',
|
||||
lastUpdate: jbqDevice.uptime ? new Date(jbqDevice.uptime * 1000).toISOString() : '',
|
||||
location: jbqDevice.lat && jbqDevice.lon ? `${jbqDevice.lat}, ${jbqDevice.lon}` : '无定位'
|
||||
},
|
||||
// 农场信息
|
||||
farmInfo: {
|
||||
farmName: '未知农场',
|
||||
farmAddress: '',
|
||||
penName: '未知栏舍',
|
||||
batchName: '未知批次'
|
||||
}
|
||||
};
|
||||
|
||||
res.status(200).json({
|
||||
res.json({
|
||||
success: true,
|
||||
data: mockAnimal
|
||||
message: '获取绑定信息成功',
|
||||
data: bindingInfo
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取动物绑定信息失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取绑定信息失败: ' + error.message,
|
||||
data: null
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/animals:
|
||||
* post:
|
||||
* summary: 创建动物
|
||||
* tags: [Animals]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - type
|
||||
* - count
|
||||
* - farmId
|
||||
* properties:
|
||||
* type:
|
||||
* type: string
|
||||
* description: 动物类型
|
||||
* count:
|
||||
* type: integer
|
||||
* description: 数量
|
||||
* farmId:
|
||||
* type: integer
|
||||
* description: 所属养殖场ID
|
||||
* health_status:
|
||||
* type: string
|
||||
* enum: [healthy, sick, quarantine]
|
||||
* description: 健康状态
|
||||
* last_inspection:
|
||||
* type: string
|
||||
* format: date-time
|
||||
* description: 最近检查时间
|
||||
* notes:
|
||||
* type: string
|
||||
* description: 备注
|
||||
* responses:
|
||||
* 201:
|
||||
* description: 动物创建成功
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* message:
|
||||
* type: string
|
||||
* example: 动物创建成功
|
||||
* data:
|
||||
* $ref: '#/components/schemas/Animal'
|
||||
* 400:
|
||||
* description: 请求参数错误
|
||||
* 401:
|
||||
* description: 未授权
|
||||
* 404:
|
||||
* description: 养殖场不存在
|
||||
* 500:
|
||||
* description: 服务器错误
|
||||
*/
|
||||
router.post('/', verifyToken, animalController.createAnimal);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/animals/{id}:
|
||||
* put:
|
||||
* summary: 更新动物
|
||||
* tags: [Animals]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: 动物ID
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* type:
|
||||
* type: string
|
||||
* description: 动物类型
|
||||
* count:
|
||||
* type: integer
|
||||
* description: 数量
|
||||
* farmId:
|
||||
* type: integer
|
||||
* description: 所属养殖场ID
|
||||
* health_status:
|
||||
* type: string
|
||||
* enum: [healthy, sick, quarantine]
|
||||
* description: 健康状态
|
||||
* last_inspection:
|
||||
* type: string
|
||||
* format: date-time
|
||||
* description: 最近检查时间
|
||||
* notes:
|
||||
* type: string
|
||||
* description: 备注
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 动物更新成功
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* message:
|
||||
* type: string
|
||||
* example: 动物更新成功
|
||||
* data:
|
||||
* $ref: '#/components/schemas/Animal'
|
||||
* 400:
|
||||
* description: 请求参数错误
|
||||
* 401:
|
||||
* description: 未授权
|
||||
* 404:
|
||||
* description: 动物不存在或养殖场不存在
|
||||
* 500:
|
||||
* description: 服务器错误
|
||||
*/
|
||||
router.put('/:id', verifyToken, animalController.updateAnimal);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/animals/{id}:
|
||||
* delete:
|
||||
* summary: 删除动物
|
||||
* tags: [Animals]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: 动物ID
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 动物删除成功
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* message:
|
||||
* type: string
|
||||
* example: 动物删除成功
|
||||
* 401:
|
||||
* description: 未授权
|
||||
* 404:
|
||||
* description: 动物不存在
|
||||
* 500:
|
||||
* description: 服务器错误
|
||||
*/
|
||||
router.delete('/:id', verifyToken, animalController.deleteAnimal);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/animals/stats/type:
|
||||
* get:
|
||||
* summary: 按类型统计动物数量
|
||||
* tags: [Animals]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 成功获取动物类型统计
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* data:
|
||||
* type: array
|
||||
* items:
|
||||
* type: object
|
||||
* properties:
|
||||
* type:
|
||||
* type: string
|
||||
* example: 牛
|
||||
* total:
|
||||
* type: integer
|
||||
* example: 5000
|
||||
* 401:
|
||||
* description: 未授权
|
||||
* 500:
|
||||
* description: 服务器错误
|
||||
*/
|
||||
router.get('/stats/type', (req, res) => {
|
||||
// 从请求头获取token
|
||||
const authHeader = req.headers['authorization'];
|
||||
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
message: '访问令牌缺失'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取所有动物列表
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
// 验证token
|
||||
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'your_jwt_secret_key');
|
||||
const { page = 1, limit = 10, search = '' } = req.query;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
// 将用户信息添加到请求对象中
|
||||
req.user = decoded;
|
||||
|
||||
// 调用控制器方法获取数据
|
||||
animalController.getAnimalStatsByType(req, res);
|
||||
} catch (error) {
|
||||
if (error.name === 'JsonWebTokenError' || error.name === 'TokenExpiredError') {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
message: '访问令牌无效'
|
||||
});
|
||||
const whereConditions = {};
|
||||
if (search) {
|
||||
whereConditions[Op.or] = [
|
||||
{ collar_number: { [Op.like]: `%${search}%` } },
|
||||
{ ear_tag: { [Op.like]: `%${search}%` } }
|
||||
];
|
||||
}
|
||||
|
||||
// 返回模拟数据
|
||||
const mockStats = [
|
||||
{ type: '肉牛', total: 5280 },
|
||||
{ type: '奶牛', total: 2150 },
|
||||
{ type: '肉羊', total: 8760 },
|
||||
{ type: '奶羊', total: 1430 },
|
||||
{ type: '猪', total: 12500 }
|
||||
];
|
||||
const { count, rows } = await Animal.findAndCountAll({
|
||||
where: whereConditions,
|
||||
limit: parseInt(limit),
|
||||
offset: parseInt(offset),
|
||||
order: [['created_at', 'DESC']]
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
res.json({
|
||||
success: true,
|
||||
data: mockStats
|
||||
data: rows,
|
||||
total: count,
|
||||
pagination: {
|
||||
page: parseInt(page),
|
||||
limit: parseInt(limit),
|
||||
total: count,
|
||||
pages: Math.ceil(count / limit)
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取动物列表失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取动物列表失败: ' + error.message,
|
||||
data: null
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user