routes_alerts.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import { Hono } from "hono";
  2. import debug from "debug";
  3. import type {
  4. DeviceAlert,
  5. } from "../client/share/monitorTypes.ts";
  6. import {
  7. DeleteStatus,
  8. } from "../client/share/types.ts";
  9. import type { Variables, WithAuth } from "./middlewares.ts";
  10. const log = {
  11. api: debug("api:monitor"),
  12. };
  13. // 设备告警记录路由
  14. export function createAlertsRoutes(withAuth: WithAuth) {
  15. const alertsRoutes = new Hono<{ Variables: Variables }>();
  16. // 获取设备告警记录列表
  17. alertsRoutes.get("/", withAuth, async (c) => {
  18. try {
  19. const apiClient = c.get('apiClient');
  20. // 获取分页参数
  21. const page = Number(c.req.query("page")) || 1;
  22. const pageSize = Number(c.req.query("pageSize")) || 10;
  23. const offset = (page - 1) * pageSize;
  24. // 获取筛选参数
  25. const deviceId = c.req.query("device_id")
  26. ? Number(c.req.query("device_id"))
  27. : null;
  28. const metricType = c.req.query("metric_type");
  29. const alertLevel = c.req.query("alert_level")
  30. ? Number(c.req.query("alert_level"))
  31. : null;
  32. const status = c.req.query("status");
  33. const startTime = c.req.query("start_time");
  34. const endTime = c.req.query("end_time");
  35. // 构建查询
  36. let query = apiClient.database
  37. .table("device_alerts")
  38. .where("is_deleted", DeleteStatus.NOT_DELETED)
  39. .orderBy("created_at", "desc");
  40. // 应用筛选条件
  41. if (deviceId) {
  42. query = query.where("device_id", deviceId);
  43. }
  44. if (metricType) {
  45. query = query.where("metric_type", metricType);
  46. }
  47. if (alertLevel !== null) {
  48. query = query.where("alert_level", alertLevel);
  49. }
  50. if (status) {
  51. query = query.where("status", status);
  52. }
  53. if (startTime && endTime) {
  54. query = query.whereBetween("created_at", [startTime, endTime]);
  55. } else if (startTime) {
  56. query = query.where("created_at", ">=", startTime);
  57. } else if (endTime) {
  58. query = query.where("created_at", "<=", endTime);
  59. }
  60. // 获取总记录数
  61. const total = await query.clone().count();
  62. // 获取分页数据
  63. const data = await query.limit(pageSize).offset(offset);
  64. return c.json({
  65. data,
  66. total: Number(total),
  67. page,
  68. pageSize,
  69. });
  70. } catch (error) {
  71. log.api("获取告警记录失败:", error);
  72. return c.json({ error: "获取告警记录失败" }, 500);
  73. }
  74. });
  75. // 获取单个告警记录
  76. alertsRoutes.get("/:id", withAuth, async (c) => {
  77. try {
  78. const id = Number(c.req.param("id"));
  79. if (!id || isNaN(id)) {
  80. return c.json({ error: "无效的告警ID" }, 400);
  81. }
  82. const apiClient = c.get('apiClient');
  83. const alert = await apiClient.database
  84. .table("device_alerts")
  85. .where("id", id)
  86. .where("is_deleted", DeleteStatus.NOT_DELETED)
  87. .first();
  88. if (!alert) {
  89. return c.json({ error: "告警不存在" }, 404);
  90. }
  91. return c.json(alert);
  92. } catch (error) {
  93. log.api("获取告警详情失败:", error);
  94. return c.json({ error: "获取告警详情失败" }, 500);
  95. }
  96. });
  97. // 更新告警状态
  98. alertsRoutes.put("/:id", withAuth, async (c) => {
  99. try {
  100. const id = Number(c.req.param("id"));
  101. if (!id || isNaN(id)) {
  102. return c.json({ error: "无效的告警ID" }, 400);
  103. }
  104. const data = (await c.req.json()) as Partial<DeviceAlert>;
  105. // 只允许更新状态
  106. if (!data.status) {
  107. return c.json({ error: "状态不能为空" }, 400);
  108. }
  109. const apiClient = c.get('apiClient');
  110. // 检查告警是否存在
  111. const alert = await apiClient.database
  112. .table("device_alerts")
  113. .where("id", id)
  114. .where("is_deleted", DeleteStatus.NOT_DELETED)
  115. .first();
  116. if (!alert) {
  117. return c.json({ error: "告警不存在" }, 404);
  118. }
  119. // 更新告警
  120. await apiClient.database.table("device_alerts").where("id", id).update({
  121. status: data.status,
  122. updated_at: apiClient.database.fn.now(),
  123. });
  124. // 获取更新后的数据
  125. const [updatedAlert] = await apiClient.database
  126. .table("device_alerts")
  127. .where("id", id);
  128. return c.json({
  129. message: "告警状态更新成功",
  130. data: updatedAlert,
  131. });
  132. } catch (error) {
  133. log.api("更新告警状态失败:", error);
  134. return c.json({ error: "更新告警状态失败" }, 500);
  135. }
  136. });
  137. return alertsRoutes;
  138. }