/** * API接口演示路由 * 展示如何使用统一的API响应格式和筛选条件管理 */ const express = require('express'); const router = express.Router(); const { Op } = require('sequelize'); const Animal = require('../models/Animal'); const Device = require('../models/Device'); const Alert = require('../models/Alert'); /** * 获取动物列表(支持筛选、分页、排序) * GET /api/demo/animals * 查询参数: * - page: 页码(默认1) * - limit: 每页数量(默认20) * - sort: 排序字段(默认createTime) * - order: 排序方式(ASC/DESC,默认DESC) * - name: 动物名称(模糊搜索) * - category: 动物类别 * - status: 状态 * - minWeight: 最小体重 * - maxWeight: 最大体重 */ router.get('/animals', async (req, res) => { try { // 获取分页参数 const { page, limit, offset } = req.getPagination(); // 获取筛选条件 const filters = req.getFilters(['name', 'category', 'status', 'penId']); // 获取排序参数 const order = req.getSorting(['name', 'category', 'status', 'weight', 'createTime', 'updateTime']); // 构建查询条件 const where = {}; // 处理名称模糊搜索 if (filters.name) { where.name = { [Op.like]: `%${filters.name}%` }; } // 处理其他筛选条件 if (filters.category) { where.category = filters.category; } if (filters.status) { where.status = filters.status; } if (filters.penId) { where.penId = filters.penId; } // 处理体重范围筛选 if (req.query.minWeight || req.query.maxWeight) { where.weight = {}; if (req.query.minWeight) { where.weight[Op.gte] = parseFloat(req.query.minWeight); } if (req.query.maxWeight) { where.weight[Op.lte] = parseFloat(req.query.maxWeight); } } // 查询数据 const { count, rows } = await Animal.findAndCountAll({ where, limit, offset, order, attributes: [ 'id', 'name', 'category', 'status', 'weight', 'birthDate', 'penId', 'createTime', 'updateTime' ] }); // 返回统一格式的响应 res.apiSuccess(rows, '获取动物列表成功', { total: count, page, limit }); } catch (error) { console.error('获取动物列表失败:', error); res.apiError('获取动物列表失败', 'DATABASE_ERROR', 500); } }); /** * 获取设备列表(支持筛选、分页、排序) * GET /api/demo/devices * 查询参数: * - page: 页码(默认1) * - limit: 每页数量(默认20) * - sort: 排序字段(默认installDate) * - order: 排序方式(ASC/DESC,默认DESC) * - name: 设备名称(模糊搜索) * - type: 设备类型 * - status: 设备状态 * - location: 安装位置 */ router.get('/devices', async (req, res) => { try { // 获取分页参数 const { page, limit, offset } = req.getPagination(); // 获取筛选条件 const filters = req.getFilters(['name', 'type', 'status', 'location']); // 获取排序参数 const order = req.getSorting(['name', 'type', 'status', 'installDate', 'createTime']); // 构建查询条件 const where = {}; // 处理名称模糊搜索 if (filters.name) { where.name = { [Op.like]: `%${filters.name}%` }; } // 处理其他筛选条件 if (filters.type) { where.type = filters.type; } if (filters.status) { where.status = filters.status; } if (filters.location) { where.location = { [Op.like]: `%${filters.location}%` }; } // 查询数据 const { count, rows } = await Device.findAndCountAll({ where, limit, offset, order, attributes: [ 'id', 'name', 'type', 'status', 'location', 'installDate', 'lastMaintenance', 'createTime', 'updateTime' ] }); // 返回统一格式的响应 res.apiSuccess(rows, '获取设备列表成功', { total: count, page, limit }); } catch (error) { console.error('获取设备列表失败:', error); res.apiError('获取设备列表失败', 'DATABASE_ERROR', 500); } }); /** * 获取告警列表(支持筛选、分页、排序) * GET /api/demo/alerts * 查询参数: * - page: 页码(默认1) * - limit: 每页数量(默认20) * - sort: 排序字段(默认createTime) * - order: 排序方式(ASC/DESC,默认DESC) * - type: 告警类型 * - level: 告警级别 * - status: 处理状态 * - startDate: 开始时间 * - endDate: 结束时间 */ router.get('/alerts', async (req, res) => { try { // 获取分页参数 const { page, limit, offset } = req.getPagination(); // 获取筛选条件 const filters = req.getFilters(['type', 'level', 'status']); // 获取排序参数 const order = req.getSorting(['type', 'level', 'status', 'createTime', 'updateTime']); // 构建查询条件 const where = {}; // 处理筛选条件 if (filters.type) { where.type = filters.type; } if (filters.level) { where.level = filters.level; } if (filters.status) { where.status = filters.status; } // 处理时间范围筛选 if (req.query.startDate || req.query.endDate) { where.createTime = {}; if (req.query.startDate) { where.createTime[Op.gte] = new Date(req.query.startDate); } if (req.query.endDate) { where.createTime[Op.lte] = new Date(req.query.endDate); } } // 查询数据 const { count, rows } = await Alert.findAndCountAll({ where, limit, offset, order, include: [ { model: Animal, attributes: ['id', 'name', 'category'] }, { model: Device, attributes: ['id', 'name', 'type'] } ], attributes: [ 'id', 'type', 'level', 'status', 'description', 'createTime', 'updateTime', 'handler', 'handleTime', 'handleNote' ] }); // 返回统一格式的响应 res.apiSuccess(rows, '获取告警列表成功', { total: count, page, limit }); } catch (error) { console.error('获取告警列表失败:', error); res.apiError('获取告警列表失败', 'DATABASE_ERROR', 500); } }); /** * 获取统计仪表盘数据 * GET /api/demo/dashboard */ router.get('/dashboard', async (req, res) => { try { // 并行获取所有统计数据 const [ animalCount, deviceCount, alertCount, onlineDevices ] = await Promise.all([ Animal.count({ where: { status: 'active' } }), Device.count(), Alert.count({ where: { status: 'pending' } }), Device.count({ where: { status: 'online' } }) ]); const dashboardData = { animalCount, deviceCount, alertCount, onlineDeviceRate: deviceCount > 0 ? (onlineDevices / deviceCount).toFixed(2) : 0, alertsByLevel: { low: await Alert.count({ where: { level: 'low', status: 'pending' } }), medium: await Alert.count({ where: { level: 'medium', status: 'pending' } }), high: await Alert.count({ where: { level: 'high', status: 'pending' } }), critical: await Alert.count({ where: { level: 'critical', status: 'pending' } }) } }; res.apiSuccess(dashboardData, '获取仪表盘数据成功'); } catch (error) { console.error('获取仪表盘数据失败:', error); res.apiError('获取仪表盘数据失败', 'DATABASE_ERROR', 500); } }); module.exports = router;