import { Hono } from "hono"; import debug from "debug"; import type { DeviceAlertRule, } from "../client/share/monitorTypes.ts"; import { EnableStatus, DeleteStatus, } from "../client/share/types.ts"; import type { Variables, WithAuth } from "./middlewares.ts"; const log = { api: debug("api:monitor"), }; // 创建设备告警规则路由 export function createDeviceAlertRulesRoutes(withAuth: WithAuth) { const deviceAlertRulesRoutes = new Hono<{ Variables: Variables }>(); // 获取设备告警规则列表 deviceAlertRulesRoutes.get("/", withAuth, async (c) => { try { const apiClient = c.get('apiClient'); // 获取分页参数 const page = Number(c.req.query("page")) || 1; const pageSize = Number(c.req.query("pageSize")) || 10; const offset = (page - 1) * pageSize; // 获取筛选参数 const deviceId = c.req.query("device_id") ? Number(c.req.query("device_id")) : null; const metricType = c.req.query("metric_type"); const alertLevel = c.req.query("alert_level") ? Number(c.req.query("alert_level")) : null; const isEnabled = c.req.query("is_enabled") ? Number(c.req.query("is_enabled")) : null; // 构建查询 let query = apiClient.database .table("device_alert_rules") .where("is_deleted", DeleteStatus.NOT_DELETED) .orderBy("id", "desc"); // 应用筛选条件 if (deviceId) { query = query.where("device_id", deviceId); } if (metricType) { query = query.where("metric_type", metricType); } if (alertLevel !== null) { query = query.where("alert_level", alertLevel); } if (isEnabled !== null) { query = query.where("is_enabled", isEnabled); } // 获取总记录数 const total = await query.clone().count(); // 获取分页数据 const data = await query.limit(pageSize).offset(offset); return c.json({ data, total: Number(total), page, pageSize, }); } catch (error) { log.api("获取设备告警规则失败:", error); return c.json({ error: "获取设备告警规则失败" }, 500); } }); // 获取单个告警规则 deviceAlertRulesRoutes.get("/:id", withAuth, async (c) => { try { const id = Number(c.req.param("id")); if (!id || isNaN(id)) { return c.json({ error: "无效的告警规则ID" }, 400); } const apiClient = c.get('apiClient'); const rule = await apiClient.database .table("device_alert_rules") .where("id", id) .where("is_deleted", DeleteStatus.NOT_DELETED) .first(); if (!rule) { return c.json({ error: "告警规则不存在" }, 404); } return c.json(rule); } catch (error) { log.api("获取告警规则详情失败:", error); return c.json({ error: "获取告警规则详情失败" }, 500); } }); // 创建告警规则 deviceAlertRulesRoutes.post("/", withAuth, async (c) => { try { const data = (await c.req.json()) as Partial; // 验证必填字段 if (!data.device_id) { return c.json({ error: "设备ID不能为空" }, 400); } if (!data.metric_type) { return c.json({ error: "监控指标类型不能为空" }, 400); } if (data.alert_level === undefined || data.alert_level === null) { return c.json({ error: "告警等级不能为空" }, 400); } // 最小值或最大值至少要有一个 if (data.min_value === undefined && data.max_value === undefined) { return c.json({ error: "最小值或最大值至少要设置一个" }, 400); } const apiClient = c.get('apiClient'); // 检查设备是否存在 const device = await apiClient.database .table("zichan_info") .where("id", data.device_id) .where("is_deleted", DeleteStatus.NOT_DELETED) .first(); if (!device) { return c.json({ error: "设备不存在" }, 404); } // 插入告警规则 const [id] = await apiClient.database.table("device_alert_rules").insert({ ...data, is_enabled: data.is_enabled !== undefined ? data.is_enabled : EnableStatus.ENABLED, created_at: apiClient.database.fn.now(), updated_at: apiClient.database.fn.now(), }); // 获取插入的数据 const [insertedRule] = await apiClient.database .table("device_alert_rules") .where("id", id); return c.json({ message: "告警规则创建成功", data: insertedRule, }); } catch (error) { log.api("创建告警规则失败:", error); return c.json({ error: "创建告警规则失败" }, 500); } }); // 更新告警规则 deviceAlertRulesRoutes.put("/:id", withAuth, async (c) => { try { const id = Number(c.req.param("id")); if (!id || isNaN(id)) { return c.json({ error: "无效的告警规则ID" }, 400); } const data = (await c.req.json()) as Partial; const apiClient = c.get('apiClient'); // 检查告警规则是否存在 const rule = await apiClient.database .table("device_alert_rules") .where("id", id) .where("is_deleted", DeleteStatus.NOT_DELETED) .first(); if (!rule) { return c.json({ error: "告警规则不存在" }, 404); } // 如果更改了设备ID,检查设备是否存在 if (data.device_id && data.device_id !== rule.device_id) { const device = await apiClient.database .table("zichan_info") .where("id", data.device_id) .where("is_deleted", DeleteStatus.NOT_DELETED) .first(); if (!device) { return c.json({ error: "设备不存在" }, 404); } } // 更新告警规则 await apiClient.database .table("device_alert_rules") .where("id", id) .update({ ...data, updated_at: apiClient.database.fn.now(), }); // 获取更新后的数据 const [updatedRule] = await apiClient.database .table("device_alert_rules") .where("id", id); return c.json({ message: "告警规则更新成功", data: updatedRule, }); } catch (error) { log.api("更新告警规则失败:", error); return c.json({ error: "更新告警规则失败" }, 500); } }); // 删除告警规则 deviceAlertRulesRoutes.delete("/:id", withAuth, async (c) => { try { const id = Number(c.req.param("id")); if (!id || isNaN(id)) { return c.json({ error: "无效的告警规则ID" }, 400); } const apiClient = c.get('apiClient'); // 检查告警规则是否存在 const rule = await apiClient.database .table("device_alert_rules") .where("id", id) .where("is_deleted", DeleteStatus.NOT_DELETED) .first(); if (!rule) { return c.json({ error: "告警规则不存在" }, 404); } // 软删除告警规则 await apiClient.database .table("device_alert_rules") .where("id", id) .update({ is_deleted: DeleteStatus.DELETED, updated_at: apiClient.database.fn.now(), }); return c.json({ message: "告警规则删除成功", id, }); } catch (error) { log.api("删除告警规则失败:", error); return c.json({ error: "删除告警规则失败" }, 500); } }); return deviceAlertRulesRoutes; }