Files
nxxmdata/backend/routes/api-demo.js
2025-09-17 19:01:52 +08:00

292 lines
7.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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;