Files
nxxmdata/backend/routes/alerts.js

629 lines
16 KiB
JavaScript
Raw Normal View History

/**
* 预警路由
* @file alerts.js
* @description 定义预警相关的API路由
*/
const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
const alertController = require('../controllers/alertController');
const { verifyToken } = require('../middleware/auth');
// 公开API路由不需要验证token
const publicRoutes = express.Router();
router.use('/public', publicRoutes);
// 公开获取所有预警数据
publicRoutes.get('/', alertController.getAllAlerts);
// 公开获取单个预警数据
publicRoutes.get('/:id', alertController.getAlertById);
// 公开获取预警统计信息
publicRoutes.get('/stats/type', alertController.getAlertStatsByType);
publicRoutes.get('/stats/level', alertController.getAlertStatsByLevel);
publicRoutes.get('/stats/status', alertController.getAlertStatsByStatus);
// 公开更新预警状态
publicRoutes.put('/:id/status', alertController.updateAlert);
/**
* @swagger
* tags:
* name: Alerts
* description: 预警管理API
*/
/**
* @swagger
* /api/alerts:
* get:
* summary: 获取所有预警
* tags: [Alerts]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: 成功获取预警列表
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* example: true
* data:
* type: array
* items:
* $ref: '#/components/schemas/Alert'
* 401:
* description: 未授权
* 500:
* description: 服务器错误
*/
2025-09-12 20:08:42 +08:00
// 根据养殖场名称搜索预警
router.get('/search', verifyToken, alertController.searchAlertsByFarmName);
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: '访问令牌缺失'
});
}
try {
// 验证token
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'your_jwt_secret_key');
// 将用户信息添加到请求对象中
req.user = decoded;
// 调用控制器方法获取数据
alertController.getAllAlerts(req, res);
} catch (error) {
if (error.name === 'JsonWebTokenError' || error.name === 'TokenExpiredError') {
return res.status(401).json({
success: false,
message: '访问令牌无效'
});
}
// 返回模拟数据
const mockAlerts = [
{
id: 0,
type: "string",
level: "low",
message: "string",
status: "active",
farmId: 0,
deviceId: 0,
resolved_at: "2025-08-20T01:09:30.453Z",
resolved_by: 0,
resolution_notes: "string",
createdAt: "2025-08-20T01:09:30.453Z",
updatedAt: "2025-08-20T01:09:30.453Z"
}
];
res.status(200).json({
success: true,
data: mockAlerts
});
}
});
/**
* @swagger
* /api/alerts/{id}:
* get:
* summary: 获取单个预警
* tags: [Alerts]
* 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/Alert'
* 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;
// 调用控制器方法获取数据
alertController.getAlertById(req, res);
} catch (error) {
if (error.name === 'JsonWebTokenError' || error.name === 'TokenExpiredError') {
return res.status(401).json({
success: false,
message: '访问令牌无效'
});
}
// 返回模拟数据
const mockAlert = {
id: parseInt(req.params.id),
type: "temperature",
level: "medium",
message: "温度异常警告",
status: "active",
farmId: 1,
deviceId: 1,
resolved_at: null,
resolved_by: null,
resolution_notes: null,
createdAt: "2025-08-20T01:09:30.453Z",
updatedAt: "2025-08-20T01:09:30.453Z"
};
res.status(200).json({
success: true,
data: mockAlert
});
}
});
/**
* @swagger
* /api/alerts:
* post:
* summary: 创建预警
* tags: [Alerts]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - type
* - message
* - farmId
* properties:
* type:
* type: string
* description: 预警类型
* level:
* type: string
* enum: [low, medium, high, critical]
* description: 预警级别
* message:
* type: string
* description: 预警消息
* status:
* type: string
* enum: [active, acknowledged, resolved]
* description: 预警状态
* farmId:
* type: integer
* description: 所属养殖场ID
* deviceId:
* type: integer
* description: 关联设备ID
* responses:
* 201:
* description: 预警创建成功
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* example: true
* message:
* type: string
* example: 预警创建成功
* data:
* $ref: '#/components/schemas/Alert'
* 400:
* description: 请求参数错误
* 401:
* description: 未授权
* 404:
* description: 养殖场或设备不存在
* 500:
* description: 服务器错误
*/
router.post('/', verifyToken, alertController.createAlert);
/**
* @swagger
* /api/alerts/{id}:
* put:
* summary: 更新预警
* tags: [Alerts]
* 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: 预警类型
* level:
* type: string
* enum: [low, medium, high, critical]
* description: 预警级别
* message:
* type: string
* description: 预警消息
* status:
* type: string
* enum: [active, acknowledged, resolved]
* description: 预警状态
* farmId:
* type: integer
* description: 所属养殖场ID
* deviceId:
* type: integer
* description: 关联设备ID
* resolved_at:
* type: string
* format: date-time
* description: 解决时间
* resolved_by:
* type: integer
* description: 解决人ID
* resolution_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/Alert'
* 400:
* description: 请求参数错误
* 401:
* description: 未授权
* 404:
* description: 预警不存在或养殖场/设备不存在
* 500:
* description: 服务器错误
*/
router.put('/:id', verifyToken, alertController.updateAlert);
/**
* @swagger
* /api/alerts/{id}:
* delete:
* summary: 删除预警
* tags: [Alerts]
* 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, alertController.deleteAlert);
/**
* @swagger
* /api/alerts/stats/type:
* get:
* summary: 按类型统计预警数量
* tags: [Alerts]
* 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: 温度异常
* count:
* type: integer
* example: 12
* 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: '访问令牌缺失'
});
}
try {
// 验证token
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'your_jwt_secret_key');
// 将用户信息添加到请求对象中
req.user = decoded;
// 调用控制器方法获取数据
alertController.getAlertStatsByType(req, res);
} catch (error) {
if (error.name === 'JsonWebTokenError' || error.name === 'TokenExpiredError') {
return res.status(401).json({
success: false,
message: '访问令牌无效'
});
}
// 返回模拟数据
const mockStats = [
{ type: 'temperature', count: 12 },
{ type: 'humidity', count: 8 },
{ type: 'system', count: 5 },
{ type: 'power', count: 3 }
];
res.status(200).json({
success: true,
data: mockStats
});
}
});
/**
* @swagger
* /api/alerts/stats/level:
* get:
* summary: 按级别统计预警数量
* tags: [Alerts]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: 成功获取预警级别统计
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* example: true
* data:
* type: array
* items:
* type: object
* properties:
* level:
* type: string
* example: high
* count:
* type: integer
* example: 8
* 401:
* description: 未授权
* 500:
* description: 服务器错误
*/
router.get('/stats/level', (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;
// 调用控制器方法获取数据
alertController.getAlertStatsByLevel(req, res);
} catch (error) {
if (error.name === 'JsonWebTokenError' || error.name === 'TokenExpiredError') {
return res.status(401).json({
success: false,
message: '访问令牌无效'
});
}
// 返回模拟数据
const mockStats = [
{ level: 'high', count: 7 },
{ level: 'medium', count: 15 },
{ level: 'low', count: 6 }
];
res.status(200).json({
success: true,
data: mockStats
});
}
});
/**
* @swagger
* /api/alerts/stats/status:
* get:
* summary: 按状态统计预警数量
* tags: [Alerts]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: 成功获取预警状态统计
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* example: true
* data:
* type: array
* items:
* type: object
* properties:
* status:
* type: string
* example: active
* count:
* type: integer
* example: 15
* 401:
* description: 未授权
* 500:
* description: 服务器错误
*/
router.get('/stats/status', (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;
// 调用控制器方法获取数据
alertController.getAlertStatsByStatus(req, res);
} catch (error) {
if (error.name === 'JsonWebTokenError' || error.name === 'TokenExpiredError') {
return res.status(401).json({
success: false,
message: '访问令牌无效'
});
}
// 返回模拟数据
const mockStats = [
{ status: 'active', count: 18 },
{ status: 'resolved', count: 10 }
];
res.status(200).json({
success: true,
data: mockStats
});
}
});
module.exports = router;