292 lines
7.6 KiB
JavaScript
292 lines
7.6 KiB
JavaScript
/**
|
||
* 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; |